Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs updates to match new Werkzeug docs #154

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions docs/api.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -46,19 +46,21 @@ Incoming Request Data


.. attribute:: form .. attribute:: form


A :class:`~werkzeug.MultiDict` with the parsed form data from `POST` A :class:`~werkzeug.datastructures.MultiDict` with the parsed form
or `PUT` requests. Please keep in mind that file uploads will not data from `POST` or `PUT` requests. Please keep in mind that file
end up here, but instead in the :attr:`files` attribute. uploads will not end up here, but instead in the :attr:`files`
attribute.


.. attribute:: args .. attribute:: args


A :class:`~werkzeug.MultiDict` with the parsed contents of the query A :class:`~werkzeug.datastructures.MultiDict` with the parsed
string. (The part in the URL after the question mark). contents of the query string. (The part in the URL after the
question mark).


.. attribute:: values .. attribute:: values


A :class:`~werkzeug.CombinedMultiDict` with the contents of both A :class:`~werkzeug.datastructures.CombinedMultiDict` with the
:attr:`form` and :attr:`args`. contents of both :attr:`form` and :attr:`args`.


.. attribute:: cookies .. attribute:: cookies


Expand All @@ -79,12 +81,13 @@ Incoming Request Data


.. attribute:: files .. attribute:: files


A :class:`~werkzeug.MultiDict` with files uploaded as part of a A :class:`~werkzeug.datastructures.MultiDict` with files
`POST` or `PUT` request. Each file is stored as uploaded as part of a `POST` or `PUT` request. Each file
:class:`~werkzeug.FileStorage` object. It basically behaves like a is stored as :class:`~werkzeug.datastructures.FileStorage`
standard file object you know from Python, with the difference that object. It basically behaves like a standard file object
it also has a :meth:`~werkzeug.FileStorage.save` function that can you know from Python, with the difference that it also has a
store the file on the filesystem. :meth:`~werkzeug.datastructures.FileStorage.save` function that
can store the file on the filesystem.


.. attribute:: environ .. attribute:: environ


Expand Down Expand Up @@ -308,10 +311,10 @@ Useful Internals


.. data:: _request_ctx_stack .. data:: _request_ctx_stack


The internal :class:`~werkzeug.LocalStack` that is used to implement The internal :class:`~werkzeug.local.LocalStack` that is used to
all the context local objects used in Flask. This is a documented implement all the context local objects used in Flask. This is a
instance and can be used by extensions and application code but the documented instance and can be used by extensions and application
use is discouraged in general. code but the use is discouraged in general.


The following attributes are always present on each layer of the The following attributes are always present on each layer of the
stack: stack:
Expand Down Expand Up @@ -356,9 +359,9 @@ Useful Internals
deferred cleanup functionality. deferred cleanup functionality.


You might find this helpful for unittests where you need the You might find this helpful for unittests where you need the
information from the context local around for a little longer. Make information from the context local around for a little longer.
sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in Make sure to properly :meth:`~werkzeug.local.LocalStack.pop` the stack
that situation, otherwise your unittests will leak memory. yourself in that situation, otherwise your unittests will leak memory.


Signals Signals
------- -------
Expand Down Expand Up @@ -434,8 +437,9 @@ exceptions where it is good to know that this object is an actual proxy:
- if the object reference is important (so for example for sending - if the object reference is important (so for example for sending
:ref:`signals`) :ref:`signals`)


If you need to get access to the underlying object that is proxied, you If you need to get access to the underlying object that is proxied,
can use the :meth:`~werkzeug.LocalProxy._get_current_object` method:: you can use the :meth:`~werkzeug.local.LocalProxy._get_current_object`
method::


app = current_app._get_current_object() app = current_app._get_current_object()
my_signal.send(app) my_signal.send(app)
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@


intersphinx_mapping = { intersphinx_mapping = {
'http://docs.python.org/dev': None, 'http://docs.python.org/dev': None,
'http://werkzeug.pocoo.org/documentation/dev/': None, 'http://werkzeug.pocoo.org/docs/': None,
'http://www.sqlalchemy.org/docs/': None, 'http://www.sqlalchemy.org/docs/': None,
'http://wtforms.simplecodes.com/docs/0.5/': None, 'http://wtforms.simplecodes.com/docs/0.5/': None,
'http://discorporate.us/projects/Blinker/docs/1.1/': None 'http://discorporate.us/projects/Blinker/docs/1.1/': None
Expand Down
40 changes: 20 additions & 20 deletions docs/patterns/fileuploads.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ uploads is actually quite simple. It basically works like this:
and an ``<input type=file>`` is placed in that form. and an ``<input type=file>`` is placed in that form.
2. The application accesses the file from the :attr:`~flask.request.files` 2. The application accesses the file from the :attr:`~flask.request.files`
dictionary on the request object. dictionary on the request object.
3. use the :meth:`~werkzeug.FileStorage.save` method of the file to save 3. use the :meth:`~werkzeug.datastructures.FileStorage.save` method of
the file permanently somewhere on the filesystem. the file to save the file permanently somewhere on the filesystem.


A Gentle Introduction A Gentle Introduction
--------------------- ---------------------
Expand All @@ -22,21 +22,21 @@ bootstrapping code for our application::


import os import os
from flask import Flask, request, redirect, url_for from flask import Flask, request, redirect, url_for
from werkzeug import secure_filename from werkzeug.utils import secure_filename


UPLOAD_FOLDER = '/path/to/the/uploads' UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])


app = Flask(__name__) app = Flask(__name__)


So first we need a couple of imports. Most should be straightforward, the So first we need a couple of imports. Most should be straightforward,
:func:`werkzeug.secure_filename` is explained a little bit later. The the :func:`werkzeug.utils.secure_filename` is explained a little bit
`UPLOAD_FOLDER` is where we will store the uploaded files and the later. The `UPLOAD_FOLDER` is where we will store the uploaded files
`ALLOWED_EXTENSIONS` is the set of allowed file extensions. Then we add a and the `ALLOWED_EXTENSIONS` is the set of allowed file extensions.
URL rule by hand to the application. Now usually we're not doing that, so Then we add a URL rule by hand to the application. Now usually we're
why here? The reasons is that we want the webserver (or our development not doing that, so why here? The reasons is that we want the webserver
server) to serve these files for us and so we only need a rule to generate (or our development server) to serve these files for us and so we only
the URL to these files. need a rule to generate the URL to these files.


Why do we limit the extensions that are allowed? You probably don't want Why do we limit the extensions that are allowed? You probably don't want
your users to be able to upload everything there if the server is directly your users to be able to upload everything there if the server is directly
Expand Down Expand Up @@ -71,12 +71,12 @@ the file and redirects the user to the URL for the uploaded file::
</form> </form>
''' '''


So what does that :func:`~werkzeug.secure_filename` function actually do? So what does that :func:`~werkzeug.utils.secure_filename` function
Now the problem is that there is that principle called "never trust user actually do? Now the problem is that there is that principle called
input". This is also true for the filename of an uploaded file. All "never trust user input". This is also true for the filename of an
submitted form data can be forged, and filenames can be dangerous. For uploaded file. All submitted form data can be forged, and filenames can
the moment just remember: always use that function to secure a filename be dangerous. For the moment just remember: always use that function
before storing it directly on the filesystem. to secure a filename before storing it directly on the filesystem.


.. admonition:: Information for the Pros .. admonition:: Information for the Pros


Expand Down Expand Up @@ -109,10 +109,10 @@ Flask 0.5 we can use a function that does that for us::
filename) filename)


Alternatively you can register `uploaded_file` as `build_only` rule and Alternatively you can register `uploaded_file` as `build_only` rule and
use the :class:`~werkzeug.SharedDataMiddleware`. This also works with use the :class:`~werkzeug.wsgi.SharedDataMiddleware`. This also works
older versions of Flask:: with older versions of Flask::


from werkzeug import SharedDataMiddleware from werkzeug.wsgi import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', app.add_url_rule('/uploads/<filename>', 'uploaded_file',
build_only=True) build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
Expand Down
12 changes: 6 additions & 6 deletions docs/patterns/jquery.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ template. This template will load jQuery as above and have a little form
we can add two numbers and a link to trigger the function on the server we can add two numbers and a link to trigger the function on the server
side. side.


Note that we are using the :meth:`~werkzeug.MultiDict.get` method here Note that we are using the :meth:`~werkzeug.datastructures.MultiDict.get`
which will never fail. If the key is missing a default value (here ``0``) method here which will never fail. If the key is missing a default
is returned. Furthermore it can convert values to a specific type (like value (here ``0``) is returned. Furthermore it can convert values to
in our case `int`). This is especially handy for code that is a specific type (like in our case `int`). This is especially handy for
triggered by a script (APIs, JavaScript etc.) because you don't need code that is triggered by a script (APIs, JavaScript etc.) because you
special error reporting in that case. don't need special error reporting in that case.


The HTML The HTML
-------- --------
Expand Down
2 changes: 1 addition & 1 deletion docs/patterns/lazyloading.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ loaded upfront. The trick to actually load the view function as needed.
This can be accomplished with a helper class that behaves just like a This can be accomplished with a helper class that behaves just like a
function but internally imports the real function on first use:: function but internally imports the real function on first use::


from werkzeug import import_string, cached_property from werkzeug.utils import import_string, cached_property


class LazyView(object): class LazyView(object):


Expand Down
32 changes: 16 additions & 16 deletions docs/quickstart.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -543,14 +543,14 @@ You can handle uploaded files with Flask easily. Just make sure not to
forget to set the ``enctype="multipart/form-data"`` attribute on your HTML forget to set the ``enctype="multipart/form-data"`` attribute on your HTML
form, otherwise the browser will not transmit your files at all. form, otherwise the browser will not transmit your files at all.


Uploaded files are stored in memory or at a temporary location on the Uploaded files are stored in memory or at a temporary location
filesystem. You can access those files by looking at the on the filesystem. You can access those files by looking at the
:attr:`~flask.request.files` attribute on the request object. Each :attr:`~flask.request.files` attribute on the request object.
uploaded file is stored in that dictionary. It behaves just like a Each uploaded file is stored in that dictionary. It behaves just
standard Python :class:`file` object, but it also has a like a standard Python :class:`file` object, but it also has a
:meth:`~werkzeug.FileStorage.save` method that allows you to store that :meth:`~werkzeug.datastructures.FileStorage.save` method that allows you
file on the filesystem of the server. Here is a simple example showing how to store that file on the filesystem of the server. Here is a simple
that works:: example showing how that works::


from flask import request from flask import request


Expand All @@ -561,16 +561,16 @@ that works::
f.save('/var/www/uploads/uploaded_file.txt') f.save('/var/www/uploads/uploaded_file.txt')
... ...


If you want to know how the file was named on the client before it was If you want to know how the file was named on the client
uploaded to your application, you can access the before it was uploaded to your application, you can access the
:attr:`~werkzeug.FileStorage.filename` attribute. However please keep in :attr:`~werkzeug.datastructures.FileStorage.filename` attribute. However
mind that this value can be forged so never ever trust that value. If you please keep in mind that this value can be forged so never ever trust that
want to use the filename of the client to store the file on the server, value. If you want to use the filename of the client to store the file
pass it through the :func:`~werkzeug.secure_filename` function that on the server, pass it through the :func:`~werkzeug.utils.secure_filename`
Werkzeug provides for you:: function that Werkzeug provides for you::


from flask import request from flask import request
from werkzeug import secure_filename from werkzeug.utils import secure_filename


@app.route('/upload', methods=['GET', 'POST']) @app.route('/upload', methods=['GET', 'POST'])
def upload_file(): def upload_file():
Expand Down
24 changes: 12 additions & 12 deletions docs/testing.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ safely change things, and you will instantly know if your change broke
something. something.


Flask gives you a couple of ways to test applications. It mainly does Flask gives you a couple of ways to test applications. It mainly does
that by exposing the Werkzeug test :class:`~werkzeug.Client` class to your that by exposing the Werkzeug test :class:`~werkzeug.test.Client` class
code and handling the context locals for you. You can then use that with to your code and handling the context locals for you. You can then use
your favourite testing solution. In this documentation we will use the that with your favourite testing solution. In this documentation we
:mod:`unittest` package that comes preinstalled with each Python will use the :mod:`unittest` package that comes preinstalled with each
installation. Python installation.


The Application The Application
--------------- ---------------
Expand Down Expand Up @@ -106,13 +106,13 @@ this::
rv = self.app.get('/') rv = self.app.get('/')
assert 'No entries here so far' in rv.data assert 'No entries here so far' in rv.data


Test functions begin with the word `test`. Every function named like that Test functions begin with the word `test`. Every function named like
will be picked up automatically. By using `self.app.get` we can send an that will be picked up automatically. By using `self.app.get` we can
HTTP `GET` request to the application with the given path. The return send an HTTP `GET` request to the application with the given path.
value will be a :class:`~flask.Flask.response_class` object. We can now The return value will be a :class:`~flask.Flask.response_class` object.
use the :attr:`~werkzeug.BaseResponse.data` attribute to inspect the We can now use the :attr:`~werkzeug.wrappers.BaseResponse.data` attribute
return value (as string) from the application. In this case, we ensure to inspect the return value (as string) from the application. In this
that ``'No entries here so far'`` is part of the output. case, we ensure that ``'No entries here so far'`` is part of the output.


Run it again and you should see one passing test:: Run it again and you should see one passing test::


Expand Down