YouTip LogoYouTip

Flask Request Response

The core of web applications is "receiving requests, returning responses." This chapter provides a comprehensive explanation of how to read request data and construct various types of responses in Flask. All examples can be run and verified directly in the development server. * * * ## Request Objectβ€”β€”request Flask provides all request information through the global proxy object `request`. Although it is a "global" object, Flask internally uses a thread isolation mechanism to ensure that each request gets its own data. ## Instance # Import request, a thread-safe proxy object from flask import Flask, request app = Flask( __name__ ) @app.route("/debug") def debug(): # Output various request information to help understand the request object return f"""

Request Debug Information

  • Method: {request.method}
  • Path: {request.path}
  • Full URL: {request.url}
  • Host: {request.host}
  • Client IP: {request.remote_addr}
  • User-Agent: {request.headers.get('User-Agent')}
""" Visit http://127.0.0.1:5000/debug?foo=bar to see the detailed request information. !(#) * * * ## Getting Query Parametersβ€”β€”request.args Parameters after the ? in the URL are called query parameters (Query String). Use `request.args` to read them; it acts like a dictionary: ## Instance @app.route("/search") def search(): # request.args.get() safely retrieves parameters, returns None when the key does not exist keyword= request.args.get("keyword","")# Get the search keyword page = request.args.get("page","1")# Get the page number, default is 1 return f"""

Search Results

Keyword: {keyword}

Page: {page}

""" # Test: /search?keyword=flask&page=2 # Test: /search?keyword=TUTORIAL > It is recommended to use the .get() method instead of direct subscript access like request.args, because the latter will throw a KeyError when the key does not exist, resulting in a 400 error page. * * * ## Getting Form Dataβ€”β€”request.form To handle form data submitted via POST requests, use `request.form`: ## Instance @app.route("/register", methods=["GET","POST"]) def register(): if request.method=="POST": # Use the value of the field with name="username" in the form username = request.form.get("username","") password = request.form.get("password","") if not username or not password: return"

Error

Username and password cannot be empty

",400 return f"

Registration Successful

Welcome {username} to TUTORIAL!

" # Display registration form for GET request return"""

Register

Username:

Password:

""" > Note: In the HTML page handling the form, the must have method="post" set, otherwise the data will be sent via the URL query string (GET method), and sensitive information will be exposed in the URL. * * * ## Getting JSON Dataβ€”β€”request.json In modern web development, JSON is the most common data format. When the client sends a request with Content-Type: application/json, use `request.json` to get the parsed data: ## Instance @app.post("/api/user") def create_user(): # request.json returns JSON data already parsed into a Python dict data = request.json# For example, client sends {"name": "tutorial", "email": "test@"} # Safely get fields name = data.get("name","Unknown") email= data.get("email","Not provided") # Directly return dict, Flask automatically converts to JSON response return{ "message": "User created successfully", "name": name, "email": email } You can test with curl or Postman: $ curl -X POST http://127.0.0.1:5000/api/user -H "Content-Type: application/json" -d '{"name": "tutorial", "email": "test@"}'{ "message": "User created successfully", "name": "tutorial", "email": "test@"} * * * ## File Upload To handle uploaded files, use `request.files`, combined with `secure_filename()` provided by Werkzeug to ensure the filename is safe: ## Instance import os from werkzeug.utils import secure_filename # Filter dangerous filename characters # Configure upload directory (should be read from config in actual projects) UPLOAD_DIR ="uploads" @app.route("/upload", methods=["GET","POST"]) def upload_file(): if request.method=="POST": # Check if a file was uploaded if"file"not in request.files: return"No file selected",400 file= request.files # User might have submitted an empty form (no file selected) if file.filename=="": return"Filename is empty",400 # secure_filename filters out dangerous characters like path traversal # For example, "../../etc/passwd" will be processed to "etc_passwd" filename = secure_filename(file.filename) # Ensure upload directory exists os.makedirs(UPLOAD_DIR, exist_ok=True) # Save file file.save(os.path.join(UPLOAD_DIR, filename)) return f"File {filename} uploaded successfully" # Display upload form for GET request return"""

Upload File

""" > If the form has a file upload field, the tag must have enctype="multipart/form-data" set, otherwise the file data will not be sent by the browser. * * * ## Complete Guide to Response Types View functions can return multiple types of data, and Flask will automatically convert them into appropriate HTTP responses. Understanding this conversion rule is the key to mastering Flask. ### Returning Strings The returned string serves as the HTML response body, with a default status code of 200 and Content-Type of text/html. ### Returning Dictionaries or Lists (JSON) Automatically calls jsonify() to convert to a JSON response, with Content-Type of application/json. ## Instance @app.get("/api/posts") def get_posts(): # Return dict, Flask automatically converts to JSON return{ "status": "ok", "data": [ {"id": 1,"title": "Flask Beginner Tutorial"}, {"id": 2,"title": "RESTful API Design"}, ] } @app.get("/api/tags") def get_tags(): # Return list, Flask automatically converts to JSON return["Python","Flask","Web Development","TUTORIAL"] ### Returning Tuplesβ€”β€”Controlling Status Codes and Response Headers The tuple format is very practical and comes in three forms: ## Instance # Form 1: (body, status_code) @app.get("/not-found") def not_found(): return"

Page not found

",404 # Form 2: (body, headers_dict) @app.get("/custom-header") def custom_header(): return"OK",{"X-Custom-Header": "tutorial"} # Form 3: (body, status_code, headers_dict) @app.post("/api/login") def api_login(): # Return token and custom status code return{"token": "abc123","user": "tutorial"},201,{"X-RateLimit": "100"} * * * ## Redirection Use the `redirect()` function to direct the user to another URL: ## Instance from flask import Flask, redirect, url_for app = Flask( __name__ ) @app.route("/") def index(): # Redirect to login page when visiting the homepage return redirect(url_for("login")) @app.route("/login") def login(): return"

Please log in first

" @app.route("/old-page") def old_page(): # Old page permanently moved to new page, use 301 status code return redirect(url_for("new_page"),code=301) @app.route("/new-page") def new_page(): return"

This is the new page

" The default redirect status code is 303 See Other, suitable for redirection after form submission (PRG pattern). For permanent migration scenarios, use code=301. * * * ## Aborting Requestsβ€”β€”abort Use `abort()` to immediately terminate the current request and return an HTTP error: ## Instance from flask import abort @app.route("/post/") def view_post(post_id): # Assume article IDs are only 1-100 if post_id 100: # Immediately return 404, subsequent code will not execute abort(404) return f"

Article #{post_id}

" @app.route("/admin") def admin(): # Return 403 for unauthorized access abort(403, description="You do not have permission to access this page") * * * ## make_responseβ€”β€”Manual Response Control When you need to manually set Cookies or customize response headers, use `make_response()`: ## Instance from flask import make_response @app.route("/set-cookie") def set_cookie
← Flask Session CookieJava Collection Algorithms β†’