Source Code: https://github.com/yezz123/fastapi-class
Install the project: pip install fastapi-class
Classes and Decorators to use FastAPI with class based routing
. In particular this allows you to
construct an instance of a class and have methods of that instance be route handlers for FastAPI & Python 3.8.
- Older Versions of Python:
- Unfortunately this does not work with
async
routes with Python versions less than 3.8 due to bugs ininspect.iscoroutinefunction
. Specifically with older versions of Pythoniscoroutinefunction
incorrectly returns false soasync
routes aren'tawait
'd. We therefore only support Python versions >= 3.8.
- Unfortunately this does not work with
from ping import pong
# Some fictional ping pong class
from fastapi_class import Routable, get, delete
def parse_arg() -> argparse.Namespace:
"""parse command line arguments."""
...
class UserRoutes(Routable):
"""Inherits from Routable."""
# Note injection here by simply passing values to the constructor.
# Other injection frameworks also work.
# supported as there's nothing special about this __init__ method.
def __init__(self, pong: pong) -> None:
"""Constructor. The pong is injected here."""
self.__pong = pong
@get('/user/{name}')
def get_user_by_name(name: str) -> User:
# Use our injected pong instance.
return self.__pong.get_user_by_name(name)
@delete('/user/{name}')
def delete_user(name: str) -> None:
self.__pong.delete(name)
def main():
args = parse_args()
# Configure the pong per command line arguments
pong = pong(args.url, args.user, args.password)
# Simple intuitive injection
user_routes = UserRoutes(pong)
app = FastAPI()
# router member inherited from Routable and configured per the annotations.
app.include_router(user_routes.router)
FastAPI generally has one define routes like:
app = FastAPI()
@app.get('/echo/{x}')
def echo(x: int) -> int:
return x
Note: that app
is a global. Furthermore, FastAPI's suggested way of doing dependency injection is handy for things like pulling values out of header in the HTTP request. However, they don't work well for more standard dependency injection scenarios where we'd like to do something like inject a Data Access Object or database connection. For that, FastAPI suggests their parameterized dependencies which might look something like:
app = FastAPI()
class ValueToInject:
# Value to inject into the function.
def __init__(self, y: int) -> None:
self.y = y
def __call__(self) -> int:
return self.y
to_add = ValueToInject(2)
@app.get('/add/{x}')
def add(x: int, y: Depends(to_add)) -> int:
return x + y
You should create a virtual environment and activate it:
python -m venv venv/
source venv/bin/activate
And then install the development dependencies:
pip install -r requirements.dev.txt
Execute the following command to apply pre-commit
formatting:
make lint
This project is licensed under the terms of the MIT license.