The file system-based FastAPI router automatically generates the routing structure from the file system.
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = "fastapi_directory_routing"
copyright = "2023, Ebubekir Karanfil"
author = "Ebubekir Karanfil"
release = "0.0.1"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ["sphinx.ext.autodoc"]

templates_path = ["_templates"]
exclude_patterns = []


# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "alabaster"
html_static_path = ["_static"]

docs/source/conf.py
ebubekir/fastapi-directory-routing
from .core import DirectoryRouter

fastapi_directory_routing/__init__.py
ebubekir/fastapi-directory-routing
from .directory_router import DirectoryRouter

fastapi_directory_routing/core/__init__.py
ebubekir/fastapi-directory-routing
import os
import importlib

from fastapi import APIRouter

METHODS = ["get", "post", "put", "delete"]


class DirectoryRouter(APIRouter):
    """DirectoryRouter class inherit from fastapi.APIRouter.

    This class begins automatic route scanning upon initialization.

    Args:
        base_directory (str, optional): Defines the folder to be subjected to automatic route scanning.
        route_file_name (str, optional): Specifies the file name within the folder where route scanning will be conducted

    Examples:
        >>> from fastapi import FastAPI
        >>> from fastapi_directory_routing import DirectoryRouter
        >>> app = FastAPI()
        >>> easy_router = DirectoryRouter()
        >>> app.include_router(prefix="/easy-routes", router=easy_router)

    Todo:
        * For each route configuration, the __config__ variable will be searched within the files.
        * Error and exception handling scenarios will be enhanced/developed.
    """

    def __init__(
        self,
        base_directory: str = "api",
        route_file_name: str = "route",
        *args,
        **kwargs,
    ):
        self._base_directory = base_directory
        self._route_file_name = route_file_name
        super().__init__(*args, **kwargs)
        self.build_router()

    def build_router(self):
        for root, dirs, files in os.walk(
            os.path.join(os.getcwd(), self.base_directory)
        ):
            if self.route_file_name + ".py" in files:
                # Import route file
                route_file = importlib.import_module(
                    os.path.relpath(root).replace("/", ".") + "." + self.route_file_name
                )

                # Find routes
                find_routes = [r for r in dir(route_file) if r in METHODS]
                if find_routes:
                    if os.path.basename(root) == self.base_directory:
                        tags = ["default"]
                    else:
                        tags = os.path.relpath(root, self.base_directory).split("/")

                    _router = APIRouter(
                        prefix="/" + os.path.relpath(root, self.base_directory),
                        tags=tags,
                    )

                    for r in find_routes:
                        _router.add_api_route("/", getattr(route_file, r), methods=[r])

                    self.include_router(_router)

    @property
    def base_directory(self):
        return self._base_directory

    @base_directory.setter
    def base_directory(self, value):
        self._base_directory = value

    @property
    def route_file_name(self):
        return self._route_file_name

fastapi_directory_routing/core/directory_router.py
ebubekir/fastapi-directory-routing
from setuptools import setup, find_packages
from distutils.util import convert_path


def get_version():
    ver_path = convert_path("fastapi_directory_routing/__version__.py")
    with open(ver_path) as ver_file:
        main_ns = {}
        exec(ver_file.read(), main_ns)
        return main_ns["__version__"]


setup(
    name="fastapi-directory-routing",
    author_email="karanfilebubekir@gmail.com",
    author="Ebubekir Karanfil",
    description="The file system-based FastAPI router automatically generates the routing structure from the file system.",
    long_description=open("README.md").read(),
    long_description_content_type="text/markdown",
    license="MIT",
    version=get_version(),
    packages=find_packages(),
    install_requires=[""],
)

setup.py
ebubekir/fastapi-directory-routing