Flask Interview Questions

Real Flask interview questions covering philosophy, app factories, blueprints, auth, testing, and WSGI.

A curated set of Flask interview questions, ordered roughly from fundamentals to more advanced — the kind you'll actually be asked in real screens and on-sites.

Philosophy & fundamentals

Q: How do you decide between Flask and Django for a new project? Flask fits small APIs, microservices, or any project where the team wants full control over structure and doesn't need an ORM, admin panel, or auth system out of the box. Django fits larger, more conventional web applications where a standard, batteries-included structure (ORM, admin site, forms, auth) saves real time and keeps a bigger team consistent. Neither choice is about raw performance — it's about how much structure you want the framework to hand you versus decide yourself.

Q: What is WSGI, and where does Flask sit relative to it? WSGI (Web Server Gateway Interface) is the standard Python interface between a web server and a Python web application, letting any WSGI-compliant server (Gunicorn, uWSGI, mod_wsgi) run any WSGI-compliant framework. Flask is built directly on Werkzeug, which implements the WSGI side of the equation — this is why a Flask app can be deployed behind any standard Python application server without any Flask-specific server needed.

Application structure

Q: What is the application factory pattern, and why use it instead of a single global app object? Instead of creating the Flask app at import time in a module, you write a create_app() function that builds and returns a configured app instance:

Python
def create_app(config_name="development"):
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    db.init_app(app)
    from .routes import bp
    app.register_blueprint(bp)

    return app

This makes it possible to create multiple independently configured instances of the app — most importantly, a separate instance configured for automated tests (pointed at a throwaway test database) without touching the instance used for real development or production.

Q: What are Flask blueprints, and when would you reach for them? A blueprint is a way to group a related set of routes, templates, and static files into a reusable component, registered on the main app with app.register_blueprint(). They're the standard tool for splitting a growing single-file Flask app into modules — an auth blueprint, a blog blueprint, an api blueprint — each maintained (and even reused across projects) independently, instead of every route living in one increasingly unwieldy file.

Requests, context & extensions

Q: You can just from flask import request anywhere and it "knows" the current request — how does that actually work? request isn't a plain global variable holding one shared object; it's a context-local proxy provided by Werkzeug. Flask pushes a request context onto an internal stack at the start of handling each incoming request, and the request proxy transparently forwards attribute access to whichever request context is active for the current thread/greenlet at that moment. This is also why code that touches request outside of an active request (e.g., in a background job with no incoming HTTP request) raises a RuntimeError — there's no context for the proxy to point at.

Q: What does jsonify() do that returning a plain Python dict from a view doesn't? jsonify() serializes the given data to a JSON string and sets the Content-Type: application/json response header, and lets you attach a custom status code or headers alongside it (jsonify(...), 201). Since Flask 1.1, returning a plain dict is also auto-converted to an equivalent JSON response, but jsonify remains the explicit, more flexible choice whenever you need anything beyond a bare 200 JSON body — and it's the only option for a top-level JSON array response.

Authentication

Q: Is a Flask session cookie safe to store sensitive data in, and what does Flask-Login add on top of it? No — the session cookie is signed against tampering with app.secret_key, but its contents are only base64-encoded, not encrypted, so anything stored there is readable by the browser or anyone who intercepts the cookie; only non-sensitive identifiers (like a user ID) belong in it. Flask-Login builds on session to provide a full login lifecycle: a current_user context-local proxy, a @login_required decorator that redirects unauthenticated requests to a configured login view, and a user_loader hook that reloads the right user object from the session on each request.

Testing

Q: What's the practical benefit of Flask's test_client() over calling a view function directly in a test? test_client() sends a simulated but genuinely complete HTTP request through Flask's real routing, request/response cycle, and any decorators or before/after-request hooks — the same path a real request takes. Calling the view function directly bypasses all of that, so a bug in routing, in @login_required, or in how the request object is parsed would go undetected even if the view's own logic were correct in isolation.

Deployment

Q: What two specific things change between flask run locally and a real production deployment? The server itself changes — Gunicorn (or another production WSGI server) replaces Flask's single-threaded development server, adding real concurrency and hardening against the kind of traffic the dev server was never built to handle. And debug/FLASK_DEBUG must be off, since the interactive debugger it enables would otherwise let anyone who triggers an unhandled exception on the live site execute arbitrary Python code from their browser.

Q: Why copy requirements.txt and install dependencies before copying the rest of the app in a Flask Dockerfile? Docker caches each instruction as a layer, and reuses a cached layer as long as its inputs haven't changed. Copying requirements.txt and running pip install before copying the full application means that layer is only rebuilt when dependencies actually change — an ordinary code-only change reuses the cached dependency-install layer instead of reinstalling every package on every single build.