Web Development
Web Development Interview with follow-up questions
1. Can you explain what Flask is and why it is used in Python web development?
Flask is a lightweight WSGI micro-framework for building web apps and APIs in Python. "Micro" means it ships a small core — routing, request/response handling, and Jinja2 templating — and leaves the rest (database, auth, forms) to extensions you add as needed (Flask-SQLAlchemy, Flask-Login, etc.). That minimalism and flexibility make it a favorite for small-to-medium apps, prototypes, and microservices.
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/users/")
def get_user(user_id: int):
return jsonify({"id": user_id, "name": "Alice"})
Why it's used: minimal boilerplate, explicit, easy to learn, and unopinionated so you assemble your own stack.
Interviewer follow-ups:
- Flask vs Django: Flask is a micro-framework (you choose the pieces); Django is batteries-included (built-in ORM, admin, auth). Pick Flask for flexibility/small services, Django for large apps that benefit from convention.
- Flask vs FastAPI — the one most likely to come up in 2026: FastAPI is the modern async (ASGI) alternative with Pydantic validation and automatic OpenAPI docs, and it's now the common choice for new APIs. Flask remains hugely popular and added async route support, but it's WSGI at its core.
- Production: never use the built-in dev server — run behind Gunicorn (WSGI).
Follow-up 1
What are some of the main features of Flask?
Some of the main features of Flask are:
- Lightweight and easy to use
- Built-in development server and debugger
- URL routing
- Template rendering
- Support for cookies and sessions
- Database integration
- Extension ecosystem
- RESTful request handling
- Unit testing support
These features make Flask a versatile framework for building web applications and APIs.
Follow-up 2
Can you compare Flask with Django?
Flask and Django are both popular web frameworks for Python, but they have some key differences:
- Flask is a micro framework, while Django is a full-featured framework. This means that Flask is more lightweight and flexible, while Django provides more out-of-the-box functionality.
- Flask is better suited for small to medium-sized projects, while Django is often used for larger, more complex projects.
- Flask has a simpler learning curve, while Django has a steeper learning curve.
- Flask allows developers to have more control over the project structure and components, while Django follows a more opinionated approach.
Ultimately, the choice between Flask and Django depends on the specific requirements of the project and the preferences of the developer.
Follow-up 3
How do you set up a basic Flask application?
To set up a basic Flask application, follow these steps:
- Install Flask using pip:
pip install flask - Create a new Python file for your application, e.g.,
app.py - Import the Flask module:
from flask import Flask - Create an instance of the Flask class:
app = Flask(__name__) - Define a route and a function to handle the route:
@app.route('/')
def hello():
return 'Hello, World!'
- Run the application:
if __name__ == '__main__':
app.run()
This will start a development server, and you can access your Flask application by visiting http://localhost:5000 in your web browser.
Follow-up 4
What is a Flask route?
A Flask route is a URL pattern that the application will respond to. It is defined using the @app.route() decorator. The route decorator takes a URL pattern as an argument and binds it to a function that will be executed when that URL is requested. For example:
@app.route('/')
def index():
return 'Hello, World!'
In this example, the route decorator binds the URL pattern '/' to the index function. When a user visits the root URL of the application, Flask will call the index function and return the string 'Hello, World!' as the response.
Follow-up 5
Can you explain how to use templates in Flask?
Templates in Flask are used for rendering dynamic HTML pages. Flask uses the Jinja2 templating engine by default. To use templates in Flask, follow these steps:
- Create a
templatesfolder in your project directory. - Create an HTML template file inside the
templatesfolder, e.g.,index.html. - In your Flask route function, use the
render_templatefunction to render the template:
from flask import render_template
@app.route('/')
def index():
return render_template('index.html', name='John')
- In your template file, you can access the variables passed from the route function using Jinja2 syntax:
Flask Template
<h1>Hello, {{ name }}!</h1>
In this example, the name variable is passed to the template and rendered as 'John' in the HTML page.
2. What are the steps involved in setting up a Flask application?
A minimal Flask app:
- Install into a virtual environment:
pip install flask. - Create the app: in a Python file, instantiate
Flask. - Define routes with the
@app.routedecorator that return responses. - Run it in development with
flask run(orapp.run()for quick local testing).
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index() -> str:
return "Hello, World!"
Run with flask --app app run --debug during development.
What separates a junior answer from a strong one:
- Don't ship
app.run()to production. The built-in server is dev-only; in production run behind Gunicorn (WSGI), often with Nginx in front. - For anything beyond a toy, use the application factory pattern — a
create_app()function that builds and configures the app — plus Blueprints to split routes into modules. This makes testing and config-per-environment clean. - Configuration comes from a config object/file or environment variables (e.g.
SECRET_KEY), not hard-coded. - Pin dependencies (
requirements.txt/pyproject.toml) and isolate with a virtual environment.
Follow-up 1
How do you define routes in a Flask application?
In a Flask application, you can define routes using the @app.route() decorator. This decorator is used to associate a URL with a function that will be executed when that URL is accessed. For example:
@app.route('/')
def index():
return 'Hello, World!'
Follow-up 2
What is the role of the Flask application object?
The Flask application object is the core of a Flask application. It is an instance of the Flask class and is responsible for handling requests and returning responses. The application object is used to define routes, handle form data, connect to databases, and more.
Follow-up 3
How can you handle form data in Flask?
To handle form data in Flask, you can use the request object. The request object contains the data submitted in a form and provides methods to access and manipulate this data. For example, you can use request.form to access the form data as a dictionary, or request.args to access query string parameters.
Follow-up 4
How do you connect a Flask application to a database?
To connect a Flask application to a database, you can use a database library such as Flask-SQLAlchemy or Flask-MySQL. These libraries provide an interface to interact with databases using Python. You need to configure the database connection settings in your Flask application and then use the library's API to perform database operations.
Follow-up 5
Can you explain how to use Flask-SQLAlchemy?
Flask-SQLAlchemy is a Flask extension that provides integration with the SQLAlchemy library. SQLAlchemy is a popular Object-Relational Mapping (ORM) library for Python. To use Flask-SQLAlchemy, you need to install it using pip: pip install flask-sqlalchemy. Then, you can create a SQLAlchemy object and bind it to your Flask application. This allows you to define models, create database tables, and perform database operations using SQLAlchemy's API.
3. How can you handle user sessions in Flask?
Flask's session object stores per-user data across requests. Under the hood it's a signed cookie: the data is serialized, stored in the cookie on the client, and cryptographically signed with your SECRET_KEY so the client can't tamper with it. You must set SECRET_KEY or sessions won't work.
from flask import Flask, session
app = Flask(__name__)
app.secret_key = "set-from-env-not-hardcoded" # load from env in real apps
@app.route("/login")
def login():
session["username"] = "John"
return "Session is set"
@app.route("/profile")
def profile():
username = session.get("username") # .get avoids KeyError
return f"Hello {username}" if username else "Not logged in"
@app.route("/logout")
def logout():
session.pop("username", None)
return "Session cleared"
The gotchas interviewers probe:
- It's signed, not encrypted. The user can read the cookie contents (it's base64), so never store secrets (passwords, tokens) in it. Signing only prevents modification.
SECRET_KEYmust be strong and kept out of source control (load from env). Rotating it invalidates all sessions.- Size limit (~4KB cookie). For larger or truly sensitive state, use server-side sessions (e.g. Flask-Session backed by Redis), storing only an ID in the cookie.
- For real auth, use Flask-Login rather than hand-rolling, and set
Secure/HttpOnly/SameSitecookie flags.
Follow-up 1
What is a secure cookie?
A secure cookie is a cookie that is only sent over HTTPS, ensuring that the cookie is encrypted and cannot be intercepted by attackers. In Flask, you can make a cookie secure by setting the 'secure' flag to True when setting the cookie. Here's an example:
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def set_secure_cookie():
response = make_response('Cookie set')
response.set_cookie('my_cookie', 'my_value', secure=True)
return response
if __name__ == '__main__':
app.run()
Follow-up 2
How can you protect against cross-site request forgery (CSRF) in Flask?
To protect against cross-site request forgery (CSRF) attacks in Flask, you can use the 'csrf_protect' decorator provided by the Flask-WTF extension. Flask-WTF integrates with Flask and provides CSRF protection for forms. Here's an example of how to use Flask-WTF to protect against CSRF attacks:
from flask import Flask, render_template
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
csrf = CSRFProtect(app)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run()
In the above example, you would need to create an HTML template called 'index.html' that includes a CSRF token in the form. Flask-WTF automatically generates and validates the CSRF token for you.
Follow-up 3
How do you use Flask-Login for user authentication?
Flask-Login is a Flask extension that provides user session management, including login, logout, and user authentication. Here's an example of how to use Flask-Login for user authentication:
from flask import Flask, render_template, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
login_manager = LoginManager()
login_manager.init_app(app)
class User(UserMixin):
def __init__(self, id):
self.id = id
@login_manager.user_loader
def load_user(user_id):
return User(user_id)
@app.route('/')
def index():
return 'Home'
@app.route('/login')
def login():
user = User(1)
login_user(user)
return redirect(url_for('index'))
@app.route('/logout')
@login_required
def logout():
logout_user()
return 'Logged out'
if __name__ == '__main__':
app.run()
In the above example, the 'User' class represents a user object and is required by Flask-Login. The 'login_manager.user_loader' decorator is used to load the user object from the user ID. The 'login_user' function is used to log in the user, and the 'logout_user' function is used to log out the user. The 'login_required' decorator is used to protect routes that require authentication.
Follow-up 4
What is the purpose of Flask's 'g' object?
Flask's 'g' object is a global object that is used to store data during a single request. It is commonly used to store information that needs to be accessed by multiple functions within the same request context. The 'g' object is unique to each request and is not shared between different requests. Here's an example of how to use Flask's 'g' object:
from flask import Flask, g
app = Flask(__name__)
@app.route('/')
def index():
g.user = 'John'
return 'User set'
@app.route('/get_user')
def get_user():
if 'user' in g:
return f'Hello {g.user}'
else:
return 'User not set'
if __name__ == '__main__':
app.run()
In the above example, the 'g.user' attribute is set in the 'index' function and can be accessed in the 'get_user' function within the same request context.
Follow-up 5
Can you explain how to use Flask's 'session' object?
Flask's 'session' object is a dictionary-like object that allows you to store data specific to a user across multiple requests. It is similar to the 'g' object, but the 'session' object persists data across different requests. To use the 'session' object in Flask, you need to set a secret key for your application. Here's an example of how to use Flask's 'session' object:
from flask import Flask, session, redirect, url_for
app = Flask(__name__)
app.secret_key = 'your_secret_key'
@app.route('/')
def index():
session['username'] = 'John'
return 'Session is set'
@app.route('/get_session')
def get_session():
if 'username' in session:
return f'Hello {session['username']}'
else:
return 'Session not set'
@app.route('/clear_session')
def clear_session():
session.clear()
return 'Session cleared'
if __name__ == '__main__':
app.run()
In the above example, the 'session' object is used to store the 'username' value, which can be accessed in different routes. The 'session.clear()' function is used to clear the session data.
4. How can you handle errors in a Flask application?
Flask handles errors with the @app.errorhandler decorator (register a handler for a status code or exception class) and the abort() function to raise HTTP errors deliberately. The handler receives the error and returns a response plus status code:
from flask import Flask, jsonify, abort
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
return jsonify({"error": "Not found"}), 404
@app.errorhandler(Exception) # catch-all for unhandled exceptions
def server_error(error):
app.logger.exception(error) # log the traceback
return jsonify({"error": "Internal server error"}), 500
@app.route("/users/")
def get_user(user_id: int):
user = db.get(user_id)
if user is None:
abort(404) # triggers the 404 handler
return jsonify(user)
Interviewer follow-ups:
abort(code)is the clean way to bail out with an HTTP error from within a view; it raises anHTTPExceptionthat your handler catches.- For APIs, return JSON, not HTML error pages, and use the right status codes (400 validation, 401/403 auth, 404 missing, 500 server).
- Register handlers on Blueprints for modular apps, and a global handler for
Exceptionas a safety net — but log the real error (app.logger.exception) rather than leaking stack traces to the client. - Don't run with
debug=Truein production; the interactive debugger is a security risk. (FastAPI handles this similarly via exception handlers + Pydantic validation errors.)
Follow-up 1
What is the purpose of Flask's errorhandler decorator?
The purpose of Flask's errorhandler decorator is to define a function that will be called whenever an error occurs in a Flask application. This allows you to handle errors in a centralized way, instead of having to handle them individually in each view function. The function should take the error as an argument and return a response to be sent back to the client.
Follow-up 2
How can you customize error pages in Flask?
To customize error pages in Flask, you can create error handler functions using the errorhandler decorator. Each error handler function should be decorated with the specific error code you want to handle. For example, to customize the 404 error page, you can define a function decorated with @app.errorhandler(404). Inside the function, you can return a custom response or render a custom template to be displayed to the user.
Follow-up 3
What is the difference between a 404 error and a 500 error?
A 404 error is a client-side error that occurs when the requested resource is not found on the server. It typically indicates that the URL or route specified by the client is incorrect or does not exist. On the other hand, a 500 error is a server-side error that occurs when there is an internal server error or an unhandled exception in the application. It indicates that something went wrong on the server side and the client's request could not be fulfilled.
Follow-up 4
How can you log errors in a Flask application?
In a Flask application, you can log errors using the logging module. You can configure a logger in your Flask application and use it to log errors and other messages. Here's an example of how to configure a logger and log an error:
import logging
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
try:
# Code that may raise an error
except Exception as e:
app.logger.error('An error occurred: %s', str(e))
Follow-up 5
Can you explain how to use Flask's 'abort' function?
Flask's abort function is used to raise an HTTP exception. It allows you to return an error response with a specific status code and message. Here's an example of how to use the abort function to raise a 404 error:
from flask import Flask, abort
app = Flask(__name__)
@app.route('/user/')
def get_user(user_id):
user = get_user_from_database(user_id)
if not user:
abort(404, 'User not found')
return render_template('user.html', user=user)
5. How can you create RESTful APIs using Flask?
You can build a REST API in plain Flask with @app.route(..., methods=[...]) and jsonify, mapping HTTP verbs (GET/POST/PUT/PATCH/DELETE) to resource operations:
from flask import Flask, request, jsonify, abort
app = Flask(__name__)
users: dict[int, dict] = {}
@app.route("/users", methods=["GET", "POST"])
def users_collection():
if request.method == "POST":
data = request.get_json()
uid = len(users) + 1
users[uid] = {"id": uid, **data}
return jsonify(users[uid]), 201 # 201 Created
return jsonify(list(users.values()))
@app.route("/users/", methods=["GET", "DELETE"])
def user_item(uid: int):
if uid not in users:
abort(404)
if request.method == "DELETE":
users.pop(uid)
return "", 204
return jsonify(users[uid])
What interviewers want beyond the basics:
- Use an extension for non-trivial APIs: Flask-RESTful is older; flask-smorest (or APIFlask) is the modern pick because it adds marshmallow/Pydantic-style validation and automatic OpenAPI/Swagger docs.
- Get the REST fundamentals right: resource-based URLs, correct verbs, correct status codes (200/201/204/400/404), and input validation.
- The honest 2026 contrast: if you're starting a new API and want async, type-based validation, and free OpenAPI docs out of the box, FastAPI is now the common default over Flask.
Follow-up 1
How do you define resources in Flask-RESTful?
In Flask-RESTful, resources are defined as classes that inherit from the flask_restful.Resource class. Each resource class represents a specific endpoint in your API. You can define methods within the resource class to handle different HTTP methods (e.g., GET, POST, PUT, DELETE).
Follow-up 2
How can you handle request data in Flask-RESTful?
Flask-RESTful provides a convenient way to handle request data. You can access the request data using the flask_restful.reqparse.RequestParser class. This class allows you to define the expected arguments and their types, and automatically parse the request data for you.
Follow-up 3
What is the purpose of Flask's 'request' object?
The request object in Flask provides access to the current request context. It allows you to access various properties of the request, such as the request method, headers, form data, and JSON data. You can use the request object to handle and process incoming requests in your Flask application.
Follow-up 4
Can you explain how to use Flask's 'url_for' function?
The url_for function in Flask is used to generate URLs for specific routes in your application. It takes the name of the route as an argument and returns the corresponding URL. You can use the url_for function in your templates or views to generate dynamic URLs. For example:
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/')
def index():
return url_for('hello')
@app.route('/hello')
def hello():
return 'Hello, World!'
Follow-up 5
What is Flask-RESTful?
Flask-RESTful is an extension for Flask that adds support for quickly building REST APIs. It provides a simple and intuitive way to define resources, handle HTTP methods, and serialize/deserialize data.
Live mock interview
Mock interview: Web Development
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.