X Tutup
Skip to content

fastapi migration

RayBB edited this page Mar 9, 2026 · 2 revisions

FastAPI Migration

Goal: Migrate to FastAPI for better performance, strong typing, data validation, and improved developer ergonomics. We prioritized high-traffic endpoints first and are now migrating the remainder (as of Feb 2026). Later we will migrate html pages.

Workflow

  1. Create: Build the new FastAPI endpoint, ensuring it matches existing functionality.
  2. Stage: Deploy to the testing environment (available at _fast/<endpoint>).
  3. Route (Testing): Update testing NGINX config to point to the new endpoint.
  4. Verify: Test edge cases, comparing testing traffic to production.
  5. Deploy: Merge to master, update olsystem routing, and wait for deployment.
  6. Cleanup: Remove old endpoints, add local redirects (deprecated_urls), and merge.

Migrating an Endpoint

This is a short guide for migrating a remaining web.py endpoint to FastAPI.

1. Understand the Existing Endpoint

  • Find the endpoint in the codebase and read it carefully.
  • Identify all input parameters (path, query, body) and their types.
  • Understand the output format (JSON shape, status codes, error cases).
  • Note any authentication requirements (required login vs. optional user).

2. Implement in FastAPI

  • Place the new endpoint in the appropriate file under openlibrary/fastapi/. Stubs already exist for most areas that need migration.
  • Follow the patterns established in the existing FastAPI files. Key references:
    • Auth: See auth.py for how to require authentication or get an optional current user.
      • public_my_books.py is an example of an option user and yearly_reading_goals.py is an example of a required user.
      • get_current_user() is only needed if you want an infogami User object with special functions attached. Generally you won't need this unless it was already used.
    • Validation: Use Pydantic models for request bodies and response shapes. Declare path/query parameter types explicitly so FastAPI validates them automatically.
    • Business logic: Keep endpoints thin — extract logic into helpers or static methods rather than embedding it in the route handler.
  • Refer to the FastAPI skill and docs and existing endpoints in the codebase for best practices (e.g., Annotated for dependencies and path params).

3. Write a Comparison Test Script

Create a temporary bash script (e.g., test_<endpoint>_compare.sh) to verify the old and new endpoints behave identically:

  • Call the same request against both:
    • web.pylocalhost:8080
    • FastAPIlocalhost:18080
  • Compare response bodies — they should be identical for success cases.
  • Minor differences in status codes or validation error messages are acceptable.
  • Cover the happy path and important edge cases.
#!/usr/bin/env bash
# Temporary comparison script — delete before merging.
ENDPOINT="/api/example.json?param=value"

OLD=$(curl -s "http://localhost:8080${ENDPOINT}")
NEW=$(curl -s "http://localhost:18080${ENDPOINT}")

if [ "$OLD" = "$NEW" ]; then
  echo "✅ Outputs match"
else
  echo "❌ Outputs differ"
  diff <(echo "$OLD" | python3 -m json.tool) <(echo "$NEW" | python3 -m json.tool)
fi

Note: This script is for local comparison only. We will delete it before merging.

4. Deprecate the Old Endpoint

Once the FastAPI endpoint is working, mark the old web.py endpoint as deprecated using the existing pattern:

@deprecated("migrated to fastapi")

Do not delete the old endpoint yet. Removal will happen in a separate PR once we are confident the new endpoint is stable in production.

Clone this wiki locally

X Tutup