diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..be456a33 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,9 @@ +{ + "name": "fastapi-37", + "image": "mcr.microsoft.com/devcontainers/python:3.12", + "features": { + "ghcr.io/devcontainers/features/node:1": { "version": "latest" } + }, + "postCreateCommand": "pipx install poetry && poetry install", + "forwardPorts": [2222] +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d92d7019..1e86bcbb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -27,13 +27,13 @@ If applicable, add screenshots to help explain your problem. **Environment:** - OS: [e.g. Linux / Windows / macOS] - - FastAPI RESTful, FastAPI, and Pydantic versions [e.g. `0.3.0`], get them with: + - FastAPI Utils, FastAPI, and Pydantic versions [e.g. `0.3.0`], get them with: ```Python -import fastapi_restful +import fastapi_utils import fastapi import pydantic.utils -print(fastapi_restful.__version__) +print(fastapi_utils.__version__) print(fastapi.__version__) print(pydantic.utils.version_info()) ``` diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c18e14ba..68cca19b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 3 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..ac9c0717 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "python.analysis.typeCheckingMode": "strict", + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "cSpell.words": [ + "fastapi" + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 91179ebc..73afb012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Latest changes +* Merge with [fastapi-utils](https://github.com/dmontagu/fastapi-utils) + +## 0.6.0 + * Fix bug where `Request.url_for` is not working as intended [[yuval9313/FastApi-RESTful#90](https://github.com/yuval9313/FastApi-RESTful/issues/90)] * Update multiple dependencies using @dependebot * Fix `repeat_every` is only running once [#142](https://github.com/yuval9313/FastApi-RESTful/pull/142) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 852548af..864830c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,135 +1,135 @@ -First, you might want to see the basic ways to [help and get help](help-fastapi-restful.md){.internal-link target=_blank}. - -## Developing - -Once you've cloned the repository, here are some guidelines to set up your environment: - -### Set up the development environment - -After cloning the repository, you can use `poetry` to create a virtual environment: - -```console -$ make develop -``` - -Behind the scenes, this checks that you have python3 and poetry installed, -then creates a virtual environment and installs the dependencies. At the end, it will print out -the path to the executable in case you want to add it to your IDE. - - -### Activate the environment - -Once the virtual environment is created, you can activate it with: - -```console -$ poetry shell -``` - -To check if this worked, try running: - -```console -$ which python - -some/directory/fastapi-restful-SOMETHING-py3.X/bin/python -``` - -If the output of this command shows the `python` binary in a path containing `fastapi-restful` somewhere in the name -(as above), then it worked! 🎉 - -!!! tip - Every time you install a new package with `pip` under that environment, activate the environment again. - - This makes sure that if you use a terminal program installed by that package (like `mypy`), - you use the one from your local environment and not any other that could be installed globally. - -### Static Code Checks - -This project makes use of `black`, `autoflake8`, and `isort` for formatting, -`flake8` for linting, and `mypy` for static type checking. - - -To auto-format your code, just run: - -```console -$ make format -``` - -It will also auto-sort all your imports, and attempt to remove any unused imports. - -You can run flake8 with: - -```console -$ make lint -``` - -and you can run mypy with: - -```console -$ make mypy -``` - -There are a number of other useful makefile recipes; you can see basic documentation of these by calling plain `make`: - -```console -$ make -``` - - -## Docs - -The documentation uses MkDocs. - -All the documentation is in Markdown format in the directory `./docs`. - -Many of the sections in the User Guide have blocks of code. - -In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs/src/` directory. - -And those Python files are included/injected in the documentation when generating the site. - -### Docs for tests - -Most of the tests actually run against the example source files in the documentation. - -This helps making sure that: - -* The documentation is up to date. -* The documentation examples can be run as is. -* Most of the features are covered by the documentation, ensured by test coverage. - -During local development, there is a script that builds the site and checks for any changes, live-reloading: - -```console -$ bash scripts/docs-live.sh -``` - -It will serve the documentation on `http://0.0.0.0:8008`. - -That way, you can edit the documentation/source files and see the changes live. - -## Tests - -You can run all tests via: - -```console -$ make test -``` - -You can also generate a coverage report with: - -```console -make testcov -``` - -On MacOS, if the tests all pass, the coverage report will be opened directly in a browser; on other operating systems -a link will be printed to the local HTML containing the coverage report. - -### Tests in your editor - -If you want to use the integrated tests in your editor add `./docs/src` to your `PYTHONPATH` variable. - -For example, in VS Code you can create a file `.env` with: - -```env -PYTHONPATH=./docs/src -``` +First, you might want to see the basic ways to [help and get help](help-fastapi-utils.md){.internal-link target=_blank}. + +## Developing + +Once you've cloned the repository, here are some guidelines to set up your environment: + +### Set up the development evironment + +After cloning the repository, you can use `poetry` to create a virtual environment: + +```console +$ make develop +``` + +Behind the scenes, this checks that you have python3 and poetry installed, +then creates a virtual environment and installs the dependencies. At the end, it will print out +the path to the executable in case you want to add it to your IDE. + + +### Activate the environment + +Once the virtual environment is created, you can activate it with: + +```console +$ poetry shell +``` + +To check if this worked, try running: + +```console +$ which python + +some/directory/fastapi-utils-SOMETHING-py3.X/bin/python +``` + +If the output of this command shows the `python` binary in a path containing `fastapi-utils` somewhere in the name +(as above), then it worked! 🎉 + +!!! tip + Every time you install a new package with `pip` under that environment, activate the environment again. + + This makes sure that if you use a terminal program installed by that package (like `mypy`), + you use the one from your local environment and not any other that could be installed globally. + +### Static Code Checks + +This project makes use of `black`, `autoflake8`, and `isort` for formatting, +`flake8` for linting, and `mypy` for static type checking. + + +To auto-format your code, just run: + +```console +$ make format +``` + +It will also auto-sort all your imports, and attempt to remove any unused imports. + +You can run flake8 with: + +```console +$ make lint +``` + +and you can run mypy with: + +```console +$ make mypy +``` + +There are a number of other useful makefile recipes; you can see basic documentation of these by calling plain `make`: + +```console +$ make +``` + + +## Docs + +The documentation uses MkDocs. + +All the documentation is in Markdown format in the directory `./docs`. + +Many of the sections in the User Guide have blocks of code. + +In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs/src/` directory. + +And those Python files are included/injected in the documentation when generating the site. + +### Docs for tests + +Most of the tests actually run against the example source files in the documentation. + +This helps making sure that: + +* The documentation is up to date. +* The documentation examples can be run as is. +* Most of the features are covered by the documentation, ensured by test coverage. + +During local development, there is a script that builds the site and checks for any changes, live-reloading: + +```console +$ bash scripts/docs-live.sh +``` + +It will serve the documentation on `http://0.0.0.0:8008`. + +That way, you can edit the documentation/source files and see the changes live. + +## Tests + +You can run all tests via: + +```console +$ make test +``` + +You can also generate a coverage report with: + +```console +make testcov +``` + +On MacOS, if the tests all pass, the coverage report will be opened directly in a browser; on other operating systems +a link will be printed to the local HTML containing the coverage report. + +### Tests in your editor + +If you want to use the integrated tests in your editor add `./docs/src` to your `PYTHONPATH` variable. + +For example, in VS Code you can create a file `.env` with: + +```env +PYTHONPATH=./docs/src +``` diff --git a/LICENSE b/LICENSE index a48c2cb1..21f35ccb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020 Yuval Levi +Copyright (c) 2024 David Montague, Yuval Levi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 6a9c7eb4..e102625a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SHELL := /bin/bash .DEFAULT_GOAL := help -pkg_src = fastapi_restful +pkg_src = fastapi_utils tests_src = tests docs_src = docs/src all_src = $(pkg_src) $(tests_src) @@ -103,6 +103,7 @@ docs-build: cp ./README.md ./docs/index.md cp ./CONTRIBUTING.md ./docs/contributing.md cp ./CHANGELOG.md ./docs/release-notes.md + pip install mkdocs mkdocs-material markdown-include python -m mkdocs build .PHONY: docs-format ## Format the python code that is part of the docs diff --git a/README.md b/README.md index 35b21013..aad30b3f 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,27 @@ Quicker FastApi developing tools

- - - Build CI + + + Build CI - - Netlify status + + Coverage
- - Package version + + Package version - - Python versions - License + + Python versions + License

--- +**Documentation**: https://fastapi-utils.davidmontague.xyz -**Documentation**: https://fastapi-restful.netlify.app - -**Source Code**: https://github.com/yuval9313/fastapi-restful - -Base on: https://github.com/dmontagu/fastapi-utils +**Source Code**: https://github.com/dmontagu/fastapi-utils --- @@ -56,7 +53,7 @@ It also adds a variety of more basic utilities that are useful across a wide var * **CamelCase Conversions**: Convenience functions for converting strings from `snake_case` to `camelCase` or `PascalCase` and back * **GUID Type**: The provided GUID type makes it easy to use UUIDs as the primary keys for your database tables -See the [docs](https://fastapi-restful.netlify.app/) for more details and examples. +See the [docs](https://https://fastapi-utils.davidmontague.xyz/) for more details and examples. ## Requirements diff --git a/docs/help-fastapi-restful.md b/docs/help-fastapi-restful.md index 13731958..36478946 100644 --- a/docs/help-fastapi-restful.md +++ b/docs/help-fastapi-restful.md @@ -1,4 +1,4 @@ -Are you looking for help with `fastapi` or `fastapi_restful`? +Are you looking for help with `fastapi` or `fastapi_utils`? ## Help or Get Help with *FastAPI* @@ -9,16 +9,16 @@ See more details about how to help FastAPI at https://fastapi.tiangolo.com/help-fastapi/ -## Star `fastapi-restful` on GitHub +## Star `fastapi-utils` on GitHub -You can "star" `fastapi-restful` in [GitHub](https://github.com/yuval9313/FastApi-RESTful) (clicking the star button at the top right) +You can "star" `fastapi-utils` in [GitHub](https://github.com/dmontagu/fastapi-utils) (clicking the star button at the top right) Adding a star will help other users find this project more easily, and see that it has been useful for others. ## Connect with the author -You can connect with this fork maintainer on +You can connect with the maintainer on [**GitHub** (`Yuval9313`)](https://github.com/yuval9313). * Follow me on [**GitHub**](https://github.com/yuval9313). @@ -31,7 +31,7 @@ You can connect with this fork maintainer on ## Create issues -You can create a new issue in the GitHub repository, for example to: +You can create a new issue in the GitHub repository, for example to: * Report a bug/issue. * Suggest a new feature. @@ -40,7 +40,7 @@ You can create a Pull Request, for example: +You can create a Pull Request, for example: * To fix a typo you found in the documentation. * To propose improvements to documentation. diff --git a/docs/src/api_model.py b/docs/src/api_model.py index 0d7ed6b0..1d6bc46a 100644 --- a/docs/src/api_model.py +++ b/docs/src/api_model.py @@ -4,7 +4,7 @@ from fastapi import FastAPI -from fastapi_restful.api_model import APIModel +from fastapi_utils.api_model import APIModel UserID = NewType("UserID", UUID) diff --git a/docs/src/api_settings.py b/docs/src/api_settings.py index e3283a3d..9ad0c5d0 100644 --- a/docs/src/api_settings.py +++ b/docs/src/api_settings.py @@ -1,6 +1,6 @@ from fastapi import FastAPI -from fastapi_restful.api_settings import get_api_settings +from fastapi_utils.api_settings import get_api_settings def get_app() -> FastAPI: diff --git a/docs/src/camelcase1.py b/docs/src/camelcase1.py index 37962f21..80c669f3 100644 --- a/docs/src/camelcase1.py +++ b/docs/src/camelcase1.py @@ -1,4 +1,4 @@ -from fastapi_restful.camelcase import camel2snake, snake2camel +from fastapi_utils.camelcase import camel2snake, snake2camel assert snake2camel("some_field_name", start_lower=False) == "SomeFieldName" assert snake2camel("some_field_name", start_lower=True) == "someFieldName" diff --git a/docs/src/camelcase2.py b/docs/src/camelcase2.py index b6bb4a7f..3bb7b6f6 100644 --- a/docs/src/camelcase2.py +++ b/docs/src/camelcase2.py @@ -1,6 +1,6 @@ from sqlalchemy.orm import declarative_base, declared_attr -from fastapi_restful.camelcase import camel2snake +from fastapi_utils.camelcase import camel2snake class CustomBase: diff --git a/docs/src/class_based_views1.py b/docs/src/class_based_views1.py index 72d208f3..c27f364f 100644 --- a/docs/src/class_based_views1.py +++ b/docs/src/class_based_views1.py @@ -3,12 +3,11 @@ import sqlalchemy as sa from fastapi import Depends, FastAPI, Header, HTTPException -from sqlalchemy.orm import declarative_base -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session, declarative_base from starlette.status import HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND -from fastapi_restful.api_model import APIMessage, APIModel -from fastapi_restful.guid_type import GUID +from fastapi_utils.api_model import APIMessage, APIModel +from fastapi_utils.guid_type import GUID # Begin setup UserID = NewType("UserID", UUID) diff --git a/docs/src/class_based_views2.py b/docs/src/class_based_views2.py index cbcfd3a1..57885ca3 100644 --- a/docs/src/class_based_views2.py +++ b/docs/src/class_based_views2.py @@ -6,9 +6,9 @@ from sqlalchemy.orm import Session, declarative_base from starlette.status import HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND -from fastapi_restful.api_model import APIMessage, APIModel -from fastapi_restful.cbv import cbv -from fastapi_restful.guid_type import GUID +from fastapi_utils.api_model import APIMessage, APIModel +from fastapi_utils.cbv import cbv +from fastapi_utils.guid_type import GUID # Begin Setup UserID = NewType("UserID", UUID) diff --git a/docs/src/class_resource_view1.py b/docs/src/class_resource_view1.py index 195cbc7c..fddc5532 100644 --- a/docs/src/class_resource_view1.py +++ b/docs/src/class_resource_view1.py @@ -1,4 +1,4 @@ -from fastapi_restful import Resource +from fastapi_utils import Resource class MyApi(Resource): diff --git a/docs/src/class_resource_view2.py b/docs/src/class_resource_view2.py index d7992a09..3451ea92 100644 --- a/docs/src/class_resource_view2.py +++ b/docs/src/class_resource_view2.py @@ -1,7 +1,7 @@ from fastapi import FastAPI from docs.src.class_resource_view1 import MyApi -from fastapi_restful import Api +from fastapi_utils import Api def create_app(): diff --git a/docs/src/class_resource_view3.py b/docs/src/class_resource_view3.py index 28c95ad1..849d9a90 100644 --- a/docs/src/class_resource_view3.py +++ b/docs/src/class_resource_view3.py @@ -2,7 +2,7 @@ from pymongo import MongoClient from docs.src.class_resource_view1 import MyApi -from fastapi_restful import Api +from fastapi_utils import Api def create_app(): diff --git a/docs/src/class_resource_view4.py b/docs/src/class_resource_view4.py index 2f375700..23df1bb8 100644 --- a/docs/src/class_resource_view4.py +++ b/docs/src/class_resource_view4.py @@ -1,6 +1,6 @@ from pydantic import BaseModel -from fastapi_restful import Resource, set_responses +from fastapi_utils import Resource, set_responses # Setup diff --git a/docs/src/enums1.py b/docs/src/enums1.py index de184da4..54e5d845 100644 --- a/docs/src/enums1.py +++ b/docs/src/enums1.py @@ -1,6 +1,6 @@ from enum import auto -from fastapi_restful.enums import StrEnum +from fastapi_utils.enums import StrEnum class MyEnum(StrEnum): diff --git a/docs/src/enums2.py b/docs/src/enums2.py index 4f9124ca..18d3f8cb 100644 --- a/docs/src/enums2.py +++ b/docs/src/enums2.py @@ -1,6 +1,6 @@ from enum import auto -from fastapi_restful.enums import CamelStrEnum +from fastapi_utils.enums import CamelStrEnum class MyEnum(CamelStrEnum): diff --git a/docs/src/guid1.py b/docs/src/guid1.py index a6f782d0..a3e1db68 100644 --- a/docs/src/guid1.py +++ b/docs/src/guid1.py @@ -1,7 +1,7 @@ import sqlalchemy as sa from sqlalchemy.orm import declarative_base -from fastapi_restful.guid_type import GUID +from fastapi_utils.guid_type import GUID Base = declarative_base() diff --git a/docs/src/guid2.py b/docs/src/guid2.py index e2605cdb..1d2811cf 100644 --- a/docs/src/guid2.py +++ b/docs/src/guid2.py @@ -1,6 +1,6 @@ import sqlalchemy as sa -from fastapi_restful.guid_type import setup_guids_postgresql +from fastapi_utils.guid_type import setup_guids_postgresql database_uri = "postgresql://user:password@db:5432/app" engine = sa.create_engine(database_uri) diff --git a/docs/src/openapi2.py b/docs/src/openapi2.py index e40f045c..c91cc042 100644 --- a/docs/src/openapi2.py +++ b/docs/src/openapi2.py @@ -1,6 +1,6 @@ from fastapi import FastAPI -from fastapi_restful.openapi import simplify_operation_ids +from fastapi_utils.openapi import simplify_operation_ids app = FastAPI() diff --git a/docs/src/repeated_tasks1.py b/docs/src/repeated_tasks1.py index 97754757..7fc4e0ea 100644 --- a/docs/src/repeated_tasks1.py +++ b/docs/src/repeated_tasks1.py @@ -1,8 +1,8 @@ from fastapi import FastAPI from sqlalchemy.orm import Session -from fastapi_restful.session import FastAPISessionMaker -from fastapi_restful.tasks import repeat_every +from fastapi_utils.session import FastAPISessionMaker +from fastapi_utils.tasks import repeat_every database_uri = f"sqlite:///./test.db?check_same_thread=False" sessionmaker = FastAPISessionMaker(database_uri) diff --git a/docs/src/session1.py b/docs/src/session1.py index 34cbeac6..38672ff5 100644 --- a/docs/src/session1.py +++ b/docs/src/session1.py @@ -7,8 +7,8 @@ from pydantic import BaseSettings from sqlalchemy.orm import Session, declarative_base -from fastapi_restful.guid_type import GUID, GUID_DEFAULT_SQLITE -from fastapi_restful.session import FastAPISessionMaker +from fastapi_utils.guid_type import GUID, GUID_DEFAULT_SQLITE +from fastapi_utils.session import FastAPISessionMaker Base = declarative_base() diff --git a/docs/src/timing1.py b/docs/src/timing1.py index 734100f9..2c3e9653 100644 --- a/docs/src/timing1.py +++ b/docs/src/timing1.py @@ -6,7 +6,7 @@ from starlette.staticfiles import StaticFiles from starlette.testclient import TestClient -from fastapi_restful.timing import add_timing_middleware, record_timing +from fastapi_utils.timing import add_timing_middleware, record_timing logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) diff --git a/docs/user-guide/basics/api-model.md b/docs/user-guide/basics/api-model.md index 5a047d77..3bbc7f1b 100644 --- a/docs/user-guide/basics/api-model.md +++ b/docs/user-guide/basics/api-model.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.api_model`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/api_model.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.api_model`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/api_model.py){.internal-link target=_blank} --- @@ -12,7 +12,7 @@ but accept `camelCase` attributes from external requests. Another `BaseModel` config setting commonly used with FastAPI is `orm_mode`, which allows your models to be read directly from ORM objects (such as those used by SQLAlchemy). -You can use `fastapi_restful.api_model.APIModel` to easily enable all of these frequently desirable settings. +You can use `fastapi_utils.api_model.APIModel` to easily enable all of these frequently desirable settings. ## Create a model diff --git a/docs/user-guide/basics/api-settings.md b/docs/user-guide/basics/api-settings.md index 0b21bcaa..5d7e4215 100644 --- a/docs/user-guide/basics/api-settings.md +++ b/docs/user-guide/basics/api-settings.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.api_settings`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/api_settings.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.api_settings`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/api_settings.py){.internal-link target=_blank} --- @@ -13,7 +13,7 @@ instance to ensure maximum performance if you want to access the settings in end functions. Even if you care about different settings in your own application, you can follow -the patterns in `fastapi_restful.api_settings` to efficiently access environment-determined +the patterns in `fastapi_utils.api_settings` to efficiently access environment-determined application configuration settings. ### Settings provided by `APISettings`: diff --git a/docs/user-guide/basics/camelcase.md b/docs/user-guide/basics/camelcase.md index 5ea4981b..ba77b11f 100644 --- a/docs/user-guide/basics/camelcase.md +++ b/docs/user-guide/basics/camelcase.md @@ -1,8 +1,8 @@ -#### Source module: [`fastapi_restful.camelcase`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/camelcase.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.camelcase`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/camelcase.py){.internal-link target=_blank} --- -The `fastapi_restful.camelcase` module contains functions for converting `camelCase` or `CamelCase` +The `fastapi_utils.camelcase` module contains functions for converting `camelCase` or `CamelCase` strings to `snake_case`, and vice versa: ```python hl_lines="" diff --git a/docs/user-guide/basics/enums.md b/docs/user-guide/basics/enums.md index 2b546912..36b3306b 100644 --- a/docs/user-guide/basics/enums.md +++ b/docs/user-guide/basics/enums.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.enums`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/enums.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.enums`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/enums.py){.internal-link target=_blank} --- @@ -44,13 +44,13 @@ and the official python docs include a detailed section about [how to do this](https://docs.python.org/3/library/enum.html#using-automatic-values). Rather than repeating this definition in each new project, to reduce boilerplate -you can just inherit from `fastapi_restful.enums.StrEnum` directly to get this behavior: +you can just inherit from `fastapi_utils.enums.StrEnum` directly to get this behavior: ```python hl_lines="3 6" {!./src/enums1.py!} ``` -You can also use `fastapi_restful.enums.CamelStrEnum` to get camelCase values: +You can also use `fastapi_utils.enums.CamelStrEnum` to get camelCase values: ```python hl_lines="3 6" {!./src/enums2.py!} diff --git a/docs/user-guide/basics/guid-type.md b/docs/user-guide/basics/guid-type.md index 13154ddf..03873728 100644 --- a/docs/user-guide/basics/guid-type.md +++ b/docs/user-guide/basics/guid-type.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.guid_type`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/guid_type.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.guid_type`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/guid_type.py){.internal-link target=_blank} --- @@ -50,13 +50,13 @@ You can create a sqlalchemy table with a GUID as a primary key using the declara ## Server Default If you want to add a server default, it will no longer be backend-agnostic, but -you can use `fastapi_restful.guid_type.GUID_SERVER_DEFAULT_POSTGRESQL`: +you can use `fastapi_utils.guid_type.GUID_SERVER_DEFAULT_POSTGRESQL`: ```python import sqlalchemy as sa from sqlalchemy.orm import declarative_base -from fastapi_restful.guid_type import GUID, GUID_SERVER_DEFAULT_POSTGRESQL +from fastapi_utils.guid_type import GUID, GUID_SERVER_DEFAULT_POSTGRESQL Base = declarative_base() @@ -75,7 +75,7 @@ class User(Base): Note this will only work if you have installed the `pgcrypto` extension in your postgres instance. If the user you connect with has the right privileges, this can be done -by calling the `fastapi_restful.guid_type.setup_guids_postgresql` function: +by calling the `fastapi_utils.guid_type.setup_guids_postgresql` function: ```python {!./src/guid2.py!} @@ -91,7 +91,7 @@ create new records): import sqlalchemy as sa from sqlalchemy.orm import declarative_base -from fastapi_restful.guid_type import GUID, GUID_DEFAULT_SQLITE +from fastapi_utils.guid_type import GUID, GUID_DEFAULT_SQLITE Base = declarative_base() diff --git a/docs/user-guide/class-based-views.md b/docs/user-guide/class-based-views.md index f2bd76b2..c35c918d 100644 --- a/docs/user-guide/class-based-views.md +++ b/docs/user-guide/class-based-views.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.cbv`](https://github.com/yuval9313/FastApi-RESTful/blob/master/fastapi_restful/cbv.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.cbv`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/cbv.py){.internal-link target=_blank} --- @@ -9,7 +9,7 @@ A common question people have as they become more comfortable with FastAPI is how they can reduce the number of times they have to copy/paste the same dependency into related routes. -`fastapi_restful` provides a "class-based view" decorator (`@cbv`) to help reduce the amount of boilerplate +`fastapi_utils` provides a "class-based view" decorator (`@cbv`) to help reduce the amount of boilerplate necessary when developing related routes. ## A basic CRUD app @@ -27,7 +27,7 @@ and `get_jwt_user` repeated in each endpoint. ## The `@cbv` decorator -By using the `fastapi_restful.cbv.cbv` decorator, we can consolidate the +By using the `fastapi_utils.cbv.cbv` decorator, we can consolidate the endpoint signatures and reduce the number of repeated dependencies. To use the `@cbv` decorator, you need to: diff --git a/docs/user-guide/class-resource.md b/docs/user-guide/class-resource.md index 85dd2490..f3dbaea0 100644 --- a/docs/user-guide/class-resource.md +++ b/docs/user-guide/class-resource.md @@ -1,4 +1,4 @@ -Source module: [`fastapi_restful.cbv_base`](https://github.com/yuval9313/FastApi-RESTful/blob/master/fastapi_restful/cbv_base.py){.internal-link target=_blank} +Source module: [`fastapi_utils.cbv_base`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/cbv_base.py){.internal-link target=_blank} --- diff --git a/docs/user-guide/openapi.md b/docs/user-guide/openapi.md index d95b8766..0ffdfda9 100644 --- a/docs/user-guide/openapi.md +++ b/docs/user-guide/openapi.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.openapi`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/openapi.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.openapi`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/openapi.py){.internal-link target=_blank} --- @@ -26,7 +26,7 @@ This is a good default behavior because it ensures that distinct endpoints on yo will have distinct `operationId`s. However, it also means that an auto-generated client will have extremely verbose function names like `getResourceApiV1ResourceResourceIdGet`. -To simplify your operation IDs, you can use `fastapi_restful.openapi.simplify_operation_ids` to replace +To simplify your operation IDs, you can use `fastapi_utils.openapi.simplify_operation_ids` to replace the generated operation IDs with ones generated using *only* the function name: ```python hl_lines="3 13 17" diff --git a/docs/user-guide/repeated-tasks.md b/docs/user-guide/repeated-tasks.md index c3738f4b..3d8bd733 100644 --- a/docs/user-guide/repeated-tasks.md +++ b/docs/user-guide/repeated-tasks.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.tasks`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/tasks.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.tasks`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/tasks.py){.internal-link target=_blank} --- @@ -15,7 +15,7 @@ challenges to overcome: 2. If the repeated tasks performs blocking IO, it shouldn't block the event loop 3. Exceptions raised by the periodic task shouldn't just be silently swallowed -The `fastapi_restful.tasks.repeat_every` decorator handles all of these issues and adds some other conveniences as well. +The `fastapi_utils.tasks.repeat_every` decorator handles all of these issues and adds some other conveniences as well. ## The `@repeat_every` decorator diff --git a/docs/user-guide/session.md b/docs/user-guide/session.md index 5c6690b0..f00b93b1 100644 --- a/docs/user-guide/session.md +++ b/docs/user-guide/session.md @@ -1,4 +1,4 @@ -#### Source module: [`fastapi_restful.sessions`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/session.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.sessions`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/session.py){.internal-link target=_blank} !!! Note #### To use please install with: `pip install fastapi-restful[session]` or `pip install fastapi-restful[all]` @@ -13,13 +13,13 @@ ORM into your application. However, the recommended approach for using SQLAlchemy's ORM with FastAPI has evolved over time to reflect both insights from the community and the addition of new features to FastAPI. -The `fastapi_restful.session` module contains an implementation making use of the most up-to-date best practices for +The `fastapi_utils.session` module contains an implementation making use of the most up-to-date best practices for managing SQLAlchemy sessions with FastAPI. --- ## `FastAPISessionMaker` -The `fastapi_restful.session.FastAPISessionMaker` class conveniently wraps session-making functionality for use with +The `fastapi_utils.session.FastAPISessionMaker` class conveniently wraps session-making functionality for use with FastAPI. This section contains an example showing how to use this class. Let's begin with some infrastructure. The first thing we'll do is make sure we have an ORM diff --git a/docs/user-guide/timing-middleware.md b/docs/user-guide/timing-middleware.md index 4af3676b..830758c6 100644 --- a/docs/user-guide/timing-middleware.md +++ b/docs/user-guide/timing-middleware.md @@ -1,8 +1,8 @@ -#### Source module: [`fastapi_restful.timing`](https://github.com/yuval9313/fastapi-restful/blob/master/fastapi_restful/timing.py){.internal-link target=_blank} +#### Source module: [`fastapi_utils.timing`](https://github.com/dmontagu/fastapi-utils/blob/master/fastapi_utils/timing.py){.internal-link target=_blank} --- -The `fastapi_restful.timing` module provides basic profiling functionality that could be +The `fastapi_utils.timing` module provides basic profiling functionality that could be used to find performance bottlenecks, monitor for regressions, etc. There are currently two public functions provided by this module: diff --git a/fastapi_restful/__init__.py b/fastapi_utils/__init__.py similarity index 100% rename from fastapi_restful/__init__.py rename to fastapi_utils/__init__.py diff --git a/fastapi_restful/api_model.py b/fastapi_utils/api_model.py similarity index 100% rename from fastapi_restful/api_model.py rename to fastapi_utils/api_model.py diff --git a/fastapi_restful/api_settings.py b/fastapi_utils/api_settings.py similarity index 100% rename from fastapi_restful/api_settings.py rename to fastapi_utils/api_settings.py diff --git a/fastapi_restful/camelcase.py b/fastapi_utils/camelcase.py similarity index 100% rename from fastapi_restful/camelcase.py rename to fastapi_utils/camelcase.py diff --git a/fastapi_restful/cbv.py b/fastapi_utils/cbv.py similarity index 100% rename from fastapi_restful/cbv.py rename to fastapi_utils/cbv.py diff --git a/fastapi_restful/cbv_base.py b/fastapi_utils/cbv_base.py similarity index 100% rename from fastapi_restful/cbv_base.py rename to fastapi_utils/cbv_base.py diff --git a/fastapi_restful/enums.py b/fastapi_utils/enums.py similarity index 100% rename from fastapi_restful/enums.py rename to fastapi_utils/enums.py diff --git a/fastapi_restful/guid_type.py b/fastapi_utils/guid_type.py similarity index 100% rename from fastapi_restful/guid_type.py rename to fastapi_utils/guid_type.py diff --git a/fastapi_restful/inferring_router.py b/fastapi_utils/inferring_router.py similarity index 100% rename from fastapi_restful/inferring_router.py rename to fastapi_utils/inferring_router.py diff --git a/fastapi_restful/openapi.py b/fastapi_utils/openapi.py similarity index 100% rename from fastapi_restful/openapi.py rename to fastapi_utils/openapi.py diff --git a/fastapi_restful/py.typed b/fastapi_utils/py.typed similarity index 100% rename from fastapi_restful/py.typed rename to fastapi_utils/py.typed diff --git a/fastapi_restful/session.py b/fastapi_utils/session.py similarity index 100% rename from fastapi_restful/session.py rename to fastapi_utils/session.py diff --git a/fastapi_restful/tasks.py b/fastapi_utils/tasks.py similarity index 100% rename from fastapi_restful/tasks.py rename to fastapi_utils/tasks.py diff --git a/fastapi_restful/timing.py b/fastapi_utils/timing.py similarity index 97% rename from fastapi_restful/timing.py rename to fastapi_utils/timing.py index 64458e8d..8d1fe9e0 100644 --- a/fastapi_restful/timing.py +++ b/fastapi_utils/timing.py @@ -7,6 +7,7 @@ For more detailed performance investigations (during development only, due to added overhead), consider using the coroutine-aware profiling library `yappi`. """ + from __future__ import annotations import os @@ -22,7 +23,7 @@ from starlette.routing import Match, Mount from starlette.types import Scope -TIMER_ATTRIBUTE = "__fastapi_restful_timer__" +TIMER_ATTRIBUTE = "__fastapi_utils_timer__" def add_timing_middleware( @@ -59,7 +60,7 @@ def record_timing(request: Request, note: str | None = None) -> None: This can help profile which piece of a request is causing a performance bottleneck. Note that for this function to succeed, the request should have been generated by a FastAPI app - that has had timing middleware added using the `fastapi_restful.timing.add_timing_middleware` function. + that has had timing middleware added using the `fastapi_utils.timing.add_timing_middleware` function. """ timer = getattr(request.state, TIMER_ATTRIBUTE, None) if timer is not None: diff --git a/mkdocs.yml b/mkdocs.yml index 539cd64e..49980884 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,6 @@ -site_name: FastAPI RESTful -site_description: FastAPI RESTful -site_url: https://fastapi-restful.netlify.app/ +site_name: FastAPI Utilities +site_description: FastAPI utilities +site_url: https://fastapi-utils.davidmontague.xyz/ theme: name: 'material' @@ -10,11 +10,11 @@ theme: logo: 'img/icon-white.svg' favicon: 'img/favicon.png' -repo_name: yuval9313/FastApi-RESTful -repo_url: https://github.com/yuval9313/fastapi-restful +repo_name: dmontagu/fastapi-utils +repo_url: https://github.com/dmontagu/fastapi-utils nav: - - FastAPI RESTful: 'index.md' + - FastAPI Utilities: 'index.md' - User Guide: - Class Resource: 'user-guide/class-resource.md' - Class Based Views: 'user-guide/class-based-views.md' @@ -28,7 +28,7 @@ nav: - String-Valued Enums: 'user-guide/basics/enums.md' - CamelCase Conversion: 'user-guide/basics/camelcase.md' - GUID Type: 'user-guide/basics/guid-type.md' - - Get Help: 'help-fastapi-restful.md' + - Get Help: 'help-fastapi-utils.md' - Development - Contributing: 'contributing.md' - Release Notes: 'release-notes.md' @@ -48,7 +48,7 @@ markdown_extensions: extra: social: - icon: 'fontawesome/brands/github-alt' - link: 'https://github.com/yuval9313/fastapi-restful' + link: 'https://github.com/dmontagu/fastapi-utils' extra_css: - 'css/custom.css' diff --git a/pyproject.toml b/pyproject.toml index b56bf21c..d1353409 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,13 @@ [tool.poetry] -name = "fastapi-restful" +name = "fastapi-utils" version = "0.5.0" -description = "Quicker FastApi developing tools" +description = "Reusable utilities for FastAPI" license = "MIT" -authors = ["Yuval Levi "] +authors = ["Yuval Levi ", "David Montague "] readme = "README.md" -homepage = "https://fastapi-restful.netlify.app" -repository = "https://github.com/yuval9313/FastApi-RESTful" -documentation = "https://fastapi-restful.netlify.app" +homepage = "https://fastapi-utils.davidmontague.xyz" +repository = "https://github.com/dmontagu/fastapi-utils" +documentation = "https://fastapi-utils.davidmontague.xyz" keywords = ["fastapi", "OOP", "RESTful"] classifiers = [ "Intended Audience :: Information Technology", @@ -33,6 +33,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", "Topic :: Internet :: WWW/HTTP", "Topic :: Utilities" @@ -102,7 +103,7 @@ isort = { known-first-party = ['FastApi-RESTful', 'tests'] } [tool.coverage.run] -source = ["fastapi_restful"] +source = ["fastapi_utils"] branch = true [tool.coverage.report] diff --git a/tests/conftest.py b/tests/conftest.py index 0fdf3866..dbb017da 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,8 +8,8 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session -from fastapi_restful.guid_type import GUID, GUID_DEFAULT_SQLITE -from fastapi_restful.session import FastAPISessionMaker, get_engine +from fastapi_utils.guid_type import GUID, GUID_DEFAULT_SQLITE +from fastapi_utils.session import FastAPISessionMaker, get_engine Base = declarative_base() diff --git a/tests/test_api_model.py b/tests/test_api_model.py index d06d6681..2536490d 100644 --- a/tests/test_api_model.py +++ b/tests/test_api_model.py @@ -4,7 +4,7 @@ import pydantic -from fastapi_restful.api_model import APIModel +from fastapi_utils.api_model import APIModel PYDANTIC_VERSION = pydantic.VERSION diff --git a/tests/test_api_settings.py b/tests/test_api_settings.py index 9ffd90b8..ea16caa6 100644 --- a/tests/test_api_settings.py +++ b/tests/test_api_settings.py @@ -6,7 +6,7 @@ from starlette.status import HTTP_200_OK, HTTP_404_NOT_FOUND from starlette.testclient import TestClient -from fastapi_restful.api_settings import get_api_settings +from fastapi_utils.api_settings import get_api_settings def get_app() -> FastAPI: diff --git a/tests/test_camelcase.py b/tests/test_camelcase.py index 7a972c1a..104dd8f8 100644 --- a/tests/test_camelcase.py +++ b/tests/test_camelcase.py @@ -2,7 +2,7 @@ import pytest -from fastapi_restful.camelcase import camel2snake, snake2camel +from fastapi_utils.camelcase import camel2snake, snake2camel @pytest.mark.parametrize( diff --git a/tests/test_cbv.py b/tests/test_cbv.py index 34b96c69..b5b9f646 100644 --- a/tests/test_cbv.py +++ b/tests/test_cbv.py @@ -6,7 +6,7 @@ from fastapi import APIRouter, Depends, Request from starlette.testclient import TestClient -from fastapi_restful.cbv import cbv +from fastapi_utils.cbv import cbv class TestCBV: diff --git a/tests/test_cbv_base.py b/tests/test_cbv_base.py index e1945e36..3c031c1c 100644 --- a/tests/test_cbv_base.py +++ b/tests/test_cbv_base.py @@ -4,7 +4,7 @@ from fastapi.responses import PlainTextResponse from starlette.testclient import TestClient -from fastapi_restful.cbv_base import Api, Resource, set_responses +from fastapi_utils.cbv_base import Api, Resource, set_responses def test_cbv() -> None: diff --git a/tests/test_enums.py b/tests/test_enums.py index 324e895e..d4b46c24 100644 --- a/tests/test_enums.py +++ b/tests/test_enums.py @@ -2,7 +2,7 @@ from enum import auto -from fastapi_restful.enums import CamelStrEnum, StrEnum +from fastapi_utils.enums import CamelStrEnum, StrEnum class TestEnums: diff --git a/tests/test_guid_type.py b/tests/test_guid_type.py index 4775c574..38a24665 100644 --- a/tests/test_guid_type.py +++ b/tests/test_guid_type.py @@ -5,7 +5,7 @@ from fastapi import FastAPI from starlette.testclient import TestClient -from fastapi_restful.session import context_session +from fastapi_utils.session import context_session from tests.conftest import User, session_maker diff --git a/tests/test_inferring_router.py b/tests/test_inferring_router.py index c6e2587b..17a38367 100644 --- a/tests/test_inferring_router.py +++ b/tests/test_inferring_router.py @@ -6,7 +6,7 @@ from fastapi import FastAPI with pytest.warns(DeprecationWarning): - from fastapi_restful.inferring_router import InferringRouter + from fastapi_utils.inferring_router import InferringRouter OpenapiSchemaType = Dict[str, Any] diff --git a/tests/test_openapi.py b/tests/test_openapi.py index 6ced08cb..03989028 100644 --- a/tests/test_openapi.py +++ b/tests/test_openapi.py @@ -3,7 +3,7 @@ import pytest from fastapi import FastAPI -from fastapi_restful.openapi import simplify_operation_ids +from fastapi_utils.openapi import simplify_operation_ids @pytest.fixture diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 3b8d0e9f..11310b74 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -14,7 +14,7 @@ import pytest -from fastapi_restful.tasks import NoArgsNoReturnAsyncFuncT, repeat_every +from fastapi_utils.tasks import NoArgsNoReturnAsyncFuncT, repeat_every # Fixtures: diff --git a/tests/test_timing.py b/tests/test_timing.py index b0585d1b..97d9036b 100644 --- a/tests/test_timing.py +++ b/tests/test_timing.py @@ -9,7 +9,7 @@ from starlette.staticfiles import StaticFiles from starlette.testclient import TestClient -from fastapi_restful.timing import add_timing_middleware, record_timing +from fastapi_utils.timing import add_timing_middleware, record_timing if TYPE_CHECKING: from pytest.capture import CaptureFixture