Overview

Main Purpose and Functionality

This is Flask, a WSGI web application framework. A Flask object (flask.app) is the central object of an application. It is created with the application's import name and acts as the registry for view functions, URL rules, template configuration and more. A WSGI server calls the app directly, and Flask.__call__() delegates to Flask.wsgi_app().

The flask package re-exports its public API from the modules that define it:

Module Exported names
flask.app Flask
flask.blueprints Blueprint
flask.config Config
flask.ctx after_this_request, copy_current_request_context, has_app_context, has_request_context
flask.helpers abort, flash, get_flashed_messages, get_template_attribute, make_response, redirect, send_file, send_from_directory, stream_with_context, url_for
flask.json jsonify
flask.templating render_template, render_template_string, stream_template, stream_template_string
flask.wrappers Request, Response

The package also includes a flask.cli command-line interface for running a development server, opening a shell and listing routes.

Key Components and Responsibilities

Application classes

  • Scaffold (flask.sansio.scaffold) holds behavior shared by Flask and Blueprint. It provides:
    • the route decorators route(), get(), post(), put(), delete(), patch() and query(), plus add_url_rule() and endpoint();
    • the hook registrars before_request(), after_request(), teardown_request(), context_processor() and url_value_preprocessor();
    • the static_folder and static_url_path properties and jinja_loader.
  • App(Scaffold) (flask.sansio.app) is the I/O-independent application base. It handles:
    • construction parameters: import_name, static and template folders, instance_path, host_matching, subdomain_matching and root_path;
    • the name, logger, jinja_env and debug properties;
    • make_config(), make_aborter(), auto_find_instance_path(), create_global_jinja_loader() and select_jinja_autoescape();
    • register_blueprint(), iter_blueprints() and add_url_rule();
    • template registration decorators such as template_filter().
  • Flask(App) (flask.app) adds the runtime parts:
    • wsgi_app() and __call__();
    • run(), send_static_file(), get_send_file_max_age(), open_resource() and open_instance_resource();
    • create_jinja_environment(), create_url_adapter(), raise_routing_exception(), update_template_context() and make_shell_context().
  • Blueprint(Scaffold) (flask.sansio.blueprints) is a collection of routes and app-related functions that is registered on an application later. It provides:
    • record() and record_once() for deferred setup functions;
    • make_setup_state(), register() and register_blueprint() for nested blueprints;
    • app_template_filter(), add_app_template_filter() and app_template_test() for app-wide template registrations.
  • Blueprint(SansioBlueprint) (flask.blueprints) adds get_send_file_max_age(), send_static_file() and open_resource().

Configuration

Config(dict) (flask.config) behaves like a dict and can be filled from several sources:

  • from_envvar()
  • from_prefixed_env() (prefix defaults to "FLASK", values parsed with json.loads by default)
  • from_pyfile()
  • from_object()
  • from_file() (takes a caller-supplied load callable)
  • from_mapping()

get_namespace() extracts the keys under a given prefix.

Request, response and context

  • Request (flask.wrappers) is the default request object. It records the matched endpoint and view arguments, and exposes endpoint, blueprint, blueprints, max_content_length, max_form_memory_size and max_form_parts. It also provides on_json_loading_failed().
  • Response (flask.wrappers) works like Werkzeug's response but defaults to an HTML mimetype. It exposes max_cookie_size. Flask.make_response() normally creates it.
  • AppContext (flask.ctx) carries information about the app and, when handling a request, about the request. It is pushed at the start of each request or CLI command and popped at the end. It has push(), pop(exc), from_environ(), has_request, copy(), request, session and match_request().

JSON

JSONProvider (flask.json.provider) is constructed with the app and defines dumps(), dump(), loads(), load() and response(). Subclasses can customize JSON behavior or use a different JSON library.

Debug helpers

flask.debughelpers.explain_template_loading_attempts() builds a report of each template loader tried. For each loader it lists the source (application or blueprint), the loader's public attributes via _dump_loader_info(), and whether the template was matched. It also looks up the current request's blueprint through the app context.

CLI

flask.cli is built on click:

  • The group's make_context() sets FLASK_RUN_FROM_CLI=true so app.run() becomes a no-op. It also attaches a ScriptInfo as obj, built from the group's create_app, set_debug_flag and load_dotenv settings.
  • The group's parse_args() handles the no_args_is_help and help-option cases by calling handle_parse_result() on the --env-file and --app options early, so commands from app.cli can be listed.
  • When listing commands, the group merges in the loaded app's cli commands. A NoAppException shows only its message, and any other exception shows the full traceback.
  • run_command (run) accepts --host, --port, --cert, --key, --reload/--no-reload, --debugger/--no-debugger, --with-threads/--without-threads, --extra-files and --exclude-patterns.
  • The shell command opens an interactive interpreter with a banner showing the Python version, app and instance path. It runs any PYTHONSTARTUP script, loads current_app.make_shell_context() into the namespace and installs a readline completer bound to that namespace.
  • routes_command (routes) lists current_app.url_map rules. --sort accepts endpoint, methods, domain, rule or match, where match is the order Flask matches routes when dispatching. --all-methods includes HEAD and OPTIONS.
  • main is the CLI entry point.

How Different Parts Work Together

Request handling

Flask.wsgi_app() is the core of request processing:

  1. It creates a context with self.request_context(environ), then calls ctx.push() and self.full_dispatch_request(ctx).
  2. If an Exception is raised, it records the error and produces the response through self.handle_exception(ctx, e). Non-Exception exceptions are recorded and re-raised.
  3. It calls the response as a WSGI application with (environ, start_response).
  4. In the finally block it hands the context to environ["werkzeug.debug.preserve_context"] if that key is present. If should_ignore_error is set and returns true for the error, the error is cleared. It then calls ctx.pop(error).

__call__() is kept separate from wsgi_app() so middleware can wrap app.wsgi_app without losing the reference to the app object:

app.wsgi_app = MyMiddleware(app.wsgi_app)

Registration and blueprints

Both Flask and Blueprint get their decorators (route(), before_request() and so on) from Scaffold, so they are used the same way. A blueprint does not act immediately. Its Blueprint.register(app, options) is called when it is registered on an app, and record() and record_once() store deferred setup functions. Blueprint.make_setup_state() creates the state those functions run against. Blueprints can also register other blueprints through register_blueprint().

Configuration and CLI flow

The app builds its config in App.make_config(), and Config loads values from files, objects, mappings or environment variables. The CLI group loads the app through ScriptInfo, and commands such as shell and routes use current_app inside an app context. shell also relies on Flask.make_shell_context().

Overall Architecture and Design Patterns

  • Library/framework style: Flask is a micro-framework built around one central application object plus context objects, not a service.
  • Sans-I/O layering: I/O-independent logic lives in flask.sansio (Scaffold, App, Blueprint). The concrete Flask and Blueprint classes in flask.app and flask.blueprints subclass those and add file access, static file serving and the WSGI interface. Within flask.sansio, Scaffold is the common base for both App and Blueprint.
  • Template Method / extension points: App has overridable factory-style methods, such as make_config(), make_aborter(), create_jinja_environment(), create_url_adapter() and make_setup_state(). These let subclasses customize the objects the app builds.
  • Strategy: JSONProvider defines a pluggable JSON interface bound to an app, so serialization can be swapped without changing callers like jsonify.
  • Decorator-based registration: routes, request hooks, context processors and template filters are all registered with decorators, with add_url_rule() as the underlying call.
  • Command pattern with deferred execution: blueprints record setup functions and replay them at registration time.
  • Context objects: AppContext is pushed and popped around each request and CLI command, which is how helpers like current_app work. wsgi_app() guarantees the pop, passing along any error, even when handling fails.
  • Decorator/wrapper pattern: Request and Response extend Werkzeug's classes with Flask-specific behavior, and the WSGI middleware pattern is supported directly through the __call__()/wsgi_app() split.