CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flask

A simple framework for building complex web applications.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

request-response.mddocs/

Request and Response Handling

Flask provides Request and Response classes for handling HTTP data. The Request object contains all incoming HTTP data, while the Response object represents the HTTP response sent back to the client.

Capabilities

Request Object

The Request object contains all data from the incoming HTTP request.

class Request:
    # HTTP method and URL information
    method: str  # HTTP method (GET, POST, etc.)
    url: str  # Complete URL
    base_url: str  # URL without query string
    url_root: str  # Root URL (scheme + host + port)
    path: str  # URL path
    query_string: bytes  # Raw query string
    full_path: str  # Path + query string
    
    # Request data
    args: ImmutableMultiDict  # URL query parameters
    form: ImmutableMultiDict  # Form data from POST/PUT
    files: ImmutableMultiDict  # Uploaded files
    values: ImmutableMultiDict  # Combined args and form data
    json: Any  # Parsed JSON data (if Content-Type is JSON)
    data: bytes  # Raw request body data
    
    # Headers and metadata
    headers: EnvironHeaders  # HTTP headers
    cookies: ImmutableMultiDict  # Request cookies
    content_type: str | None  # Content-Type header
    content_length: int | None  # Content-Length header
    mimetype: str  # Main content type without parameters
    
    # Remote client information
    remote_addr: str | None  # Client IP address
    remote_user: str | None  # Remote user (if authenticated)
    
    # Flask-specific attributes
    endpoint: str | None  # Matched endpoint name
    view_args: dict[str, Any] | None  # URL rule variables
    url_rule: Rule | None  # Matched URL rule
    blueprint: str | None  # Blueprint name
    
    # Environment and context
    environ: dict  # WSGI environment
    shallow: bool  # Whether request was created with shallow=True
    
    def get_json(
        self,
        force: bool = False,
        silent: bool = False,
        cache: bool = True
    ) -> Any:
        """
        Parse request data as JSON.
        
        Args:
            force: Parse even if Content-Type is not JSON
            silent: Return None on parse errors instead of raising
            cache: Cache parsed JSON for subsequent calls
            
        Returns:
            Parsed JSON data or None
            
        Raises:
            BadRequest: If JSON parsing fails and silent=False
        """
    
    def get_data(self, cache: bool = True, as_text: bool = False, parse_form_data: bool = False) -> bytes | str:
        """
        Get raw request body data.
        
        Args:
            cache: Cache data for subsequent calls
            as_text: Return data as text string
            parse_form_data: Parse form data from body
            
        Returns:
            Request body as bytes or string
        """
    
    @property
    def is_json(self) -> bool:
        """Check if request has JSON content type."""
    
    @property
    def is_secure(self) -> bool:
        """Check if request was made over HTTPS."""
    
    @property
    def is_xhr(self) -> bool:
        """Check if request was made via XMLHttpRequest (deprecated)."""

Response Object

The Response object represents the HTTP response sent to the client.

class Response:
    def __init__(
        self,
        response: Any = None,
        status: int | str | None = None,
        headers: dict | list | None = None,
        mimetype: str | None = None,
        content_type: str | None = None,
        direct_passthrough: bool = False
    ):
        """
        Create a Response object.
        
        Args:
            response: Response data (string, bytes, or iterable)
            status: HTTP status code or phrase
            headers: Response headers
            mimetype: Response MIME type
            content_type: Complete Content-Type header
            direct_passthrough: Pass response directly to WSGI server
        """
    
    # Response data and status
    data: bytes  # Response body as bytes
    status: str  # HTTP status line
    status_code: int  # HTTP status code
    
    # Headers
    headers: Headers  # Response headers
    content_type: str | None  # Content-Type header
    content_length: int | None  # Content-Length header
    mimetype: str  # Main content type
    
    # Caching and cookies
    cache_control: ResponseCacheControl  # Cache-Control header
    expires: datetime | None  # Expires header
    last_modified: datetime | None  # Last-Modified header
    etag: str | None  # ETag header
    vary: HeaderSet  # Vary header
    
    def set_cookie(
        self,
        key: str,
        value: str = '',
        max_age: int | None = None,
        expires: datetime | str | None = None,
        path: str | None = '/',
        domain: str | None = None,
        secure: bool = False,
        httponly: bool = False,
        samesite: str | None = None
    ) -> None:
        """
        Set a cookie on the response.
        
        Args:
            key: Cookie name
            value: Cookie value
            max_age: Cookie max age in seconds
            expires: Cookie expiration date
            path: Cookie path
            domain: Cookie domain
            secure: Require HTTPS for cookie
            httponly: Prevent JavaScript access
            samesite: SameSite attribute ('Strict', 'Lax', or 'None')
        """
    
    def delete_cookie(
        self,
        key: str,
        path: str | None = '/',
        domain: str | None = None,
        secure: bool = False,
        httponly: bool = False,
        samesite: str | None = None
    ) -> None:
        """
        Delete a cookie by setting it to expire immediately.
        
        Args:
            key: Cookie name to delete
            path: Cookie path (must match original)
            domain: Cookie domain (must match original)
            secure: Secure flag (must match original)
            httponly: HttpOnly flag (must match original)
            samesite: SameSite flag (must match original)
        """
    
    @property
    def is_json(self) -> bool:
        """Check if response has JSON content type."""
    
    def get_json(self, force: bool = False, silent: bool = False, cache: bool = True) -> Any:
        """
        Parse response data as JSON.
        
        Args:
            force: Parse even if Content-Type is not JSON
            silent: Return None on parse errors
            cache: Cache parsed JSON
            
        Returns:
            Parsed JSON data or None
        """

Response Creation Helpers

Functions for creating different types of responses.

def make_response(*args) -> Response:
    """
    Create a Response object from various inputs.
    
    Args:
        *args: Response data, status, headers in various combinations
        
    Returns:
        Response object
        
    Examples:
        make_response('Hello')
        make_response('Hello', 200)
        make_response('Error', 404, {'Content-Type': 'text/plain'})
        make_response(('Hello', 200, {'X-Custom': 'value'}))
    """

Usage Examples

Accessing Request Data

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/info')
def request_info():
    return {
        'method': request.method,
        'url': request.url,
        'path': request.path,
        'args': dict(request.args),
        'headers': dict(request.headers),
        'remote_addr': request.remote_addr,
        'is_secure': request.is_secure,
        'is_json': request.is_json
    }

@app.route('/query')
def query_params():
    # Get single value
    name = request.args.get('name', 'Unknown')
    
    # Get multiple values for same key
    tags = request.args.getlist('tag')
    
    # Get with type conversion
    page = request.args.get('page', 1, type=int)
    
    return {
        'name': name,
        'tags': tags,
        'page': page
    }

Handling Form Data

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/form', methods=['GET', 'POST'])
def form_handler():
    if request.method == 'GET':
        return render_template('form.html')
    
    # Handle form submission
    username = request.form.get('username')
    email = request.form.get('email')
    
    # Handle checkboxes (multiple values)
    interests = request.form.getlist('interests')
    
    # Validate required fields
    if not username or not email:
        return 'Username and email are required', 400
    
    return f'Hello {username}! Email: {email}, Interests: {interests}'

@app.route('/upload', methods=['POST'])
def file_upload():
    if 'file' not in request.files:
        return 'No file uploaded', 400
    
    file = request.files['file']
    if file.filename == '':
        return 'No file selected', 400
    
    if file:
        # Save file
        filename = secure_filename(file.filename)
        file.save(os.path.join('uploads', filename))
        return f'File {filename} uploaded successfully'

JSON Request Handling

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/user', methods=['POST'])
def create_user():
    # Check if request contains JSON
    if not request.is_json:
        return {'error': 'Content-Type must be application/json'}, 400
    
    # Get JSON data
    data = request.get_json()
    
    # Validate required fields
    required_fields = ['name', 'email']
    for field in required_fields:
        if field not in data:
            return {'error': f'Missing field: {field}'}, 400
    
    # Process user creation
    user = {
        'id': 123,
        'name': data['name'],
        'email': data['email'],
        'created': '2023-01-01T00:00:00Z'
    }
    
    return jsonify(user), 201

@app.route('/api/data', methods=['PUT'])
def update_data():
    try:
        data = request.get_json(force=True)
    except Exception:
        return {'error': 'Invalid JSON'}, 400
    
    return {'message': 'Data updated', 'received': data}

Creating Custom Responses

from flask import Flask, make_response, jsonify, render_template
from datetime import datetime, timedelta

app = Flask(__name__)

@app.route('/custom')
def custom_response():
    # Create response with custom headers
    response = make_response('Custom response content')
    response.headers['X-Custom-Header'] = 'Custom Value'
    response.status_code = 200
    return response

@app.route('/json-custom')
def json_custom():
    data = {'message': 'Hello', 'timestamp': datetime.now().isoformat()}
    response = make_response(jsonify(data))
    response.headers['X-API-Version'] = '1.0'
    return response

@app.route('/template-custom')  
def template_custom():
    html = render_template('page.html', title='Custom Page')
    response = make_response(html)
    response.headers['X-Generated'] = 'Flask'
    return response

@app.route('/download')
def download_file():
    data = 'File content here'
    response = make_response(data)
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers['Content-Disposition'] = 'attachment; filename=data.txt'
    return response

Cookie Handling

from flask import Flask, request, make_response
from datetime import datetime, timedelta

app = Flask(__name__)

@app.route('/set-cookie')
def set_cookie():
    response = make_response('Cookie set!')
    
    # Simple cookie
    response.set_cookie('username', 'john')
    
    # Cookie with expiration
    expires = datetime.now() + timedelta(days=30)
    response.set_cookie('session_id', 'abc123', expires=expires)
    
    # Secure cookie
    response.set_cookie(
        'secure_token',
        'secret_value',
        secure=True,
        httponly=True,
        samesite='Strict'
    )
    
    return response

@app.route('/get-cookie')
def get_cookie():
    username = request.cookies.get('username', 'Guest')
    session_id = request.cookies.get('session_id')
    
    return {
        'username': username,
        'session_id': session_id,
        'all_cookies': dict(request.cookies)
    }

@app.route('/delete-cookie')
def delete_cookie():
    response = make_response('Cookie deleted!')
    response.delete_cookie('username')
    return response

Response Headers and Caching

from flask import Flask, make_response
from datetime import datetime, timedelta

app = Flask(__name__)

@app.route('/cached')
def cached_response():
    response = make_response('This response is cached')
    
    # Set cache headers
    response.cache_control.max_age = 3600  # 1 hour
    response.cache_control.public = True
    
    # Set ETag for conditional requests
    response.set_etag('resource-v1')
    
    # Set Last-Modified
    response.last_modified = datetime.now()
    
    return response

@app.route('/no-cache')
def no_cache_response():
    response = make_response('This response is not cached')
    
    # Prevent caching
    response.cache_control.no_cache = True
    response.cache_control.no_store = True
    response.cache_control.must_revalidate = True
    
    # Set expiration in the past
    response.expires = datetime.now() - timedelta(hours=1)
    
    return response

@app.route('/api/cors')
def cors_response():
    response = make_response({'message': 'CORS enabled'})
    
    # CORS headers
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
    response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    
    return response

Error Responses

from flask import Flask, request, jsonify, make_response

app = Flask(__name__)

@app.route('/api/users/<int:user_id>')
def get_user(user_id):
    # Simulate user lookup
    if user_id <= 0:
        return {'error': 'Invalid user ID'}, 400
    
    if user_id > 1000:
        return {'error': 'User not found'}, 404
    
    return {'id': user_id, 'name': f'User {user_id}'}

@app.errorhandler(400)
def bad_request(error):
    return make_response(
        jsonify({'error': 'Bad Request', 'message': str(error)}),
        400,
        {'Content-Type': 'application/json'}
    )

@app.errorhandler(404)
def not_found(error):
    if request.path.startswith('/api/'):
        # JSON error for API routes
        return jsonify({'error': 'Not Found'}), 404
    else:
        # HTML error for web routes
        return render_template('404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    response = make_response('Internal Server Error', 500)
    response.headers['X-Error-ID'] = 'ERR-12345'
    return response

Install with Tessl CLI

npx tessl i tessl/pypi-flask

docs

blueprints.md

cli.md

configuration.md

context-globals.md

core-application.md

helpers.md

index.md

json-support.md

request-response.md

routing.md

sessions.md

signals.md

templates.md

testing.md

tile.json