Skip to main content

Basic Routing and HTTP Methods

In this tutorial, you will build a basic web application that maps various URL patterns to Python functions. You will learn how to handle different HTTP verbs like GET and POST using both decorators and manual registration methods provided by the Scaffold class.

Prerequisites

To follow this tutorial, you need the flask package installed in your environment. This codebase uses Scaffold as the base for both the main Flask application and Blueprint objects, so the routing techniques shown here apply to both.

Step 1: Create a Basic Route

The most common way to define a route is using the @app.route decorator. By default, this decorator responds to GET requests.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello, World!"

In this example, the @app.route("/") decorator tells the application that whenever a user visits the root URL, it should execute the index() function. This internally calls Scaffold.route, which registers the URL rule in the application's routing system.

Step 2: Use HTTP Method Shortcuts

Flask provides specific decorators for standard HTTP methods, making your code more readable. These shortcuts were introduced in Flask 2.0 and are implemented in the Scaffold class.

@app.get("/items")
def get_items():
return "Fetching all items..."

@app.post("/items")
def add_item():
return "Item added successfully!", 201

The @app.get and @app.post decorators are shortcuts for @app.route(..., methods=["GET"]) and @app.route(..., methods=["POST"]). The Scaffold class also provides @app.put, @app.delete, and @app.patch.

Note: You cannot pass a methods argument to these shortcut decorators; they are strictly bound to their respective HTTP verb.

Step 3: Handle Multiple Methods in One Function

Sometimes you want a single function to handle multiple types of requests, such as a login page that displays a form on GET and processes the form on POST.

@app.route("/login", methods=["GET", "POST"])
def login():
return "Handling login logic"

When using the generic @app.route decorator, you can provide a list of strings to the methods argument.

Warning: The methods argument must be a list (e.g., ["GET", "POST"]). If you pass a single string like methods="GET", the application will raise a TypeError because it expects an iterable of strings.

Step 4: Register Routes Manually

In some cases, you might prefer to define your functions separately from the routing logic. You can use the add_url_rule method for this.

def contact_us():
return "Contact us at support@example.com"

app.add_url_rule("/contact", view_func=contact_us)

The Scaffold.add_url_rule method is what the @app.route decorator calls internally. It maps the URL rule /contact to the view_func named contact_us. By default, the "endpoint" name for this route will be the name of the function ("contact_us").

Step 5: Organize with Blueprints

Because Blueprint also inherits from Scaffold, you can use all the same routing methods to organize your application into components.

from flask import Blueprint

admin_bp = Blueprint("admin", __name__)

@admin_bp.get("/dashboard")
def dashboard():
return "Admin Dashboard"

app.register_blueprint(admin_bp, url_prefix="/admin")

When you register the blueprint on the main app, the route becomes accessible at /admin/dashboard.

Complete Example

Here is the complete code combining these concepts:

from flask import Flask, Blueprint

app = Flask(__name__)
api_bp = Blueprint("api", __name__)

# Basic GET route
@app.route("/")
def index():
return "Welcome to the Home Page"

# Method shortcuts
@api_bp.get("/status")
def status():
return {"status": "online"}

# Multiple methods
@app.route("/submit", methods=["GET", "POST"])
def submit():
return "Form submitted or displayed"

# Manual registration
def about():
return "About this application"

app.add_url_rule("/about", view_func=about)

# Registering the blueprint
app.register_blueprint(api_bp, url_prefix="/api")

if __name__ == "__main__":
app.run()

Important Constraints

  1. Late Registration: You must define all routes before the application starts handling requests. If you attempt to call add_url_rule or any route decorator after the first request has been processed, Flask will raise an AssertionError.
  2. Automatic Methods: Flask automatically handles OPTIONS and HEAD requests for your routes unless you explicitly disable this behavior via the PROVIDE_AUTOMATIC_OPTIONS configuration or the provide_automatic_options parameter in add_url_rule.