Quickstart¶

Eager to become started? This page gives a good introduction to Flask. Follow Installation to set up a project and install Flask first.

A Minimal Application¶

A minimal Flask application looks something like this:

                            from              flask              import              Flask              app              =              Flask              (              __name__              )              @app              .              route              (              "/"              )              def              hello_world              ():              return              "<p>Hello, Earth!</p>"            

So what did that code practice?

  1. First we imported the Flask class. An instance of this class will exist our WSGI awarding.

  2. Side by side we create an case of this class. The first statement is the proper noun of the application'southward module or package. __name__ is a user-friendly shortcut for this that is advisable for most cases. This is needed so that Flask knows where to look for resources such as templates and static files.

  3. We then use the road() decorator to tell Flask what URL should trigger our function.

  4. The role returns the message we want to display in the user's browser. The default content blazon is HTML, and then HTML in the cord will exist rendered by the browser.

Save it every bit how-do-you-do.py or something similar. Make sure to not call your application flask.py because this would disharmonize with Flask itself.

To run the application, use the flask control or python -m flask. Earlier you can do that you need to tell your concluding the application to work with by exporting the FLASK_APP environment variable:

              $ consign FLASK_APP=hullo $ flask run  * Running on http://127.0.0.1:5000/            

Awarding Discovery Behavior

Every bit a shortcut, if the file is named app.py or wsgi.py , you lot don't have to set the FLASK_APP environment variable. See Command Line Interface for more details.

This launches a very simple builtin server, which is good enough for testing but probably not what you desire to utilize in product. For deployment options see Deployment Options.

Now head over to http://127.0.0.ane:5000/, and you lot should see your hello world greeting.

If some other program is already using port 5000, y'all'll run across OSError: [Errno 98] or OSError: [WinError 10013] when the server tries to kickoff. See Address already in utilise for how to handle that.

Externally Visible Server

If you run the server yous will find that the server is only attainable from your own computer, not from whatever other in the network. This is the default considering in debugging mode a user of the awarding can execute arbitrary Python code on your figurer.

If you have the debugger disabled or trust the users on your network, you can make the server publicly available just past calculation --host=0.0.0.0 to the command line:

                $ flask run --host=0.0.0.0              

This tells your operating system to listen on all public IPs.

What to do if the Server does not Kickoff¶

In case the python -g flask fails or flask does non be, at that place are multiple reasons this might be the instance. Start of all y'all need to look at the error bulletin.

Old Version of Flask¶

Versions of Flask older than 0.eleven used to have unlike means to start the application. In short, the flask command did not be, and neither did python -m flask. In that case you lot have two options: either upgrade to newer Flask versions or have a expect at Development Server to run into the alternative method for running a server.

Invalid Import Name¶

The FLASK_APP environs variable is the name of the module to import at flask run. In case that module is incorrectly named yous will become an import error upon commencement (or if debug is enabled when y'all navigate to the application). It will tell you what it tried to import and why it failed.

The most common reason is a typo or because you lot did non actually create an app object.

Debug Mode¶

The flask run command tin can do more than only commencement the development server. By enabling debug mode, the server will automatically reload if code changes, and volition show an interactive debugger in the browser if an error occurs during a request.

The interactive debugger in action.

Alert

The debugger allows executing arbitrary Python lawmaking from the browser. It is protected by a pin, but nevertheless represents a major security risk. Do not run the development server or debugger in a product environment.

To enable all development features, ready the FLASK_ENV environment variable to development before calling flask run .

              $ consign FLASK_ENV=development $ flask run            

See besides:

  • Development Server and Control Line Interface for information about running in development fashion.

  • Debugging Application Errors for information most using the built-in debugger and other debuggers.

  • Logging and Handling Application Errors to log errors and display nice error pages.

HTML Escaping¶

When returning HTML (the default response type in Flask), any user-provided values rendered in the output must be escaped to protect from injection attacks. HTML templates rendered with Jinja, introduced later, volition do this automatically.

escape() , shown here, can be used manually. It is omitted in near examples for brevity, only you should ever be aware of how you're using untrusted data.

                            from              markupsafe              import              escape              @app              .              route              (              "/<name>"              )              def              hello              (              proper noun              ):              render              f              "Howdy,                            {              escape              (              proper noun              )              }              !"            

If a user managed to submit the name <script>alert("bad")</script> , escaping causes it to be rendered every bit text, rather than running the script in the user's browser.

<name> in the route captures a value from the URL and passes it to the view function. These variable rules are explained below.

Routing¶

Modern web applications utilise meaningful URLs to help users. Users are more probable to like a folio and come back if the folio uses a meaningful URL they can remember and use to straight visit a folio.

Use the route() decorator to bind a function to a URL.

                            @app              .              route              (              '/'              )              def              index              ():              return              'Index Page'              @app              .              route              (              '/hello'              )              def              hello              ():              render              'Hello, World'            

You can practise more! Yous tin can make parts of the URL dynamic and attach multiple rules to a function.

Variable Rules¶

You tin add variable sections to a URL by marker sections with <variable_name> . Your function then receives the <variable_name> as a keyword argument. Optionally, you can employ a converter to specify the type of the argument like <converter:variable_name> .

                                from                markupsafe                import                escape                @app                .                route                (                '/user/<username>'                )                def                show_user_profile                (                username                ):                # show the user profile for that user                return                f                'User                                {                escape                (                username                )                }                '                @app                .                route                (                '/post/<int:post_id>'                )                def                show_post                (                post_id                ):                # testify the mail service with the given id, the id is an integer                return                f                'Post                                {                post_id                }                '                @app                .                route                (                '/path/<path:subpath>'                )                def                show_subpath                (                subpath                ):                # bear witness the subpath subsequently /path/                return                f                'Subpath                                {                escape                (                subpath                )                }                '              

Converter types:

string

(default) accepts any text without a slash

int

accepts positive integers

bladder

accepts positive floating indicate values

path

like cord but also accepts slashes

uuid

accepts UUID strings

Unique URLs / Redirection Behavior¶

The following two rules differ in their utilise of a abaft slash.

                                @app                .                route                (                '/projects/'                )                def                projects                ():                return                'The projection folio'                @app                .                route                (                '/nearly'                )                def                about                ():                return                'The nearly folio'              

The canonical URL for the projects endpoint has a abaft slash. Information technology'south similar to a folder in a file organisation. If y'all access the URL without a trailing slash ( /projects ), Flask redirects you lot to the canonical URL with the trailing slash ( /projects/ ).

The approved URL for the about endpoint does not take a abaft slash. It's similar to the pathname of a file. Accessing the URL with a trailing slash ( /about/ ) produces a 404 "Not Found" error. This helps keep URLs unique for these resources, which helps search engines avoid indexing the same folio twice.

URL Edifice¶

To build a URL to a specific role, use the url_for() function. Information technology accepts the name of the function equally its get-go argument and whatever number of keyword arguments, each respective to a variable part of the URL dominion. Unknown variable parts are appended to the URL equally query parameters.

Why would you lot want to build URLs using the URL reversing part url_for() instead of difficult-coding them into your templates?

  1. Reversing is often more descriptive than hard-coding the URLs.

  2. You can change your URLs in one go instead of needing to remember to manually change hard-coded URLs.

  3. URL edifice handles escaping of special characters transparently.

  4. The generated paths are always absolute, avoiding unexpected behavior of relative paths in browsers.

  5. If your awarding is placed outside the URL root, for case, in /myapplication instead of / , url_for() properly handles that for you.

For example, here we utilise the test_request_context() method to endeavor out url_for() . test_request_context() tells Flask to behave as though information technology'due south handling a request even while we use a Python crush. See Context Locals.

                                from                flask                import                url_for                @app                .                route                (                '/'                )                def                index                ():                return                'alphabetize'                @app                .                route                (                '/login'                )                def                login                ():                return                'login'                @app                .                route                (                '/user/<username>'                )                def                contour                (                username                ):                render                f                '                {                username                }                \'                s contour'                with                app                .                test_request_context                ():                print                (                url_for                (                'alphabetize'                ))                print                (                url_for                (                'login'                ))                print                (                url_for                (                'login'                ,                next                =                '/'                ))                print                (                url_for                (                'profile'                ,                username                =                'John Doe'                ))              
                / /login /login?next=/ /user/John%20Doe              

HTTP Methods¶

Web applications use dissimilar HTTP methods when accessing URLs. You should familiarize yourself with the HTTP methods as you piece of work with Flask. By default, a route only answers to GET requests. Y'all can employ the methods argument of the road() decorator to handle different HTTP methods.

                                from                flask                import                asking                @app                .                road                (                '/login'                ,                methods                =                [                'GET'                ,                'POST'                ])                def                login                ():                if                request                .                method                ==                'Post'                :                render                do_the_login                ()                else                :                render                show_the_login_form                ()              

If Become is present, Flask automatically adds back up for the HEAD method and handles HEAD requests according to the HTTP RFC. Likewise, OPTIONS is automatically implemented for you.

Static Files¶

Dynamic web applications also need static files. That's usually where the CSS and JavaScript files are coming from. Ideally your web server is configured to serve them for you, simply during development Flask can practise that also. But create a folder called static in your package or adjacent to your module and it will be available at /static on the application.

To generate URLs for static files, use the special 'static' endpoint name:

                            url_for              (              'static'              ,              filename              =              'mode.css'              )            

The file has to exist stored on the filesystem equally static/style.css .

Rendering Templates¶

Generating HTML from within Python is not fun, and really pretty cumbersome because you lot take to practise the HTML escaping on your own to proceed the awarding secure. Because of that Flask configures the Jinja2 template engine for you automatically.

To return a template you tin can use the render_template() method. All yous take to do is provide the name of the template and the variables y'all want to laissez passer to the template engine as keyword arguments. Here's a simple example of how to render a template:

                            from              flask              import              render_template              @app              .              route              (              '/hullo/'              )              @app              .              road              (              '/hi/<name>'              )              def              hello              (              proper name              =              None              ):              return              render_template              (              'hello.html'              ,              name              =              name              )            

Flask will look for templates in the templates folder. So if your application is a module, this folder is next to that module, if it'southward a bundle information technology's actually inside your packet:

Case 1: a module:

                            /              application              .              py              /              templates              /              hi              .              html            

Instance two: a package:

                            /              application              /              __init__              .              py              /              templates              /              hello              .              html            

For templates you tin use the full power of Jinja2 templates. Caput over to the official Jinja2 Template Documentation for more information.

Hither is an case template:

                            <!doctype html>              <              championship              >Hello from Flask</              championship              >              {%              if              name              %}              <              h1              >Hello              {{              name              }}!</              h1              >              {%              else              %}              <              h1              >How-do-you-do, World!</              h1              >              {%              endif              %}            

Inside templates you also have admission to the config , asking , session and g 1 objects as well as the url_for() and get_flashed_messages() functions.

Templates are especially useful if inheritance is used. If yous want to know how that works, see Template Inheritance. Basically template inheritance makes information technology possible to go along sure elements on each folio (like header, navigation and footer).

Automated escaping is enabled, so if proper noun contains HTML it volition be escaped automatically. If yous can trust a variable and you know that it will be safe HTML (for example because it came from a module that converts wiki markup to HTML) yous can mark it equally safe by using the Markup class or by using the |safety filter in the template. Head over to the Jinja two documentation for more examples.

Here is a basic introduction to how the Markup class works:

                            >>>                            from              markupsafe              import              Markup              >>>                            Markup              (              '<stiff>Hello                            %southward              !</stiff>'              )              %              '<blink>hacker</blink>'              Markup('<strong>Hullo &lt;glimmer&gt;hacker&lt;/blink&gt;!</stiff>')              >>>                            Markup              .              escape              (              '<glimmer>hacker</blink>'              )              Markup('&lt;glimmer&gt;hacker&lt;/blink&gt;')              >>>                            Markup              (              '<em>Marked up</em> &raquo; HTML'              )              .              striptags              ()              'Marked upward » HTML'            
Changelog

Changed in version 0.5: Autoescaping is no longer enabled for all templates. The following extensions for templates trigger autoescaping: .html , .htm , .xml , .xhtml . Templates loaded from a string will take autoescaping disabled.

1

Unsure what that thousand object is? It's something in which you can store information for your own needs. See the documentation for flask.1000 and Using SQLite three with Flask.

Accessing Asking Data¶

For web applications it'due south crucial to react to the information a customer sends to the server. In Flask this information is provided by the global request object. If you have some feel with Python y'all might be wondering how that object tin be global and how Flask manages to still exist threadsafe. The respond is context locals:

Context Locals¶

Insider Information

If you want to empathise how that works and how you tin can implement tests with context locals, read this department, otherwise but skip it.

Certain objects in Flask are global objects, merely non of the usual kind. These objects are actually proxies to objects that are local to a specific context. What a mouthful. But that is really quite piece of cake to understand.

Imagine the context being the handling thread. A request comes in and the web server decides to spawn a new thread (or something else, the underlying object is capable of dealing with concurrency systems other than threads). When Flask starts its internal request handling it figures out that the current thread is the active context and binds the current application and the WSGI environments to that context (thread). It does that in an intelligent way then that one application can invoke another application without breaking.

So what does this mean to you? Basically you can completely ignore that this is the case unless you lot are doing something like unit testing. You will detect that lawmaking which depends on a request object will suddenly break because there is no asking object. The solution is creating a request object yourself and binding information technology to the context. The easiest solution for unit testing is to use the test_request_context() context manager. In combination with the with statement information technology will bind a examination request so that you can interact with it. Hither is an example:

                                from                flask                import                request                with                app                .                test_request_context                (                '/hello'                ,                method                =                'POST'                ):                # now you can do something with the request until the                # terminate of the with block, such as basic assertions:                assert                request                .                path                ==                '/howdy'                assert                request                .                method                ==                'Mail'              

The other possibility is passing a whole WSGI environs to the request_context() method:

                                with                app                .                request_context                (                environ                ):                assert                request                .                method                ==                'Mail service'              

The Request Object¶

The request object is documented in the API section and we will not cover it here in detail (encounter Asking ). Hither is a broad overview of some of the most common operations. Kickoff of all you have to import it from the flask module:

                                from                flask                import                asking              

The current request method is available by using the method attribute. To admission class information (data transmitted in a Mail service or PUT request) you tin can utilize the form aspect. Hither is a full case of the two attributes mentioned above:

                                @app                .                route                (                '/login'                ,                methods                =                [                'Mail'                ,                'GET'                ])                def                login                ():                error                =                None                if                request                .                method                ==                'POST'                :                if                valid_login                (                asking                .                class                [                'username'                ],                asking                .                grade                [                'password'                ]):                render                log_the_user_in                (                request                .                form                [                'username'                ])                else                :                error                =                'Invalid username/password'                # the code below is executed if the request method                # was Go or the credentials were invalid                return                render_template                (                'login.html'                ,                fault                =                error                )              

What happens if the key does not exist in the form attribute? In that case a special KeyError is raised. Y'all can grab information technology like a standard KeyError but if y'all don't exercise that, a HTTP 400 Bad Request error page is shown instead. So for many situations y'all don't have to deal with that trouble.

To admission parameters submitted in the URL ( ?key=value ) you tin use the args attribute:

                                searchword                =                asking                .                args                .                get                (                'primal'                ,                ''                )              

We recommend accessing URL parameters with get or by catching the KeyError considering users might change the URL and presenting them a 400 bad request page in that example is not user friendly.

For a full list of methods and attributes of the request object, caput over to the Request documentation.

File Uploads¶

You tin can handle uploaded files with Flask easily. Just make certain not to forget to set the enctype="multipart/course-data" attribute on your HTML form, otherwise the browser will not transmit your files at all.

Uploaded files are stored in retention or at a temporary location on the filesystem. You lot tin can access those files by looking at the files attribute on the request object. Each uploaded file is stored in that lexicon. It behaves merely like a standard Python file object, but it also has a save() method that allows you to shop that file on the filesystem of the server. Hither is a simple example showing how that works:

                                from                flask                import                asking                @app                .                route                (                '/upload'                ,                methods                =                [                'GET'                ,                'Post'                ])                def                upload_file                ():                if                asking                .                method                ==                'POST'                :                f                =                request                .                files                [                'the_file'                ]                f                .                save                (                '/var/www/uploads/uploaded_file.txt'                )                ...              

If y'all want to know how the file was named on the client before information technology was uploaded to your awarding, you tin can access the filename attribute. However please keep in mind that this value can be forged so never e'er trust that value. If you want to employ the filename of the client to store the file on the server, pass it through the secure_filename() office that Werkzeug provides for yous:

                                from                werkzeug.utils                import                secure_filename                @app                .                route                (                '/upload'                ,                methods                =                [                'Go'                ,                'POST'                ])                def                upload_file                ():                if                request                .                method                ==                'Post'                :                file                =                request                .                files                [                'the_file'                ]                file                .                save                (                f                "/var/www/uploads/                {                secure_filename                (                file                .                filename                )                }                "                )                ...              

For some amend examples, come across Uploading Files.

Cookies¶

To access cookies y'all can use the cookies attribute. To fix cookies you can apply the set_cookie method of response objects. The cookies aspect of request objects is a dictionary with all the cookies the client transmits. If you want to use sessions, do not use the cookies directly but instead utilize the Sessions in Flask that add some security on top of cookies for yous.

Reading cookies:

                                from                flask                import                request                @app                .                road                (                '/'                )                def                index                ():                username                =                asking                .                cookies                .                get                (                'username'                )                # utilize cookies.get(cardinal) instead of cookies[key] to non become a                # KeyError if the cookie is missing.              

Storing cookies:

                                from                flask                import                make_response                @app                .                route                (                '/'                )                def                alphabetize                ():                resp                =                make_response                (                render_template                (                ...                ))                resp                .                set_cookie                (                'username'                ,                'the username'                )                return                resp              

Notation that cookies are fix on response objects. Since you normally just return strings from the view functions Flask will convert them into response objects for you. If you explicitly desire to practice that yous can employ the make_response() function and then alter it.

Sometimes you lot might want to set a cookie at a point where the response object does non be yet. This is possible by utilizing the Deferred Request Callbacks pattern.

For this also see About Responses.

Redirects and Errors¶

To redirect a user to another endpoint, use the redirect() function; to abort a request early on with an error code, employ the abort() part:

                            from              flask              import              abort              ,              redirect              ,              url_for              @app              .              road              (              '/'              )              def              index              ():              render              redirect              (              url_for              (              'login'              ))              @app              .              road              (              '/login'              )              def              login              ():              abort              (              401              )              this_is_never_executed              ()            

This is a rather pointless example because a user will be redirected from the index to a page they cannot access (401 means access denied) merely it shows how that works.

By default a black and white error page is shown for each fault lawmaking. If you want to customize the fault folio, you can employ the errorhandler() decorator:

                            from              flask              import              render_template              @app              .              errorhandler              (              404              )              def              page_not_found              (              error              ):              return              render_template              (              'page_not_found.html'              ),              404            

Note the 404 after the render_template() call. This tells Flask that the status lawmaking of that page should be 404 which means not found. By default 200 is assumed which translates to: all went well.

See Handling Application Errors for more than details.

About Responses¶

The return value from a view function is automatically converted into a response object for you. If the return value is a string it'south converted into a response object with the string equally response body, a 200 OK status code and a text/html mimetype. If the return value is a dict, jsonify() is called to produce a response. The logic that Flask applies to converting render values into response objects is equally follows:

  1. If a response object of the right blazon is returned it's direct returned from the view.

  2. If information technology's a string, a response object is created with that data and the default parameters.

  3. If information technology'due south a dict, a response object is created using jsonify .

  4. If a tuple is returned the items in the tuple can provide actress information. Such tuples have to be in the form (response, condition) , (response, headers) , or (response, status, headers) . The status value will override the condition lawmaking and headers tin can be a list or lexicon of boosted header values.

  5. If none of that works, Flask volition assume the return value is a valid WSGI awarding and convert that into a response object.

If you want to get concur of the resulting response object inside the view y'all can use the make_response() function.

Imagine you accept a view like this:

                            from              flask              import              render_template              @app              .              errorhandler              (              404              )              def              not_found              (              error              ):              return              render_template              (              'error.html'              ),              404            

Yous just need to wrap the return expression with make_response() and get the response object to modify information technology, then render it:

                            from              flask              import              make_response              @app              .              errorhandler              (              404              )              def              not_found              (              error              ):              resp              =              make_response              (              render_template              (              'error.html'              ),              404              )              resp              .              headers              [              'Ten-Something'              ]              =              'A value'              return              resp            

APIs with JSON¶

A common response format when writing an API is JSON. It'southward piece of cake to get started writing such an API with Flask. If you lot return a dict from a view, information technology will be converted to a JSON response.

                                @app                .                road                (                "/me"                )                def                me_api                ():                user                =                get_current_user                ()                return                {                "username"                :                user                .                username                ,                "theme"                :                user                .                theme                ,                "image"                :                url_for                (                "user_image"                ,                filename                =                user                .                image                ),                }              

Depending on your API design, you may desire to create JSON responses for types other than dict . In that case, use the jsonify() function, which will serialize whatsoever supported JSON data type. Or wait into Flask community extensions that support more than complex applications.

                                from                flask                import                jsonify                @app                .                route                (                "/users"                )                def                users_api                ():                users                =                get_all_users                ()                return                jsonify                ([                user                .                to_json                ()                for                user                in                users                ])              

Sessions¶

In add-on to the request object there is besides a second object called session which allows yous to shop information specific to a user from one request to the next. This is implemented on top of cookies for you and signs the cookies cryptographically. What this means is that the user could expect at the contents of your cookie but not modify it, unless they know the undercover central used for signing.

In order to utilise sessions you have to set a undercover fundamental. Hither is how sessions piece of work:

                            from              flask              import              session              # Set up the cloak-and-dagger key to some random bytes. Go along this actually underground!              app              .              secret_key              =              b              '_5#y2L"F4Q8z              \n\xec              ]/'              @app              .              route              (              '/'              )              def              index              ():              if              'username'              in              session              :              return              f              'Logged in as                            {              session              [              "username"              ]              }              '              render              'You are not logged in'              @app              .              route              (              '/login'              ,              methods              =              [              'GET'              ,              'POST'              ])              def              login              ():              if              request              .              method              ==              'Mail service'              :              session              [              'username'              ]              =              asking              .              form              [              'username'              ]              render              redirect              (              url_for              (              'alphabetize'              ))              return              '''                              <form method="post">                              <p><input blazon=text proper noun=username>                              <p><input type=submit value=Login>                              </course>                              '''              @app              .              road              (              '/logout'              )              def              logout              ():              # remove the username from the session if it's there              session              .              pop              (              'username'              ,              None              )              return              redirect              (              url_for              (              'index'              ))            

How to generate good secret keys

A secret fundamental should be as random as possible. Your operating organization has means to generate pretty random data based on a cryptographic random generator. Use the following control to quickly generate a value for Flask.secret_key (or SECRET_KEY ):

                $ python -c 'import secrets; print(secrets.token_hex())' '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'              

A notation on cookie-based sessions: Flask will take the values y'all put into the session object and serialize them into a cookie. If you are finding some values do non persist across requests, cookies are indeed enabled, and you are not getting a clear error message, cheque the size of the cookie in your folio responses compared to the size supported by web browsers.

Besides the default customer-side based sessions, if you want to handle sessions on the server-side instead, there are several Flask extensions that support this.

Message Flashing¶

Skillful applications and user interfaces are all almost feedback. If the user does non become enough feedback they will probably cease upwardly hating the application. Flask provides a actually simple way to give feedback to a user with the flashing system. The flashing organization basically makes it possible to record a message at the end of a request and admission it on the adjacent (and simply the adjacent) request. This is usually combined with a layout template to expose the message.

To wink a message use the flash() method, to get hold of the messages you can utilize get_flashed_messages() which is also available in the templates. See Bulletin Flashing for a full example.

Logging¶

Changelog

New in version 0.3.

Sometimes you might exist in a state of affairs where you deal with information that should be right, merely actually is not. For instance you may take some client-side code that sends an HTTP request to the server only it's patently malformed. This might be caused by a user tampering with the data, or the client code failing. Most of the time information technology's okay to reply with 400 Bad Asking in that situation, but sometimes that won't do and the code has to go along working.

You lot may nonetheless want to log that something fishy happened. This is where loggers come in handy. As of Flask 0.3 a logger is preconfigured for y'all to use.

Here are some example log calls:

                            app              .              logger              .              debug              (              'A value for debugging'              )              app              .              logger              .              warning              (              'A warning occurred (              %d                              apples)'              ,              42              )              app              .              logger              .              error              (              'An error occurred'              )            

The attached logger is a standard logging Logger , so head over to the official logging docs for more information.

See Handling Application Errors.

Hooking in WSGI Middleware¶

To add WSGI middleware to your Flask application, wrap the application's wsgi_app aspect. For example, to employ Werkzeug'southward ProxyFix middleware for running behind Nginx:

                            from              werkzeug.middleware.proxy_fix              import              ProxyFix              app              .              wsgi_app              =              ProxyFix              (              app              .              wsgi_app              )            

Wrapping app.wsgi_app instead of app ways that app still points at your Flask application, not at the middleware, and so y'all can continue to employ and configure app directly.

Using Flask Extensions¶

Extensions are packages that help you lot accomplish mutual tasks. For example, Flask-SQLAlchemy provides SQLAlchemy support that makes information technology elementary and easy to use with Flask.

For more on Flask extensions, encounter Extensions.

Deploying to a Web Server¶

Set up to deploy your new Flask app? See Deployment Options.