Skip to content

Instantly share code, notes, and snippets.

@andrewbolster
Created April 21, 2024 16:40
Show Gist options
  • Save andrewbolster/98fa7ffda5845e4be3acb52618ab420b to your computer and use it in GitHub Desktop.
Save andrewbolster/98fa7ffda5845e4be3acb52618ab420b to your computer and use it in GitHub Desktop.
Better Statement Generator
import typing as t
import logging
import random
from fastapi import Depends, FastAPI, Header, HTTPException
from fastapi.security.http import HTTPAuthorizationCredentials, HTTPBearer
from pydantic import BaseModel
from starlette import status
from os import environ
app = FastAPI()
# Placeholder for a database containing valid token values
known_tokens = set(["master-backup-token"])
# We will handle a missing token ourselves
get_bearer_token = HTTPBearer(auto_error=False)
api_key = environ.get("API_KEY", None)
if api_key is None:
logging.warning("API_KEY environment variable is not set")
else:
known_tokens.add(api_key)
logging.info(f"Added API key from environment to known tokens")
# Use the api_key variable in your code as needed
class UnauthorizedMessage(BaseModel):
detail: str = "Bearer token missing or unknown"
async def get_token(
auth: t.Optional[HTTPAuthorizationCredentials] = Depends(get_bearer_token),
) -> str:
# Simulate a database query to find a known token
if auth is None or (token := auth.credentials) not in known_tokens:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=UnauthorizedMessage().detail,
)
return token
app = FastAPI(title="Better Statement Generator",
description="Generate better statements by combining adjectives and nouns.",
version="0.1.0",
docs_url='/',
redoc_url='/redoc',
openapi_url='/openapi.json')
adjectives = ["red", "blue", "green", "small", "big"]
nouns = ["apple", "car", "tree", "dog", "cat"]
@app.get("/generate", response_model=str, responses={status.HTTP_401_UNAUTHORIZED: dict(model=UnauthorizedMessage)},)
def generate_pair(token: str = Depends(get_token)):
adjective = random.choice(adjectives)
noun = random.choice(nouns)
return f"{adjective}-{noun}"
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
fastapi
uvicorn
# not really required for deployment but I'm being lazy
pytest
httpx
import pytest
from fastapi.testclient import TestClient
import os
from main import app
client = TestClient(app)
def test_generate_pair_with_valid_token():
response = client.get("/generate", headers={"Authorization": "Bearer master-backup-token"})
assert response.status_code == 200
assert response.json() is not None
def test_generate_pair_with_invalid_token():
response = client.get("/generate", headers={"Authorization": "Bearer invalid-token"})
assert response.status_code == 401
assert response.json() == {"detail": "Bearer token missing or unknown"}
def test_generate_pair_without_token():
response = client.get("/generate")
assert response.status_code == 401
assert response.json() == {"detail": "Bearer token missing or unknown"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment