fastapi-factory-utilities 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi_factory_utilities-0.7.2/LICENSE +21 -0
- fastapi_factory_utilities-0.7.2/PKG-INFO +142 -0
- fastapi_factory_utilities-0.7.2/README.md +93 -0
- fastapi_factory_utilities-0.7.2/pyproject.toml +154 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/__main__.py +6 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/__init__.py +1 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/api/__init__.py +25 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/api/tags.py +9 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/api/v1/sys/__init__.py +12 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/api/v1/sys/health.py +97 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/api/v1/sys/readiness.py +60 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/__init__.py +23 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/application.py +131 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/builder.py +109 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/config.py +185 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/enums.py +11 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/exceptions.py +20 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/app/fastapi_builder.py +86 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/exceptions.py +79 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/__init__.py +7 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/abstracts.py +40 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/__init__.py +25 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/abstract.py +48 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/configs.py +85 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/depends.py +20 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/exceptions.py +29 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/exchange.py +70 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/listener/__init__.py +7 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/listener/abstract.py +72 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/message.py +86 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/plugins.py +84 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/publisher/__init__.py +7 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/publisher/abstract.py +66 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/aiopika/queue.py +86 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/__init__.py +26 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/builder.py +259 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/configs.py +15 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/depends.py +30 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/documents.py +32 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/exceptions.py +25 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/helpers.py +16 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/plugins.py +155 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/odm_plugin/repositories.py +281 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/__init__.py +17 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/builder.py +317 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/configs.py +116 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/exceptions.py +13 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/helpers.py +42 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/instruments/__init__.py +85 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/opentelemetry_plugin/plugins.py +137 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/__init__.py +31 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/configs.py +12 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/depends.py +51 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/exceptions.py +13 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/plugin.py +41 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/plugins/taskiq_plugins/schedulers.py +187 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/protocols.py +32 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/security/jwt.py +159 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/security/kratos.py +98 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/hydra/__init__.py +13 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/hydra/exceptions.py +15 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/hydra/objects.py +26 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/hydra/services.py +122 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/kratos/__init__.py +13 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/kratos/enums.py +11 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/kratos/exceptions.py +15 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/kratos/objects.py +43 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/kratos/services.py +86 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/__init__.py +14 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/enums.py +30 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/exceptions.py +27 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/health_calculator_strategies.py +48 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/readiness_calculator_strategies.py +41 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/services.py +218 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/services/status/types.py +128 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/configs.py +80 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/importlib.py +28 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/log.py +178 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/status.py +72 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/uvicorn.py +80 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/core/utils/yaml_reader.py +166 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/__init__.py +11 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/__main__.py +6 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/api/__init__.py +19 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/api/books/__init__.py +5 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/api/books/responses.py +26 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/api/books/routes.py +59 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/app.py +60 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/application.yaml +22 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/entities/books/__init__.py +7 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/entities/books/entities.py +16 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/entities/books/enums.py +16 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/entities/books/types.py +54 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/models/__init__.py +1 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/models/books/__init__.py +6 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/models/books/document.py +20 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/models/books/repository.py +11 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/services/books/__init__.py +5 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/example/services/books/services.py +176 -0
- fastapi_factory_utilities-0.7.2/src/fastapi_factory_utilities/py.typed +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 VANROYE Victorien
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastapi_factory_utilities
|
|
3
|
+
Version: 0.7.2
|
|
4
|
+
Summary: Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie, Taskiq, AioPika and OpenTelemetry.
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: python,fastapi,beanie,taskiq,opentelemetry,microservices
|
|
8
|
+
Author: miragecentury
|
|
9
|
+
Author-email: victorien.vanroye@gmail.com
|
|
10
|
+
Maintainer: miragecentury
|
|
11
|
+
Maintainer-email: victorien.vanroye@gmail.com
|
|
12
|
+
Requires-Python: >=3.12,<3.13
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Dist: aio-pika (>=9.5.7,<10.0.0)
|
|
23
|
+
Requires-Dist: aiohttp[speedups] (>=3.12.13,<4.0.0)
|
|
24
|
+
Requires-Dist: beanie (>=1.30.0,<2.0.0)
|
|
25
|
+
Requires-Dist: fastapi (>=0.115.13,<1)
|
|
26
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.26.0,<2.0.0)
|
|
27
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.26.0,<2.0.0)
|
|
28
|
+
Requires-Dist: opentelemetry-instrumentation-aio-pika (>=0.59b0,<0.60)
|
|
29
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client (>=0,<1)
|
|
30
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi (>=0,<1)
|
|
31
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo (>=0,<1)
|
|
32
|
+
Requires-Dist: opentelemetry-propagator-b3 (>=1.26.0,<2.0.0)
|
|
33
|
+
Requires-Dist: opentelemetry-sdk (>=1.26.0,<2.0.0)
|
|
34
|
+
Requires-Dist: pyaml (>=25.1.0,<26.0.0)
|
|
35
|
+
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
|
36
|
+
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
|
37
|
+
Requires-Dist: pymongo (>=4.9.2,<4.16.0)
|
|
38
|
+
Requires-Dist: reactivex (>=4.0.4,<5.0.0)
|
|
39
|
+
Requires-Dist: structlog (>=24.1,<26.0)
|
|
40
|
+
Requires-Dist: taskiq-dependencies (>=1.5.8,<2.0.0)
|
|
41
|
+
Requires-Dist: taskiq-fastapi (>=0.3.5,<0.4.0)
|
|
42
|
+
Requires-Dist: taskiq-redis (>=1.0.9,<2.0.0)
|
|
43
|
+
Requires-Dist: typer (>=0,<1)
|
|
44
|
+
Requires-Dist: uvicorn (>=0.34.3,<1)
|
|
45
|
+
Project-URL: Homepage, https://github.com/DeerHide/fastapi_factory_utilities
|
|
46
|
+
Project-URL: Repository, https://github.com/DeerHide/fastapi_factory_utilities
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# fastapi_factory_utilities
|
|
50
|
+
|
|
51
|
+
Project Empty for Python with Poetry
|
|
52
|
+
|
|
53
|
+
## Setup
|
|
54
|
+
|
|
55
|
+
### Dev Tools
|
|
56
|
+
|
|
57
|
+
#### Python
|
|
58
|
+
|
|
59
|
+
<https://www.python.org/downloads/>
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
sudo apt install software-properties-common -y
|
|
63
|
+
sudo add-apt-repository ppa:deadsnakes/ppa
|
|
64
|
+
sudo apt update
|
|
65
|
+
sudo apt install python3.12 -y
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Poetry
|
|
69
|
+
|
|
70
|
+
<https://python-poetry.org/>
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -sSL https://install.python-poetry.org | python3.12 -
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Pre-commit
|
|
77
|
+
|
|
78
|
+
Included in the project while in virtual environment
|
|
79
|
+
<https://pre-commit.com/>
|
|
80
|
+
|
|
81
|
+
#### Docker
|
|
82
|
+
|
|
83
|
+
<https://docs.docker.com/get-docker/>
|
|
84
|
+
|
|
85
|
+
#### Skaffold
|
|
86
|
+
|
|
87
|
+
<https://skaffold.dev>
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
|
|
91
|
+
chmod +x skaffold
|
|
92
|
+
sudo mv skaffold /usr/local/bin
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Buildpacks
|
|
96
|
+
|
|
97
|
+
<https://buildpacks.io/>
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
sudo add-apt-repository ppa:cncf-buildpacks/pack-cli
|
|
101
|
+
sudo apt-get update
|
|
102
|
+
sudo apt-get install pack-cli
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Paketo
|
|
106
|
+
|
|
107
|
+
Included with the usage of buildpacks
|
|
108
|
+
<https://paketo.io/>
|
|
109
|
+
|
|
110
|
+
#### Portman
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm install -g @apideck/portman
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### MongoDB
|
|
117
|
+
|
|
118
|
+
<https://docs.mongodb.com/manual/installation/>
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
sudo apt install -y mongodb
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 1- Dev Environment
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Initialize python virtual environment and install dependencies
|
|
128
|
+
./scripts/setup_dev_env.sh
|
|
129
|
+
|
|
130
|
+
pre-commit run --all-files
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2- Build and Run Application on Docker
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
./scripts/dev-in-container.sh
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
./scripts/test_portman.sh
|
|
141
|
+
```
|
|
142
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# fastapi_factory_utilities
|
|
2
|
+
|
|
3
|
+
Project Empty for Python with Poetry
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### Dev Tools
|
|
8
|
+
|
|
9
|
+
#### Python
|
|
10
|
+
|
|
11
|
+
<https://www.python.org/downloads/>
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
sudo apt install software-properties-common -y
|
|
15
|
+
sudo add-apt-repository ppa:deadsnakes/ppa
|
|
16
|
+
sudo apt update
|
|
17
|
+
sudo apt install python3.12 -y
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
#### Poetry
|
|
21
|
+
|
|
22
|
+
<https://python-poetry.org/>
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -sSL https://install.python-poetry.org | python3.12 -
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### Pre-commit
|
|
29
|
+
|
|
30
|
+
Included in the project while in virtual environment
|
|
31
|
+
<https://pre-commit.com/>
|
|
32
|
+
|
|
33
|
+
#### Docker
|
|
34
|
+
|
|
35
|
+
<https://docs.docker.com/get-docker/>
|
|
36
|
+
|
|
37
|
+
#### Skaffold
|
|
38
|
+
|
|
39
|
+
<https://skaffold.dev>
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
|
|
43
|
+
chmod +x skaffold
|
|
44
|
+
sudo mv skaffold /usr/local/bin
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### Buildpacks
|
|
48
|
+
|
|
49
|
+
<https://buildpacks.io/>
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
sudo add-apt-repository ppa:cncf-buildpacks/pack-cli
|
|
53
|
+
sudo apt-get update
|
|
54
|
+
sudo apt-get install pack-cli
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Paketo
|
|
58
|
+
|
|
59
|
+
Included with the usage of buildpacks
|
|
60
|
+
<https://paketo.io/>
|
|
61
|
+
|
|
62
|
+
#### Portman
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm install -g @apideck/portman
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### MongoDB
|
|
69
|
+
|
|
70
|
+
<https://docs.mongodb.com/manual/installation/>
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
sudo apt install -y mongodb
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 1- Dev Environment
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Initialize python virtual environment and install dependencies
|
|
80
|
+
./scripts/setup_dev_env.sh
|
|
81
|
+
|
|
82
|
+
pre-commit run --all-files
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2- Build and Run Application on Docker
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
./scripts/dev-in-container.sh
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
./scripts/test_portman.sh
|
|
93
|
+
```
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "fastapi_factory_utilities"
|
|
3
|
+
homepage = "https://github.com/DeerHide/fastapi_factory_utilities"
|
|
4
|
+
repository = "https://github.com/DeerHide/fastapi_factory_utilities"
|
|
5
|
+
keywords = ["python", "fastapi", "beanie", "taskiq", "opentelemetry", "microservices"]
|
|
6
|
+
version = "0.7.2"
|
|
7
|
+
description = "Consolidate libraries and utilities to create microservices in Python with FastAPI, Beanie, Taskiq, AioPika and OpenTelemetry."
|
|
8
|
+
authors = ["miragecentury <victorien.vanroye@gmail.com>"]
|
|
9
|
+
maintainers = ["miragecentury <victorien.vanroye@gmail.com>"]
|
|
10
|
+
license = "MIT"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
packages = [
|
|
13
|
+
{ include = "fastapi_factory_utilities", from = "src" },
|
|
14
|
+
{ include = "fastapi_factory_utilities/py.typed", from = "src" },
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
"Topic :: Software Development :: Libraries",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[[tool.poetry.source]]
|
|
28
|
+
name = "velmios"
|
|
29
|
+
url = "https://pypi.velmios.io/simple"
|
|
30
|
+
priority = "explicit"
|
|
31
|
+
|
|
32
|
+
[tool.poetry.dependencies]
|
|
33
|
+
python = "~3.12"
|
|
34
|
+
structlog = ">=24.1,<26.0"
|
|
35
|
+
typer = "^0"
|
|
36
|
+
pydantic = "^2.8.2"
|
|
37
|
+
fastapi = ">=0.115.13,<1"
|
|
38
|
+
uvicorn = ">=0.34.3,<1"
|
|
39
|
+
opentelemetry-sdk = "^1.26.0"
|
|
40
|
+
opentelemetry-exporter-otlp-proto-http = "^1.26.0"
|
|
41
|
+
opentelemetry-exporter-otlp-proto-grpc = "^1.26.0"
|
|
42
|
+
opentelemetry-instrumentation-fastapi = "^0"
|
|
43
|
+
opentelemetry-propagator-b3 = "^1.26.0"
|
|
44
|
+
beanie = "^1.30.0"
|
|
45
|
+
opentelemetry-instrumentation-pymongo = "^0"
|
|
46
|
+
pymongo = ">=4.9.2,<4.16.0"
|
|
47
|
+
pyaml = "^25.1.0"
|
|
48
|
+
reactivex = "^4.0.4"
|
|
49
|
+
pyjwt = "^2.10.1"
|
|
50
|
+
aiohttp = { version="^3.12.13", extras=["speedups"] }
|
|
51
|
+
opentelemetry-instrumentation-aiohttp-client = "^0"
|
|
52
|
+
aio-pika = "^9.5.7"
|
|
53
|
+
opentelemetry-instrumentation-aio-pika = "^0.59b0"
|
|
54
|
+
taskiq-dependencies = { version="^1.5.8", source="velmios"}
|
|
55
|
+
taskiq-fastapi = "^0.3.5"
|
|
56
|
+
taskiq-redis = "^1.0.9"
|
|
57
|
+
|
|
58
|
+
[tool.poetry.group.test]
|
|
59
|
+
optional = true
|
|
60
|
+
|
|
61
|
+
[tool.poetry.group.test.dependencies]
|
|
62
|
+
mypy = "^1.10.0"
|
|
63
|
+
types-requests = "^2.32.0.20240712"
|
|
64
|
+
types-pyyaml = "^6.0.12.20240311"
|
|
65
|
+
pylint = {version=">=3.2.2,<5.0.0", extras=["spelling"]}
|
|
66
|
+
black = "^25.9.0"
|
|
67
|
+
pre-commit = "^4.0.1"
|
|
68
|
+
pyupgrade = "^3.15.2"
|
|
69
|
+
pytest = "^8.2.0"
|
|
70
|
+
pytest-xdist = "^3.6.1"
|
|
71
|
+
pytest-cov = "^7.0.0"
|
|
72
|
+
ruff = "^0.14"
|
|
73
|
+
pytest-asyncio = ">=0.25,<1.3"
|
|
74
|
+
pytest-mongo = "^3.1.0"
|
|
75
|
+
locust = "^2.32.4"
|
|
76
|
+
testcontainers = { version="^4.9.0", extras=["mongodb","rabbitmq", "redis"] }
|
|
77
|
+
types-deprecated = "^1.2.15.20241117"
|
|
78
|
+
types-pygments = "^2.18.0.20240506"
|
|
79
|
+
types-colorama = "^0.4.15.20240311"
|
|
80
|
+
types-protobuf = ">=5.29.1.20241207,<7.0.0.0"
|
|
81
|
+
types-psutil = ">=6.1.0.20241221,<8.0.0.0"
|
|
82
|
+
types-pyopenssl = "^24.1.0.20240722"
|
|
83
|
+
types-ujson = "^5.10.0.20240515"
|
|
84
|
+
httpx = "^0.28.1"
|
|
85
|
+
|
|
86
|
+
[tool.poetry.extras]
|
|
87
|
+
|
|
88
|
+
[tool.poetry.scripts]
|
|
89
|
+
fastapi_factory_utilities-example = "fastapi_factory_utilities.example.__main__:main"
|
|
90
|
+
|
|
91
|
+
[build-system]
|
|
92
|
+
requires = ["poetry-core"]
|
|
93
|
+
build-backend = "poetry.core.masonry.api"
|
|
94
|
+
|
|
95
|
+
[tool.pytest.ini_options]
|
|
96
|
+
testpaths = "tests"
|
|
97
|
+
addopts = "--import-mode=importlib -n auto --color=yes"
|
|
98
|
+
filterwarnings = [
|
|
99
|
+
"ignore:.*datetime.datetime.utcfromtimestamp().*:DeprecationWarning", # reactivex
|
|
100
|
+
"ignore:.*datetime.datetime.utcnow().*:DeprecationWarning", # reactivex
|
|
101
|
+
"ignore::pydantic.warnings.PydanticDeprecatedSince211",
|
|
102
|
+
"ignore:The @wait_container_is_ready decorator is deprecated.*:DeprecationWarning", # testcontainers
|
|
103
|
+
"ignore:The wait_for_logs function with string or callable predicates is deprecated.*:DeprecationWarning", # testcontainers
|
|
104
|
+
]
|
|
105
|
+
asyncio_mode = "auto"
|
|
106
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
107
|
+
mongo_params = ""
|
|
108
|
+
|
|
109
|
+
[tool.black]
|
|
110
|
+
line-length = 120
|
|
111
|
+
target-version = ['py312']
|
|
112
|
+
|
|
113
|
+
[tool.isort]
|
|
114
|
+
profile = "black"
|
|
115
|
+
|
|
116
|
+
[tool.mypy]
|
|
117
|
+
python_version = "3.12"
|
|
118
|
+
warn_unused_configs = true
|
|
119
|
+
packages = "fastapi_factory_utilities"
|
|
120
|
+
mypy_path = "src:tests"
|
|
121
|
+
namespace_packages = true
|
|
122
|
+
plugins = ["pydantic.mypy"]
|
|
123
|
+
follow_imports = "silent"
|
|
124
|
+
follow_untyped_imports = true
|
|
125
|
+
warn_redundant_casts = true
|
|
126
|
+
warn_unused_ignores = true
|
|
127
|
+
disallow_any_generics = true
|
|
128
|
+
check_untyped_defs = true
|
|
129
|
+
no_implicit_reexport = true
|
|
130
|
+
|
|
131
|
+
# for strict mypy: (this is the tricky one :-))
|
|
132
|
+
disallow_untyped_defs = true
|
|
133
|
+
|
|
134
|
+
[tool.pydantic-mypy]
|
|
135
|
+
init_forbid_extra = true
|
|
136
|
+
init_typed = true
|
|
137
|
+
warn_required_dynamic_aliases = true
|
|
138
|
+
|
|
139
|
+
[tool.ruff]
|
|
140
|
+
# Same as Black.
|
|
141
|
+
line-length = 120
|
|
142
|
+
indent-width = 4
|
|
143
|
+
|
|
144
|
+
[tool.ruff.lint]
|
|
145
|
+
select = ["D","F","E","W","I","UP","PL","N","RUF"]
|
|
146
|
+
|
|
147
|
+
[tool.ruff.format]
|
|
148
|
+
quote-style = "double"
|
|
149
|
+
indent-style = "space"
|
|
150
|
+
docstring-code-format = true
|
|
151
|
+
docstring-code-line-length = 120
|
|
152
|
+
|
|
153
|
+
[tool.ruff.lint.pydocstyle]
|
|
154
|
+
convention = "google"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Python Factory Core Module."""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Define the API for the Python Factory."""
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter
|
|
4
|
+
|
|
5
|
+
from .tags import TagEnum
|
|
6
|
+
from .v1.sys import api_v1_sys
|
|
7
|
+
|
|
8
|
+
api: APIRouter = APIRouter(prefix="/api")
|
|
9
|
+
|
|
10
|
+
### API v1 ###
|
|
11
|
+
# Prefix the API with /api/v1
|
|
12
|
+
api_v1: APIRouter = APIRouter(prefix="/v1")
|
|
13
|
+
api_v1.include_router(router=api_v1_sys)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### API v2 ###
|
|
17
|
+
# Prefix the API with /api/v2
|
|
18
|
+
api_v2: APIRouter = APIRouter(prefix="/v2")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Include the API routers ###
|
|
22
|
+
api.include_router(router=api_v1)
|
|
23
|
+
api.include_router(router=api_v2)
|
|
24
|
+
|
|
25
|
+
__all__: list[str] = ["TagEnum", "api"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Package for system related API endpoints."""
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter
|
|
4
|
+
|
|
5
|
+
from .health import api_v1_sys_health
|
|
6
|
+
from .readiness import api_v1_sys_readiness
|
|
7
|
+
|
|
8
|
+
api_v1_sys = APIRouter(prefix="/sys")
|
|
9
|
+
api_v1_sys.include_router(router=api_v1_sys_health)
|
|
10
|
+
api_v1_sys.include_router(router=api_v1_sys_readiness)
|
|
11
|
+
|
|
12
|
+
__all__: list[str] = ["api_v1_sys"]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""API v1 sys health module.
|
|
2
|
+
|
|
3
|
+
Provide the Get health endpoint
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from http import HTTPStatus
|
|
7
|
+
|
|
8
|
+
from fastapi import APIRouter, Depends, Response
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
from fastapi_factory_utilities.core.services.status.enums import HealthStatusEnum
|
|
12
|
+
from fastapi_factory_utilities.core.services.status.services import (
|
|
13
|
+
StatusService,
|
|
14
|
+
depends_status_service,
|
|
15
|
+
)
|
|
16
|
+
from fastapi_factory_utilities.core.services.status.types import ComponentInstanceKey
|
|
17
|
+
|
|
18
|
+
api_v1_sys_health = APIRouter(prefix="/health")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HealthResponseModel(BaseModel):
|
|
22
|
+
"""Health response schema."""
|
|
23
|
+
|
|
24
|
+
status: HealthStatusEnum
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@api_v1_sys_health.get(
|
|
28
|
+
path="",
|
|
29
|
+
tags=["sys"],
|
|
30
|
+
response_model=HealthResponseModel,
|
|
31
|
+
responses={
|
|
32
|
+
HTTPStatus.OK.value: {
|
|
33
|
+
"model": HealthResponseModel,
|
|
34
|
+
"description": "Health status.",
|
|
35
|
+
},
|
|
36
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
37
|
+
"model": HealthResponseModel,
|
|
38
|
+
"description": "Internal server error.",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
def get_api_v1_sys_health(
|
|
43
|
+
response: Response, status_service: StatusService = Depends(depends_status_service)
|
|
44
|
+
) -> HealthResponseModel:
|
|
45
|
+
"""Get the health of the system.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
response (Response): The response object.
|
|
49
|
+
status_service (StatusService): The status service.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
HealthResponse: The health status.
|
|
53
|
+
"""
|
|
54
|
+
status: HealthStatusEnum = status_service.get_status()["health"]
|
|
55
|
+
match status:
|
|
56
|
+
case HealthStatusEnum.HEALTHY:
|
|
57
|
+
response.status_code = HTTPStatus.OK.value
|
|
58
|
+
case HealthStatusEnum.UNHEALTHY:
|
|
59
|
+
response.status_code = HTTPStatus.INTERNAL_SERVER_ERROR.value
|
|
60
|
+
return HealthResponseModel(status=status)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ComponentHealthResponseModel(BaseModel):
|
|
64
|
+
"""Component health response schema."""
|
|
65
|
+
|
|
66
|
+
components: dict[ComponentInstanceKey, HealthStatusEnum]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@api_v1_sys_health.get(
|
|
70
|
+
path="/components",
|
|
71
|
+
tags=["sys"],
|
|
72
|
+
response_model=ComponentHealthResponseModel,
|
|
73
|
+
responses={
|
|
74
|
+
HTTPStatus.OK.value: {
|
|
75
|
+
"model": ComponentHealthResponseModel,
|
|
76
|
+
"description": "Health status of all components.",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
def get_api_v1_sys_components_health(
|
|
81
|
+
status_service: StatusService = Depends(depends_status_service),
|
|
82
|
+
) -> ComponentHealthResponseModel:
|
|
83
|
+
"""Get the health of all components.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
status_service (StatusService): The status service.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
list[ComponentHealthResponseModel]: The health status of all components.
|
|
90
|
+
"""
|
|
91
|
+
components_dict: dict[ComponentInstanceKey, HealthStatusEnum] = {}
|
|
92
|
+
|
|
93
|
+
for _, components in status_service.get_components_status_by_type().items():
|
|
94
|
+
for key, status in components.items():
|
|
95
|
+
components_dict[key] = status["health"]
|
|
96
|
+
|
|
97
|
+
return ComponentHealthResponseModel(components=dict(components_dict))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""API v1 sys readiness module.
|
|
2
|
+
|
|
3
|
+
Provide the Get readiness endpoint
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from http import HTTPStatus
|
|
7
|
+
|
|
8
|
+
from fastapi import APIRouter, Depends, Response
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
from fastapi_factory_utilities.core.services.status.enums import ReadinessStatusEnum
|
|
12
|
+
from fastapi_factory_utilities.core.services.status.services import (
|
|
13
|
+
StatusService,
|
|
14
|
+
depends_status_service,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
api_v1_sys_readiness = APIRouter(prefix="/readiness")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ReadinessResponseModel(BaseModel):
|
|
21
|
+
"""Readiness response schema."""
|
|
22
|
+
|
|
23
|
+
status: ReadinessStatusEnum
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@api_v1_sys_readiness.get(
|
|
27
|
+
path="",
|
|
28
|
+
tags=["sys"],
|
|
29
|
+
response_model=ReadinessResponseModel,
|
|
30
|
+
responses={
|
|
31
|
+
HTTPStatus.OK.value: {
|
|
32
|
+
"model": ReadinessResponseModel,
|
|
33
|
+
"description": "Readiness status.",
|
|
34
|
+
},
|
|
35
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
36
|
+
"model": ReadinessResponseModel,
|
|
37
|
+
"description": "Internal server error.",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
def get_api_v1_sys_readiness(
|
|
42
|
+
response: Response, status_service: StatusService = Depends(depends_status_service)
|
|
43
|
+
) -> ReadinessResponseModel:
|
|
44
|
+
"""Get the readiness of the system.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
response (Response): The response object.
|
|
48
|
+
status_service (StatusService): The status service
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
ReadinessResponse: The readiness status.
|
|
52
|
+
"""
|
|
53
|
+
status: ReadinessStatusEnum = status_service.get_status()["readiness"]
|
|
54
|
+
|
|
55
|
+
match status:
|
|
56
|
+
case ReadinessStatusEnum.READY:
|
|
57
|
+
response.status_code = HTTPStatus.OK.value
|
|
58
|
+
case ReadinessStatusEnum.NOT_READY:
|
|
59
|
+
response.status_code = HTTPStatus.INTERNAL_SERVER_ERROR.value
|
|
60
|
+
return ReadinessResponseModel(status=status)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Provides the core application module for the Python Factory."""
|
|
2
|
+
|
|
3
|
+
from .application import ApplicationAbstract
|
|
4
|
+
from .builder import ApplicationGenericBuilder
|
|
5
|
+
from .config import (
|
|
6
|
+
BaseApplicationConfig,
|
|
7
|
+
DependencyConfig,
|
|
8
|
+
HttpServiceDependencyConfig,
|
|
9
|
+
RootConfig,
|
|
10
|
+
depends_dependency_config,
|
|
11
|
+
)
|
|
12
|
+
from .enums import EnvironmentEnum
|
|
13
|
+
|
|
14
|
+
__all__: list[str] = [
|
|
15
|
+
"ApplicationAbstract",
|
|
16
|
+
"ApplicationGenericBuilder",
|
|
17
|
+
"BaseApplicationConfig",
|
|
18
|
+
"DependencyConfig",
|
|
19
|
+
"EnvironmentEnum",
|
|
20
|
+
"HttpServiceDependencyConfig",
|
|
21
|
+
"RootConfig",
|
|
22
|
+
"depends_dependency_config",
|
|
23
|
+
]
|