Authentication¶
FastHTTP provides built-in authentication classes that work per route via the auth parameter on any decorator.
Available Auth Classes¶
| Class | Use case |
|---|---|
BasicAuth(username, password) |
HTTP Basic — base64-encoded credentials |
DigestAuth(username, password) |
HTTP Digest — challenge-response handshake |
BearerAuth(token) |
Bearer token — OAuth2, JWT, API keys |
All three are imported from fasthttp directly and convert to their httpx equivalents at request time.
BasicAuth¶
Sends Authorization: Basic <base64> on every request to the route:
from fasthttp import FastHTTP, BasicAuth
from fasthttp.response import Response
app = FastHTTP()
@app.get("https://api.example.com/profile", auth=BasicAuth("alice", "s3cr3t"))
async def get_profile(resp: Response) -> dict:
return resp.json()
if __name__ == "__main__":
app.run()
DigestAuth¶
Performs the full HTTP Digest challenge-response handshake automatically:
from fasthttp import FastHTTP, DigestAuth
from fasthttp.response import Response
app = FastHTTP()
@app.get("https://api.example.com/data", auth=DigestAuth("alice", "s3cr3t"))
async def get_data(resp: Response) -> dict:
return resp.json()
if __name__ == "__main__":
app.run()
BearerAuth¶
Sends Authorization: Bearer <token> — use for OAuth2 access tokens, JWTs, and static API tokens:
from fasthttp import FastHTTP, BearerAuth
from fasthttp.response import Response
app = FastHTTP()
@app.get("https://api.example.com/users", auth=BearerAuth("my-jwt-token"))
async def get_users(resp: Response) -> list:
return resp.json()
if __name__ == "__main__":
app.run()
Auth on Routers¶
The auth parameter works on all Router decorators:
from fasthttp import FastHTTP, Router, BearerAuth
from fasthttp.response import Response
TOKEN = "my-service-token"
app = FastHTTP()
payments = Router(base_url="https://payments.example.com", prefix="/v1")
@payments.post("/charge", auth=BearerAuth(TOKEN))
async def charge(resp: Response) -> dict:
return resp.json()
@payments.get("/history", auth=BearerAuth(TOKEN))
async def history(resp: Response) -> list:
return resp.json()
app.include_router(payments)
if __name__ == "__main__":
app.run()
Mixing Auth Types¶
Different routes can use different auth classes:
from fasthttp import FastHTTP, BasicAuth, BearerAuth
from fasthttp.response import Response
app = FastHTTP()
@app.get("https://legacy.example.com/api", auth=BasicAuth("admin", "pass"))
async def legacy(resp: Response) -> dict:
return resp.json()
@app.get("https://modern.example.com/api", auth=BearerAuth("jwt-token"))
async def modern(resp: Response) -> dict:
return resp.json()
if __name__ == "__main__":
app.run()
No Auth¶
Omit auth (default None) to send no authentication headers:
@app.get("https://api.example.com/public")
async def public(resp: Response) -> dict:
return resp.json()
Combining with raise_for_status¶
Auth and raise_for_status can be set together on the same route:
from fasthttp import FastHTTP, BearerAuth
from fasthttp.exceptions import FastHTTPBadStatusError
from fasthttp.response import Response
app = FastHTTP()
@app.get(
"https://api.example.com/secure",
auth=BearerAuth("my-token"),
raise_for_status=True,
)
async def secure(resp: Response) -> dict:
return resp.json()
if __name__ == "__main__":
try:
app.run()
except FastHTTPBadStatusError as e:
print(f"HTTP {e.status_code} on {e.url}")