Skip to main content

Classes and Decorators to use FastAPI with Class based routing

Project description

Class

Classes and Decorators to use FastAPI with Class based routing

Test Package version Supported Python versions


Source Code: https://github.com/yezz123/fastapi-class

Install the project: pip install fastapi-class


This package provides classes and decorators to use FastAPI with class based routing in Python 3.8. This allows you to construct an instance of a class and have methods of that instance be route handlers for FastAPI.

Note: This package does not support async routes with Python versions less than 3.8 due to bugs in inspect.iscoroutinefunction. Specifically, with older versions of Python iscoroutinefunction incorrectly returns false so async routes are not awaited. As a result, this package only supports Python versions >= 3.8.

To get started, install the package using pip:

pip install fastapi-class

Example

let's imagine that this code is part of a system that manages a list of users. The Dao class represents a Data Access Object, which is responsible for storing and retrieving user data from a database.

The UserRoutes class is responsible for defining the routes (i.e., the URL paths) that users can access to perform various actions on the user data.

Here's how the code could be used in a real world scenario:

import argparse

from dao import Dao
from fastapi import FastAPI

from fastapi_class.decorators import delete, get
from fastapi_class.routable import Routable


def parse_arg() -> argparse.Namespace:
    """parse command line arguments."""
    parser = argparse.ArgumentParser(
        description="Example of FastAPI class based routing."
    )
    parser.add_argument("--url", type=str, help="URL to connect to.")
    parser.add_argument("--user", type=str, help="User to connect with.")
    parser.add_argument("--password", type=str, help="Password to connect with.")
    return parser.parse_args()


class UserRoutes(Routable):
    """Inherits from Routable."""

    # Note injection here by simply passing values to the constructor. Other injection frameworks also
    # supported as there's nothing special about this __init__ method.
    def __init__(self, dao: Dao) -> None:
        """Constructor. The Dao is injected here."""
        super().__init__()
        self.__dao = Dao

    @get("/user/{name}")
    def get_user_by_name(self, name: str) -> str:
        # Use our injected DAO instance.
        return self.__dao.get_user_by_name(name)

    @delete("/user/{name}")
    def delete_user(self, name: str) -> None:
        self.__dao.delete(name)


def main():
    args = parse_arg()
    # Configure the DAO per command line arguments
    dao = Dao(args.url, args.user, args.password)
    # Simple intuitive injection
    user_routes = UserRoutes(dao)
    app = FastAPI()
    # router member inherited from cr.Routable and configured per the annotations.
    app.include_router(user_routes.router)

Explanation

FastAPI generally has one define routes like:

from fastapi import FastAPI

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:

from fastapi import FastAPI

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

Development 🚧

Setup environment 📦

You should create a virtual environment and activate it:

python -m venv venv/
source venv/bin/activate

And then install the development dependencies:

# Install dependencies
pip install -e .[test,lint]

Run tests 🌝

You can run all the tests with:

bash scripts/test.sh

Note: You can also generate a coverage report with:

bash scripts/test_html.sh

Format the code 🍂

Execute the following command to apply pre-commit formatting:

bash scripts/format.sh

Execute the following command to apply mypy type checking:

bash scripts/lint.sh

License

This project is licensed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_class-2.0.0.tar.gz (10.5 kB view hashes)

Uploaded Source

Built Distribution

fastapi_class-2.0.0-py3-none-any.whl (8.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page