CodeSampleX

Exemplo

fastapi 0.141.1: Extract and validate Header, Cookie, and Path parameters with underscore-to-hyphen conversion, multi-value header parsing, catch-all routing, and HTTPBearer authentication

Amostra verificada para pypi fastapi 0.141.1: Extract and validate Header, Cookie, and Path parameters with underscore-to-hyphen conversion, multi-value…

sha256:ccf237ce0f266d463c20e4aecf8533f09462a3412c3a6efd3f6be83e4641bebe

Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu. Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas. MIT-0

Evidência de execução

O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.

Base da evidência
Contrato assinado aprovado
Recibos de verificação
2
Chaves de assinatura que o compilaram
2
Ambiente declarado python linux x64 python python pip

Ambientes das execuções de verificação

Ambiente Contrato Etapas Execução
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-17
python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-18

Caso

HOW
Objetivo
Extract and validate Header, Cookie, and Path parameters with underscore-to-hyphen conversion, multi-value header parsing, catch-all routing, and HTTPBearer authentication
Pacotes
Símbolos
  • fastapi.FastAPI
  • fastapi.Header
  • fastapi.Cookie
  • fastapi.Path
  • fastapi.security.HTTPBearer
  • fastapi.security.HTTPAuthorizationCredentials
  • fastapi.testclient.TestClient
Ambiente
python
Criado
2026-08-17T17:57:04Z

Contrato

  1. Header parameters defined with underscores automatically translate to hyphenated HTTP header lookups unless convert_underscores is explicitly disabled, and multi-value header lists only capture distinct HTTP headers rather than splitting comma-separated values
  2. assert Header(convert_underscores=True) maps snake_case python names to hyphenated headers and rejects literal underscores with 422 Unprocessable Entity
  3. assert Header(convert_underscores=False) matches literal underscore headers and rejects hyphenated headers with 422 Unprocessable Entity
  4. assert Header(default=[]) receives multiple distinct headers as a list and retains single comma-separated headers as a single un-split string element
  5. assert Header(alias=...) matches explicitly aliased HTTP header names
  6. assert Cookie(...) extracts values from request Cookie headers and returns 422 with cookie loc when required cookies are missing
  7. assert Cookie(default=...) populates fallback values when the cookie is omitted
  8. assert Path(gt=0, le=1000) rejects non-integer strings with int_parsing and rejects out-of-bounds values with less_than_equal
  9. assert Path parameter on catch-all {file_path:path} captures arbitrary subpaths including forward slashes
  10. assert HTTPBearer(auto_error=True) returns 401 Unauthorized with WWW-Authenticate Bearer header on missing or non-bearer credentials
  11. assert HTTPBearer(auto_error=False) resolves to None without raising 401 when the Authorization header is omitted

Arquivos

  • NOTES.md
  • csx.json
  • requirements.txt
  • src/__init__.py
  • src/app.py
  • test/__init__.py
  • test/contract.py

Baixar o artefato de código-fonte (tar.gz)

Código-fonte

NOTES.md
# FastAPI Parameter Binding, Underscore Conversion, Multi-Value Headers, and HTTPBearer Security

## Search Results
`search_known_solution` returned existing samples:
- `sha256:d77e10a9943362242c5ea9fad10b53e2bb9a5f7b9cb0be1f55808d5bd36f534e` (*"Manage FastAPI dependency injection lifecycles, request caching with Depends, background task ordering, yield exception handling, and response status/model interaction"*)
- `sha256:fc03836e42df24fc9ebcc02153f8212390e8abec2d04d133be4cc5598abd71d4` (*"Configure FastAPI behind a reverse proxy prefix with root_path and root_path_in_servers without route matching 404s or broken Swagger UI docs"*)
- `sha256:e332c164b1327606b7ddbb7dca07956830a4f2bf723ca9a1926291a42cfb0a88` (*"Bind query parameters to Pydantic models using Annotated and Query without silent multi-value dropping or request body coercion"*)

This project addresses a distinct area: HTTP `Header`, `Cookie`, and `Path` parameter extraction mechanics, automatic hyphenation translation, list parsing across duplicate header entries vs comma-separated strings, catch-all routing, and `HTTPBearer` authentication semantics.

## Pinned Release
- `fastapi` == 0.141.1 (PyPI)
- `starlette` == 1.6.0
- `pydantic` == 2.13.4
- `httpx2` == 2.10.0

## What a Model Would Have Written
1. A model expects that declaring `x_auth_token: str = Header(...)` in Python will extract incoming HTTP headers named `x_auth_token` with an underscore, or assumes that setting `convert_underscores=False` is required only for uncommon headers.
2. A model expects that declaring `tags: list[str] = Header(default=[])` will parse comma-delimited header values (e.g. `X-Tags: a, b`) automatically into separate Python list items `["a", "b"]`.
3. A model expects `HTTPBearer(auto_error=True)` on missing credentials to return `403 Forbidden` rather than `401 Unauthorized` with a `WWW-Authenticate: Bearer` challenge header.

## How the Wrong Version Fails
- Sending literal underscore headers to `Header(convert_underscores=True)` fails **loudly** at runtime with HTTP 422 Unprocessable Entity and error location `["header", "x-auth-token"]`.
- Sending comma-separated strings to `Header()` typed as `list[str]` fails **silently with a green 200 OK** that preserves the single un-split string `["a, b"]` as a 1-element list, causing downstream item lookups and filtering to fail.
- Expecting 403 on missing Bearer auth fails **loudly** with HTTP status assertions expecting 403 when FastAPI returns 401 along with the `WWW-Authenticate: Bearer` header.
csx.json
{"case":{"believed":"Declaring a Header parameter in Python with snake_case matches the exact header name with underscores and splitting comma-separated headers into list types occurs automatically","caseId":"case:sha256:a68c9ca9abb984d457f02bc4dc55be722322745fefbc2d2a1e997bc775179eb8","contract":["Header parameters defined with underscores automatically translate to hyphenated HTTP header lookups unless convert_underscores is explicitly disabled, and multi-value header lists only capture distinct HTTP headers rather than splitting comma-separated values","assert Header(convert_underscores=True) maps snake_case python names to hyphenated headers and rejects literal underscores with 422 Unprocessable Entity","assert Header(convert_underscores=False) matches literal underscore headers and rejects hyphenated headers with 422 Unprocessable Entity","assert Header(default=[]) receives multiple distinct headers as a list and retains single comma-separated headers as a single un-split string element","assert Header(alias=...) matches explicitly aliased HTTP header names","assert Cookie(...) extracts values from request Cookie headers and returns 422 with cookie loc when required cookies are missing","assert Cookie(default=...) populates fallback values when the cookie is omitted","assert Path(gt=0, le=1000) rejects non-integer strings with int_parsing and rejects out-of-bounds values with less_than_equal","assert Path parameter on catch-all {file_path:path} captures arbitrary subpaths including forward slashes","assert HTTPBearer(auto_error=True) returns 401 Unauthorized with WWW-Authenticate Bearer header on missing or non-bearer credentials","assert HTTPBearer(auto_error=False) resolves to None without raising 401 when the Authorization header is omitted"],"goal":"Extract and validate Header, Cookie, and Path parameters with underscore-to-hyphen conversion, multi-value header parsing, catch-all routing, and HTTPBearer authentication","kind":"HOW","packages":["pkg:pypi/fastapi@0.141.1","pkg:pypi/starlette@1.6.0","pkg:pypi/pydantic@2.13.4","pkg:pypi/httpx2@2.10.0"],"schemaVersion":1,"symbols":["fastapi.FastAPI","fastapi.Header","fastapi.Cookie","fastapi.Path","fastapi.security.HTTPBearer","fastapi.security.HTTPAuthorizationCredentials","fastapi.testclient.TestClient"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/fastapi@0.141.1","pkg:pypi/starlette@1.6.0","pkg:pypi/pydantic@2.13.4","pkg:pypi/httpx2@2.10.0"],"schemaVersion":1,"symbols":["fastapi.FastAPI","fastapi.Header","fastapi.Cookie","fastapi.Path","fastapi.security.HTTPBearer","fastapi.security.HTTPAuthorizationCredentials","fastapi.testclient.TestClient"],"verifierAdapter":"python@1"}
requirements.txt
fastapi==0.141.1
starlette==1.6.0
annotated-doc==0.0.5
pydantic==2.13.4
pydantic-core==2.46.4
typing-extensions==4.15.0
typing-inspection==0.4.2
annotated-types==0.8.0
anyio==4.13.0
idna==3.18
httpx2==2.10.0
httpcore2==2.10.0
truststore==0.10.4
httpx==0.28.1
httpcore==1.0.9
h11==0.16.0
certifi==2026.2.25
src/__init__.py
"""Package root for src."""
src/app.py
"""FastAPI application demonstrating Header, Cookie, Path parameters, and HTTPBearer security."""

from typing import Any, Dict, List, Optional
from fastapi import Cookie, Depends, FastAPI, Header, Path
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer

app = FastAPI(title="FastAPI Parameter and Security Behavior")

bearer_strict = HTTPBearer(auto_error=True)
bearer_optional = HTTPBearer(auto_error=False)


@app.get("/headers")
def read_headers(
    x_auth_token: str = Header(),
    custom_api_key: str = Header(convert_underscores=False),
    x_tags: List[str] = Header(default=[]),
    aliased_header: Optional[str] = Header(default=None, alias="X-Custom-Alias"),
) -> Dict[str, Any]:
    """Read various headers to prove underscore conversion, multi-value lists, and aliasing."""
    return {
        "x_auth_token": x_auth_token,
        "custom_api_key": custom_api_key,
        "x_tags": x_tags,
        "aliased_header": aliased_header,
    }


@app.get("/cookies")
def read_cookies(
    session_id: str = Cookie(),
    theme: str = Cookie(default="dark"),
) -> Dict[str, str]:
    """Read required and defaulted cookies."""
    return {
        "session_id": session_id,
        "theme": theme,
    }


@app.get("/items/{item_id}")
def read_item(
    item_id: int = Path(gt=0, le=1000),
) -> Dict[str, int]:
    """Read path parameter with integer parsing and range validation constraints."""
    return {
        "item_id": item_id,
    }


@app.get("/static/{file_path:path}")
def read_static_file(
    file_path: str = Path(),
) -> Dict[str, str]:
    """Read catch-all subpath parameter."""
    return {
        "file_path": file_path,
    }


@app.get("/auth/strict")
def auth_strict_endpoint(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_strict),
) -> Dict[str, str]:
    """Protected endpoint requiring valid Bearer credentials."""
    return {
        "scheme": credentials.scheme,
        "token": credentials.credentials,
    }


@app.get("/auth/optional")
def auth_optional_endpoint(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(bearer_optional),
) -> Dict[str, Any]:
    """Optional endpoint allowing unauthenticated access or Bearer credentials."""
    if credentials is None:
        return {"authenticated": False, "user": "anonymous"}
    return {
        "authenticated": True,
        "scheme": credentials.scheme,
        "token": credentials.credentials,
    }
test/__init__.py
"""Test suite package."""
test/contract.py
"""Contract verification for FastAPI parameter parsing, conversions, and HTTPBearer security."""

import sys
from pathlib import Path

# Add project root to sys.path
sys.path.insert(0, str(Path(__file__).parent.parent))

from fastapi.testclient import TestClient
from src.app import app


def test_header_underscore_conversion_and_loc() -> None:
    client = TestClient(app)

    # 1. Matching hyphenated header for snake_case parameter (default convert_underscores=True)
    res_valid = client.get(
        "/headers",
        headers={
            "x-auth-token": "secret-token-123",
            "custom_api_key": "api-key-456",
        },
    )
    assert res_valid.status_code == 200, f"Expected 200, got {res_valid.status_code}: {res_valid.text}"
    data = res_valid.json()
    assert data["x_auth_token"] == "secret-token-123"
    assert data["custom_api_key"] == "api-key-456"

    # 2. Sending literal underscore header fails when convert_underscores=True
    res_underscore_fail = client.get(
        "/headers",
        headers={
            "x_auth_token": "secret-token-123",
            "custom_api_key": "api-key-456",
        },
    )
    assert res_underscore_fail.status_code == 422, f"Expected 422, got {res_underscore_fail.status_code}"
    err = res_underscore_fail.json()["detail"][0]
    assert err["loc"] == ["header", "x-auth-token"]
    assert err["type"] == "missing"

    # 3. Sending hyphenated header fails when convert_underscores=False
    res_hyphen_fail = client.get(
        "/headers",
        headers={
            "x-auth-token": "secret-token-123",
            "custom-api-key": "api-key-456",
        },
    )
    assert res_hyphen_fail.status_code == 422, f"Expected 422, got {res_hyphen_fail.status_code}"
    err_custom = res_hyphen_fail.json()["detail"][0]
    assert err_custom["loc"] == ["header", "custom_api_key"]
    assert err_custom["type"] == "missing"


def test_multi_value_headers_and_aliasing() -> None:
    client = TestClient(app)

    # Multiple distinct header lines are collected as a list of strings
    res_multi = client.get(
        "/headers",
        headers=[
            ("x-auth-token", "t"),
            ("custom_api_key", "k"),
            ("x-tags", "production"),
            ("x-tags", "primary"),
        ],
    )
    assert res_multi.status_code == 200
    assert res_multi.json()["x_tags"] == ["production", "primary"]

    # Single comma-separated header is NOT auto-split into multiple items
    res_single = client.get(
        "/headers",
        headers={
            "x-auth-token": "t",
            "custom_api_key": "k",
            "x-tags": "production, primary",
        },
    )
    assert res_single.status_code == 200
    assert res_single.json()["x_tags"] == ["production, primary"]

    # Header alias binds case-insensitively
    res_alias = client.get(
        "/headers",
        headers={
            "x-auth-token": "t",
            "custom_api_key": "k",
            "x-custom-alias": "custom-alias-val",
        },
    )
    assert res_alias.status_code == 200
    assert res_alias.json()["aliased_header"] == "custom-alias-val"


def test_cookie_extraction_and_defaults() -> None:
    client = TestClient(app)

    # Session ID extracted and default theme applied
    res_valid = client.get("/cookies", cookies={"session_id": "sess_abc123"})
    assert res_valid.status_code == 200
    assert res_valid.json() == {"session_id": "sess_abc123", "theme": "dark"}

    # Explicit theme cookie overrides default
    res_custom = client.get(
        "/cookies",
        cookies={"session_id": "sess_abc123", "theme": "light"},
    )
    assert res_custom.status_code == 200
    assert res_custom.json() == {"session_id": "sess_abc123", "theme": "light"}

    # Missing required cookie yields 422 with cookie loc
    res_missing = client.get("/cookies")
    assert res_missing.status_code == 422
    err = res_missing.json()["detail"][0]
    assert err["loc"] == ["cookie", "session_id"]
    assert err["type"] == "missing"


def test_path_parameters_validation_and_catchall() -> None:
    client = TestClient(app)

    # Valid integer path parameter within bounds
    res_valid = client.get("/items/500")
    assert res_valid.status_code == 200
    assert res_valid.json() == {"item_id": 500}

    # Non-integer path parameter fails with int_parsing
    res_type_err = client.get("/items/not-a-number")
    assert res_type_err.status_code == 422
    err_type = res_type_err.json()["detail"][0]
    assert err_type["loc"] == ["path", "item_id"]
    assert err_type["type"] == "int_parsing"

    # Out-of-bounds value fails with less_than_equal
    res_bound_err = client.get("/items/1500")
    assert res_bound_err.status_code == 422
    err_bound = res_bound_err.json()["detail"][0]
    assert err_bound["loc"] == ["path", "item_id"]
    assert err_bound["type"] == "less_than_equal"

    # Catch-all path parameter captures slash-separated subpath
    res_path = client.get("/static/assets/css/main.bundle.css")
    assert res_path.status_code == 200
    assert res_path.json() == {"file_path": "assets/css/main.bundle.css"}


def test_http_bearer_security() -> None:
    client = TestClient(app)

    # Strict: Valid bearer token succeeds
    res_strict_ok = client.get(
        "/auth/strict",
        headers={"Authorization": "Bearer jwt-session-token"},
    )
    assert res_strict_ok.status_code == 200
    assert res_strict_ok.json() == {
        "scheme": "Bearer",
        "token": "jwt-session-token",
    }

    # Strict: Missing Authorization header returns 401 with WWW-Authenticate header
    res_strict_missing = client.get("/auth/strict")
    assert res_strict_missing.status_code == 401
    assert res_strict_missing.headers.get("www-authenticate") == "Bearer"
    assert res_strict_missing.json() == {"detail": "Not authenticated"}

    # Strict: Invalid scheme returns 401
    res_strict_basic = client.get(
        "/auth/strict",
        headers={"Authorization": "Basic dXNlcjpwYXNz"},
    )
    assert res_strict_basic.status_code == 401
    assert res_strict_basic.headers.get("www-authenticate") == "Bearer"
    assert res_strict_basic.json() == {"detail": "Not authenticated"}

    # Optional: Missing Authorization header returns 200 with anonymous user
    res_opt_anon = client.get("/auth/optional")
    assert res_opt_anon.status_code == 200
    assert res_opt_anon.json() == {"authenticated": False, "user": "anonymous"}

    # Optional: Valid Bearer token returns 200 with authenticated credentials
    res_opt_auth = client.get(
        "/auth/optional",
        headers={"Authorization": "Bearer opt-token-xyz"},
    )
    assert res_opt_auth.status_code == 200
    assert res_opt_auth.json() == {
        "authenticated": True,
        "scheme": "Bearer",
        "token": "opt-token-xyz",
    }


def main() -> None:
    test_header_underscore_conversion_and_loc()
    test_multi_value_headers_and_aliasing()
    test_cookie_extraction_and_defaults()
    test_path_parameters_validation_and_catchall()
    test_http_bearer_security()
    print("All contract assertions passed successfully.")


if __name__ == "__main__":
    main()

Seeder de origem

csx-seed