Skip to content

mohamed-em2m/firebase-fastapi-wrapper

Repository files navigation

🔥 firebase-fastapi-wrapper

PyPI version Python Versions CI License: MIT

A lightweight, production-ready adapter that lets you run any FastAPI (or ASGI) application inside Firebase Cloud Functions — with full support for all HTTP methods, CORS, timeouts, and structured error handling.


✨ Features

Feature Details
🔄 Full HTTP forwarding GET, POST, PUT, PATCH, DELETE — all forwarded correctly
🔒 CORS support Built-in cors_origins allow-list
⏱️ Timeout protection Configurable per-request timeout
🐛 Structured errors JSON error responses with unique request_id for tracing
🏷️ Typed Full type annotations + PEP 561 py.typed marker
🐍 Python 3.10 → 3.12 Tested on all active Python versions
🌐 Multi-server Works in Firebase Functions and locally with Uvicorn

🚀 Installation

# pip
pip install firebase-fastapi-wrapper

# uv
uv add firebase-fastapi-wrapper

# Poetry
poetry add firebase-fastapi-wrapper

🧩 Quickstart (Firebase Functions)

# functions/main.py
from fastapi import FastAPI
from firebase_functions import https_fn
from firebase_fastapi_wrapper import FastAPIWrapper

app = FastAPI()

@app.get("/hello")
def hello():
    return {"message": "Hello from FastAPI inside Firebase!"}

@app.get("/users/{user_id}")
def get_user(user_id: str):
    return {"user_id": user_id}

# Wrap once at module level
firebase_handler = FastAPIWrapper(app)

@https_fn.on_request()
def handle_request(req: https_fn.Request) -> https_fn.Response:
    return firebase_handler(req)

requirements.txt (Firebase Functions needs this):

firebase-fastapi-wrapper>=0.2.0

🌐 Local Development (Uvicorn / any server)

You don't need Firebase to develop and test your app. Run it directly with Uvicorn — the same FastAPI app works on any ASGI server:

# local_server.py
import uvicorn
from main import app   # import your FastAPI app

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
pip install uvicorn
python local_server.py
# → http://localhost:8000/hello
# → http://localhost:8000/docs  (Swagger UI)

Tip: Use an environment variable to switch between Firebase and local mode:

import os
if os.getenv("RUNNING_IN_FIREBASE"):
    firebase_handler = FastAPIWrapper(app)
else:
    import uvicorn
    uvicorn.run(app, port=8000)

⚙️ Advanced Configuration

firebase_handler = FastAPIWrapper(
    app,
    # Allow specific origins to make cross-origin requests
    cors_origins=["https://myapp.web.app", "https://example.com"],
    # Request timeout in seconds (default: 30)
    timeout=60,
    # Hide exception details in production (default: True)
    error_include_detail=False,
    # Raise exceptions instead of returning 500 — useful in tests
    raise_on_error=False,
)

CORS with wildcard

firebase_handler = FastAPIWrapper(app, cors_origins=["*"])

🚦 Error Handling

All unhandled exceptions are caught and returned as structured JSON:

{
  "error": "Internal Server Error",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

Set error_include_detail=True during development to also see the exception message:

{
  "error": "Internal Server Error",
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "detail": "division by zero"
}

🧪 Running Tests

# Install dev dependencies
uv sync --extra dev

# Run the full test suite
uv run pytest tests/ -v

# With coverage report
uv run pytest tests/ -v --cov=firebase_fastapi_wrapper --cov-report=term-missing

🤝 Contributing

See CONTRIBUTING.md for setup instructions, commit conventions, and how to open a PR.


📄 License

MIT © Mohamed Emam

About

this is my impelmtion to how use fastapi with firebase functions

Resources

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages