Flask HTTP Methods
Every request a browser sends to a server uses an HTTP method. The method tells the server what the browser wants to do — retrieve data, send data, update data, or delete data. Flask lets you specify which HTTP methods each route accepts.
The Four Core HTTP Methods
Think of HTTP methods like verbs in a sentence. The URL is the noun (what you're acting on), and the method is the verb (what you're doing to it).
| Method | Real-World Action | Web Equivalent |
|---|---|---|
| GET | Reading a menu | Fetching a web page |
| POST | Placing an order | Submitting a form |
| PUT | Replacing your whole order | Updating a resource completely |
| DELETE | Cancelling your order | Removing a resource |
GET: The Default Method
By default, every Flask route accepts only GET requests. When you type a URL in the browser and press Enter, the browser sends a GET request. Flask returns the page.
@app.route('/products')
def products():
return '<h1>All Products</h1>'This route responds to GET /products only. If another method tries to access it, Flask returns a 405 Method Not Allowed error.
Accepting POST Requests
When a user fills out a form and clicks Submit, the browser sends a POST request. The form data travels in the request body (invisible in the URL). Tell Flask to accept POST by listing it in the methods argument:
from flask import Flask, request
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
return f'Logging in as {username}'
return '''
<form method="POST">
<input name="username" placeholder="Username">
<input name="password" type="password" placeholder="Password">
<button type="submit">Login</button>
</form>
'''What Happens at Each Step
User visits /login in browser
│
GET /login
│
Flask checks: request.method == 'GET'
│
Returns the HTML form
│
User fills form and clicks Login
│
POST /login
│
Flask checks: request.method == 'POST'
│
Reads request.form data
│
Processes login
Separating GET and POST into Different Functions
Flask 2.0 and newer allow you to split GET and POST into separate functions using dedicated decorators:
@app.get('/login')
def login_form():
return '<form method="POST">...</form>'
@app.post('/login')
def login_submit():
username = request.form.get('username')
return f'Welcome, {username}!'This approach keeps each function small and focused on one job. Many developers prefer it over the if request.method pattern.
Reading Form Data
POST request data arrives in request.form. GET request parameters arrive in request.args.
@app.route('/search', methods=['GET'])
def search():
keyword = request.args.get('q', '')
return f'Results for: {keyword}'
@app.route('/submit', methods=['POST'])
def submit():
name = request.form.get('name')
email = request.form.get('email')
return f'Received from {name}: {email}'Using PUT and DELETE for APIs
PUT and DELETE are used mainly in REST APIs rather than traditional web pages. Browsers only send GET and POST from HTML forms, so PUT and DELETE requests come from JavaScript (fetch/axios) or API clients like Postman.
@app.route('/user/<int:user_id>', methods=['PUT'])
def update_user(user_id):
data = request.get_json()
return f'Updated user {user_id} with {data}'
@app.route('/user/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
return f'Deleted user {user_id}'Method Not Allowed
If a request uses a method that the route does not accept, Flask automatically returns HTTP 405 with a JSON or HTML error. You see this error often during development when you forget to add 'POST' to a form-handling route.
Route defined: methods=['GET']
Request sent: POST /login
│
Flask returns: 405 Method Not Allowed
Summary
HTTP methods describe the intent of a request. GET fetches data, POST submits data, PUT replaces data, and DELETE removes it. Flask routes accept only GET by default. Add the methods parameter to accept other methods. Use request.method to check which method arrived and respond accordingly. Keep functions focused by using @app.get() and @app.post() decorators when possible.
