alpha-python 0.4.0__tar.gz → 0.5.0__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.
- {alpha_python-0.4.0 → alpha_python-0.5.0}/LICENSE +1 -1
- {alpha_python-0.4.0/src/alpha_python.egg-info → alpha_python-0.5.0}/PKG-INFO +58 -2
- alpha_python-0.5.0/README.md +58 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/pyproject.toml +10 -2
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/__init__.py +22 -8
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/adapters/__init__.py +2 -0
- alpha_python-0.5.0/src/alpha/adapters/rest_api_unit_of_work.py +105 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/adapters/sqla_unit_of_work.py +9 -9
- alpha_python-0.5.0/src/alpha/domain/models/group.py +35 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/exceptions.py +12 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/jwt_factory.py +18 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/controller.mustache +1 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/__init__.py +5 -1
- alpha_python-0.5.0/src/alpha/interfaces/api_repository.py +610 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/providers.py +1 -1
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/sql_repository.py +0 -11
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/mixins/jwt_provider.py +7 -7
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/database_provider.py +2 -2
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/ldap_provider.py +9 -9
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/models/identity.py +55 -21
- alpha_python-0.5.0/src/alpha/providers/models/token.py +55 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/oidc_provider.py +7 -5
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/repositories/__init__.py +2 -0
- alpha_python-0.5.0/src/alpha/repositories/models/repository_model.py +34 -0
- alpha_python-0.5.0/src/alpha/repositories/rest_api_repository.py +1199 -0
- alpha_python-0.5.0/src/alpha/services/authentication_service.py +824 -0
- alpha_python-0.5.0/src/alpha/services/models/cookie.py +51 -0
- alpha_python-0.5.0/src/alpha/utils/response_object.py +166 -0
- alpha_python-0.5.0/src/alpha/utils/secret_generator.py +19 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0/src/alpha_python.egg-info}/PKG-INFO +58 -2
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha_python.egg-info/SOURCES.txt +7 -1
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha_python.egg-info/requires.txt +1 -0
- alpha_python-0.4.0/README.md +0 -3
- alpha_python-0.4.0/src/alpha/providers/models/token.py +0 -7
- alpha_python-0.4.0/src/alpha/repositories/models/repository_model.py +0 -16
- alpha_python-0.4.0/src/alpha/services/authentication_service.py +0 -200
- alpha_python-0.4.0/src/alpha/utils/response_object.py +0 -26
- {alpha_python-0.4.0 → alpha_python-0.5.0}/setup.cfg +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/cli.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/containers/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/containers/container.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/domain/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/domain/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/domain/models/base_model.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/domain/models/life_cycle_base.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/domain/models/user.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/encoder.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/_type_conversion_matrix.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/_type_mapping.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/class_factories.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/default_field_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/field_iterator.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/logging_handler_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/model_class_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/models/factory_classes.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/password_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/request_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/response_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/factories/type_factories.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/api_generate_handler.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/api_run_handler.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/base_handler.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/gen-code.sh +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/models/argument.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/models/command.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/models/section.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/models/subparser.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/run-api.sh +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/Dockerfile.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/README.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/__init__model.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/__init__test.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/__main__.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/base_model.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/controller_test.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/dockerignore.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/encoder.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/git_push.sh.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/gitignore.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/model.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/openapi.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/param_type.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/requirements.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/security_controller_.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/setup.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/test-requirements.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/tox.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/travis.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/typing_utils.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/handlers/templates/python-flask/util.mustache +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/connectors/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/connectors/ldap_connector.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/connectors/oidc_connector.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/databases/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/databases/sql_alchemy.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/filter_operators.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/json_patch.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/order_by.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/query_clause.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/infra/models/search_filter.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/attrs_instance.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/dataclass_instance.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/factories.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/handler.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/openapi_model.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/patchable.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/pydantic_instance.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/sql_database.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/sql_mapper.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/token_factory.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/unit_of_work.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/interfaces/updateable.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/mixins/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/api_key_provider.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/providers/models/credentials.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/py.typed +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/repositories/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/repositories/sql_alchemy_repository.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/services/__init__.py +0 -0
- /alpha_python-0.4.0/src/alpha/providers/local_provider.py → /alpha_python-0.5.0/src/alpha/services/models/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/__init__.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/_http_codes.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/is_attrs.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/is_pydantic.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/logging_configurator.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/logging_level_checker.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/verify_identity.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha/utils/version_checker.py +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha_python.egg-info/dependency_links.txt +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha_python.egg-info/entry_points.txt +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/src/alpha_python.egg-info/top_level.txt +0 -0
- {alpha_python-0.4.0 → alpha_python-0.5.0}/tests/test_encoder.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpha-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
|
|
5
5
|
Author-email: Bart Reijling <bart@reijling.eu>
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -29,6 +29,7 @@ Requires-Dist: itsdangerous==1.1.0; extra == "flask"
|
|
|
29
29
|
Requires-Dist: MarkupSafe<2.0.2; extra == "flask"
|
|
30
30
|
Requires-Dist: Jinja2==2.11.2; extra == "flask"
|
|
31
31
|
Requires-Dist: Flask<2,>=1.1.2; extra == "flask"
|
|
32
|
+
Requires-Dist: Werkzeug<2.1.0,>=1.0.1; extra == "flask"
|
|
32
33
|
Requires-Dist: flask-cors>=3.0.10; extra == "flask"
|
|
33
34
|
Requires-Dist: Flask-Compress>=1.13; extra == "flask"
|
|
34
35
|
Provides-Extra: mysql
|
|
@@ -41,4 +42,59 @@ Dynamic: license-file
|
|
|
41
42
|
|
|
42
43
|
# alpha
|
|
43
44
|
|
|
44
|
-
Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
|
|
45
|
+
Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
|
|
46
|
+
|
|
47
|
+
## Badges
|
|
48
|
+
|
|
49
|
+
[](https://badge.fury.io/py/alpha-python)
|
|
50
|
+
[](https://travis-ci.com/breijling/alpha)
|
|
51
|
+
[](https://coveralls.io/github/breijling/alpha?branch=main)
|
|
52
|
+
[](https://choosealicense.com/licenses/mit/)
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
TODO: Add documentation link when available.
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
The library is still in development, but you can already install it using pip:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
pip install alpha-python
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If you want to use the alpha cli for generating API code, you can install it using pip as well:
|
|
67
|
+
|
|
68
|
+
```shell
|
|
69
|
+
pip install alpha-python[api-generator]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
If you want to add the library to your API project, you can add it to your pyproject.toml file:
|
|
73
|
+
|
|
74
|
+
```shell
|
|
75
|
+
# Poetry example
|
|
76
|
+
poetry add alpha-python --extras "flask, postgresql"
|
|
77
|
+
poetry add --dev alpha-python --extras "api-generator"
|
|
78
|
+
|
|
79
|
+
# UV example
|
|
80
|
+
uv add alpha-python --extra flask --extra postgresql
|
|
81
|
+
uv add --dev alpha-python --extra api-generator
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
The library contains a lot of different components, but the most important ones are:
|
|
87
|
+
|
|
88
|
+
- `alpha.encoder.JSONEncoder`: A JSON encoder that can be used to serialize complex objects to JSON.
|
|
89
|
+
|
|
90
|
+
## Features
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Contributing
|
|
95
|
+
|
|
96
|
+
If you want to contribute to the development of this library, you can fork the repository and create a pull request with your changes.
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
This library is licensed under the MIT License. See the LICENSE file for more information.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# alpha
|
|
2
|
+
|
|
3
|
+
Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
|
|
4
|
+
|
|
5
|
+
## Badges
|
|
6
|
+
|
|
7
|
+
[](https://badge.fury.io/py/alpha-python)
|
|
8
|
+
[](https://travis-ci.com/breijling/alpha)
|
|
9
|
+
[](https://coveralls.io/github/breijling/alpha?branch=main)
|
|
10
|
+
[](https://choosealicense.com/licenses/mit/)
|
|
11
|
+
|
|
12
|
+
## Documentation
|
|
13
|
+
|
|
14
|
+
TODO: Add documentation link when available.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
The library is still in development, but you can already install it using pip:
|
|
19
|
+
|
|
20
|
+
```shell
|
|
21
|
+
pip install alpha-python
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If you want to use the alpha cli for generating API code, you can install it using pip as well:
|
|
25
|
+
|
|
26
|
+
```shell
|
|
27
|
+
pip install alpha-python[api-generator]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you want to add the library to your API project, you can add it to your pyproject.toml file:
|
|
31
|
+
|
|
32
|
+
```shell
|
|
33
|
+
# Poetry example
|
|
34
|
+
poetry add alpha-python --extras "flask, postgresql"
|
|
35
|
+
poetry add --dev alpha-python --extras "api-generator"
|
|
36
|
+
|
|
37
|
+
# UV example
|
|
38
|
+
uv add alpha-python --extra flask --extra postgresql
|
|
39
|
+
uv add --dev alpha-python --extra api-generator
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
The library contains a lot of different components, but the most important ones are:
|
|
45
|
+
|
|
46
|
+
- `alpha.encoder.JSONEncoder`: A JSON encoder that can be used to serialize complex objects to JSON.
|
|
47
|
+
|
|
48
|
+
## Features
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Contributing
|
|
53
|
+
|
|
54
|
+
If you want to contribute to the development of this library, you can fork the repository and create a pull request with your changes.
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
This library is licensed under the MIT License. See the LICENSE file for more information.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "alpha-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = "Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -56,7 +56,10 @@ dev = [
|
|
|
56
56
|
"psycopg2-binary>=2.9.11",
|
|
57
57
|
"pymysql>=1.1.2",
|
|
58
58
|
"ldap3>=2.9.1",
|
|
59
|
-
"cryptography>=46.0.3"
|
|
59
|
+
"cryptography>=46.0.3",
|
|
60
|
+
"ipykernel>=7.2.0",
|
|
61
|
+
"flask<2",
|
|
62
|
+
"httpx>=0.28.1",
|
|
60
63
|
]
|
|
61
64
|
|
|
62
65
|
[project.optional-dependencies]
|
|
@@ -72,6 +75,7 @@ flask = [
|
|
|
72
75
|
"MarkupSafe<2.0.2",
|
|
73
76
|
"Jinja2==2.11.2",
|
|
74
77
|
"Flask>=1.1.2,<2",
|
|
78
|
+
"Werkzeug>=1.0.1,<2.1.0",
|
|
75
79
|
"flask-cors>=3.0.10",
|
|
76
80
|
"Flask-Compress>=1.13",
|
|
77
81
|
]
|
|
@@ -116,5 +120,9 @@ force_grid_wrap = 0
|
|
|
116
120
|
python_version = "3.11"
|
|
117
121
|
exclude = ['^tests/']
|
|
118
122
|
|
|
123
|
+
[[tool.mypy.overrides]]
|
|
124
|
+
module = ["flask", "flask.*"]
|
|
125
|
+
ignore_missing_imports = true
|
|
126
|
+
|
|
119
127
|
[tool.ruff]
|
|
120
128
|
line-length = 79
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from alpha.adapters.rest_api_unit_of_work import RestApiUnitOfWork
|
|
1
2
|
from alpha.adapters.sqla_unit_of_work import SqlAlchemyUnitOfWork
|
|
2
3
|
from alpha.factories.jwt_factory import JWTFactory
|
|
3
4
|
from alpha.factories.logging_handler_factory import LoggingHandlerFactory
|
|
@@ -20,6 +21,7 @@ from alpha.interfaces.pydantic_instance import PydanticInstance
|
|
|
20
21
|
from alpha.interfaces.openapi_model import OpenAPIModel
|
|
21
22
|
from alpha.interfaces.updateable import Updateable
|
|
22
23
|
from alpha.interfaces.patchable import Patchable
|
|
24
|
+
from alpha.interfaces.api_repository import ApiRepository
|
|
23
25
|
from alpha.interfaces.sql_repository import SqlRepository
|
|
24
26
|
from alpha.interfaces.sql_mapper import SqlMapper
|
|
25
27
|
from alpha.interfaces.sql_database import SqlDatabase
|
|
@@ -44,6 +46,7 @@ from alpha.providers.models.credentials import PasswordCredentials
|
|
|
44
46
|
from alpha.providers.models.token import Token
|
|
45
47
|
from alpha.providers.oidc_provider import OIDCProvider, KeyCloakProvider
|
|
46
48
|
from alpha.repositories.models.repository_model import RepositoryModel
|
|
49
|
+
from alpha.repositories.rest_api_repository import RestApiRepository
|
|
47
50
|
from alpha.repositories.sql_alchemy_repository import SqlAlchemyRepository
|
|
48
51
|
from alpha.services.authentication_service import AuthenticationService
|
|
49
52
|
from alpha.utils.is_attrs import is_attrs
|
|
@@ -60,13 +63,20 @@ from alpha.encoder import JSONEncoder
|
|
|
60
63
|
|
|
61
64
|
# Optional LDAP support - only import if ldap3 is available
|
|
62
65
|
try:
|
|
63
|
-
from alpha.infra.connectors.ldap_connector import
|
|
64
|
-
|
|
66
|
+
from alpha.infra.connectors.ldap_connector import (
|
|
67
|
+
LDAPConnector, # noqa: F401
|
|
68
|
+
)
|
|
69
|
+
from alpha.providers.ldap_provider import (
|
|
70
|
+
LDAPProvider, # noqa: F401
|
|
71
|
+
ADProvider, # noqa: F401
|
|
72
|
+
)
|
|
73
|
+
|
|
65
74
|
_LDAP_AVAILABLE = True
|
|
66
75
|
except ImportError:
|
|
67
|
-
_LDAP_AVAILABLE = False
|
|
76
|
+
_LDAP_AVAILABLE = False # type: ignore
|
|
68
77
|
|
|
69
78
|
__all__ = [
|
|
79
|
+
"RestApiUnitOfWork",
|
|
70
80
|
"SqlAlchemyUnitOfWork",
|
|
71
81
|
"JWTFactory",
|
|
72
82
|
"LoggingHandlerFactory",
|
|
@@ -91,6 +101,7 @@ __all__ = [
|
|
|
91
101
|
"OpenAPIModel",
|
|
92
102
|
"Updateable",
|
|
93
103
|
"Patchable",
|
|
104
|
+
"ApiRepository",
|
|
94
105
|
"SqlRepository",
|
|
95
106
|
"SqlMapper",
|
|
96
107
|
"SqlDatabase",
|
|
@@ -112,6 +123,7 @@ __all__ = [
|
|
|
112
123
|
"OIDCProvider",
|
|
113
124
|
"KeyCloakProvider",
|
|
114
125
|
"RepositoryModel",
|
|
126
|
+
"RestApiRepository",
|
|
115
127
|
"SqlAlchemyRepository",
|
|
116
128
|
"AuthenticationService",
|
|
117
129
|
"is_attrs",
|
|
@@ -128,8 +140,10 @@ __all__ = [
|
|
|
128
140
|
|
|
129
141
|
# Conditionally add LDAP-related exports if available
|
|
130
142
|
if _LDAP_AVAILABLE:
|
|
131
|
-
__all__.extend(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
__all__.extend(
|
|
144
|
+
[
|
|
145
|
+
"LDAPConnector",
|
|
146
|
+
"LDAPProvider",
|
|
147
|
+
"ADProvider",
|
|
148
|
+
]
|
|
149
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Contains the REST API Unit of Work implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, TypeVar
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
from alpha.repositories.models.repository_model import RepositoryModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
UOW = TypeVar("UOW", bound="RestApiUnitOfWork")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RestApiUnitOfWork:
|
|
14
|
+
"""Unit of Work implementation for REST API interactions."""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
repos: list[RepositoryModel[Any]],
|
|
19
|
+
session: requests.sessions.Session | None = None,
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Initialize the Unit of Work with repositories.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
repos : list[RepositoryModel]
|
|
26
|
+
The list of repository models to use.
|
|
27
|
+
session : requests.sessions.Session | None
|
|
28
|
+
The requests session (or compatible HTTP client, e.g., httpx) to
|
|
29
|
+
use for context management, by default None
|
|
30
|
+
|
|
31
|
+
Raises
|
|
32
|
+
------
|
|
33
|
+
TypeError
|
|
34
|
+
If any repository does not implement its specified interface.
|
|
35
|
+
"""
|
|
36
|
+
self._repositories = repos
|
|
37
|
+
self._session = session
|
|
38
|
+
|
|
39
|
+
def __enter__(self: UOW) -> UOW:
|
|
40
|
+
"""Enter the REST API Unit of Work context.
|
|
41
|
+
Initializes a :class:`requests.sessions.Session` if one was not
|
|
42
|
+
provided and attaches the configured repositories as attributes on the
|
|
43
|
+
unit of work instance. Each repository is constructed using the shared
|
|
44
|
+
session and its associated configuration, and optionally validated
|
|
45
|
+
against a declared interface.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
UOW
|
|
50
|
+
The configured :class:`RestApiUnitOfWork` instance to be used
|
|
51
|
+
within the context manager.
|
|
52
|
+
"""
|
|
53
|
+
self._session = self._session or requests.sessions.Session()
|
|
54
|
+
|
|
55
|
+
for repo in self._repositories:
|
|
56
|
+
name: str = repo.name
|
|
57
|
+
interface: Any = repo.interface
|
|
58
|
+
additional_config: dict[str, Any] = dict(
|
|
59
|
+
repo.additional_config or {}
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
self.__setattr__(
|
|
63
|
+
name,
|
|
64
|
+
repo.repository(
|
|
65
|
+
session=self._session,
|
|
66
|
+
default_model=repo.default_model,
|
|
67
|
+
**additional_config,
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if interface:
|
|
72
|
+
if not isinstance(getattr(self, name), interface):
|
|
73
|
+
raise TypeError(f"Repository for {name} has no interface")
|
|
74
|
+
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def __exit__(self, *args: Any) -> None:
|
|
78
|
+
"""Finalize the Unit of Work context."""
|
|
79
|
+
if self._session:
|
|
80
|
+
self._session.close()
|
|
81
|
+
|
|
82
|
+
def commit(self) -> None:
|
|
83
|
+
raise NotImplementedError("RestApiUnitOfWork does not support commit")
|
|
84
|
+
|
|
85
|
+
def flush(self) -> None:
|
|
86
|
+
raise NotImplementedError("RestApiUnitOfWork does not support flush")
|
|
87
|
+
|
|
88
|
+
def rollback(self) -> None:
|
|
89
|
+
raise NotImplementedError(
|
|
90
|
+
"RestApiUnitOfWork does not support rollback"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def refresh(self, obj: object) -> None:
|
|
94
|
+
raise NotImplementedError("RestApiUnitOfWork does not support refresh")
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def session(self) -> requests.sessions.Session | None:
|
|
98
|
+
"""Get the current session.
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
requests.sessions.Session | None
|
|
103
|
+
The current session used for API interactions.
|
|
104
|
+
"""
|
|
105
|
+
return self._session
|
|
@@ -14,7 +14,11 @@ UOW = TypeVar("UOW", bound="SqlAlchemyUnitOfWork")
|
|
|
14
14
|
class SqlAlchemyUnitOfWork:
|
|
15
15
|
"""Unit of Work implementation for SQLAlchemy databases."""
|
|
16
16
|
|
|
17
|
-
def __init__(
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
db: SqlDatabase,
|
|
20
|
+
repos: list[RepositoryModel[Any]],
|
|
21
|
+
) -> None:
|
|
18
22
|
"""Initialize the Unit of Work with a database and repositories.
|
|
19
23
|
|
|
20
24
|
Parameters
|
|
@@ -28,9 +32,6 @@ class SqlAlchemyUnitOfWork:
|
|
|
28
32
|
------
|
|
29
33
|
TypeError
|
|
30
34
|
If the provided database is not a valid SqlDatabase instance.
|
|
31
|
-
TypeError
|
|
32
|
-
If the provided repositories list is empty or contains invalid
|
|
33
|
-
models.
|
|
34
35
|
"""
|
|
35
36
|
if not isinstance(db, SqlDatabase): # type: ignore
|
|
36
37
|
raise TypeError("No valid database provided")
|
|
@@ -55,17 +56,16 @@ class SqlAlchemyUnitOfWork:
|
|
|
55
56
|
self._session = self._db.get_session()
|
|
56
57
|
|
|
57
58
|
for repo in self._repositories:
|
|
58
|
-
session = self._session
|
|
59
|
-
model = repo.default_model
|
|
60
|
-
|
|
61
59
|
name: str = repo.name
|
|
62
|
-
repository = repo.repository
|
|
63
60
|
interface: Any = repo.interface
|
|
64
61
|
|
|
65
62
|
self.__setattr__(
|
|
66
63
|
name,
|
|
67
|
-
repository(
|
|
64
|
+
repo.repository(
|
|
65
|
+
session=self._session, default_model=repo.default_model
|
|
66
|
+
),
|
|
68
67
|
)
|
|
68
|
+
|
|
69
69
|
if interface:
|
|
70
70
|
if not isinstance(getattr(self, name), interface):
|
|
71
71
|
raise TypeError(f"Repository for {name} has no interface")
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
from typing import Sequence, cast
|
|
4
|
+
from uuid import UUID
|
|
5
|
+
|
|
6
|
+
from alpha.domain.models.base_model import BaseDomainModel, DomainModel
|
|
7
|
+
from alpha.domain.models.life_cycle_base import LifeCycleBase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(kw_only=True)
|
|
11
|
+
class Group(LifeCycleBase, BaseDomainModel):
|
|
12
|
+
id: UUID | int | str | None = None
|
|
13
|
+
name: str | None = None
|
|
14
|
+
description: str | None = None
|
|
15
|
+
permissions: Sequence[str] | None = None
|
|
16
|
+
is_active: bool = True
|
|
17
|
+
|
|
18
|
+
def update(self, obj: DomainModel) -> DomainModel:
|
|
19
|
+
"""Update the Group instance with data from another Group instance.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
obj
|
|
24
|
+
Group object to update from.
|
|
25
|
+
"""
|
|
26
|
+
if not isinstance(obj, Group):
|
|
27
|
+
raise TypeError("Group.update expects a Group instance.")
|
|
28
|
+
|
|
29
|
+
self.name = obj.name
|
|
30
|
+
self.description = obj.description
|
|
31
|
+
self.permissions = obj.permissions
|
|
32
|
+
self.modified_at = datetime.now(tz=timezone.utc)
|
|
33
|
+
self.is_active = obj.is_active
|
|
34
|
+
|
|
35
|
+
return cast(DomainModel, self)
|
|
@@ -19,6 +19,10 @@ class NotFoundException(ClientErrorException):
|
|
|
19
19
|
"""Equivalent to HTTP code 404"""
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
class MethodNotAllowedException(ClientErrorException):
|
|
23
|
+
"""Equivalent to HTTP code 405"""
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
class NotAcceptableException(ClientErrorException):
|
|
23
27
|
"""Equivalent to HTTP code 406"""
|
|
24
28
|
|
|
@@ -55,11 +59,19 @@ class ServiceUnavailableException(ServerErrorException):
|
|
|
55
59
|
"""Equivalent to HTTP code 503"""
|
|
56
60
|
|
|
57
61
|
|
|
62
|
+
class GatewayTimeoutException(ServerErrorException):
|
|
63
|
+
"""Equivalent to HTTP code 504"""
|
|
64
|
+
|
|
65
|
+
|
|
58
66
|
# General Exceptions
|
|
59
67
|
class MissingConfigurationException(Exception):
|
|
60
68
|
"""Raised when a required configuration is missing."""
|
|
61
69
|
|
|
62
70
|
|
|
71
|
+
class InvalidAttributeError(Exception):
|
|
72
|
+
"""Raised when a required attribute is invalid."""
|
|
73
|
+
|
|
74
|
+
|
|
63
75
|
class MissingDependencyException(Exception):
|
|
64
76
|
"""Raised when a required dependency is missing."""
|
|
65
77
|
|
|
@@ -19,6 +19,24 @@ class JWTFactory:
|
|
|
19
19
|
issuer: str = "http://localhost",
|
|
20
20
|
jwt_algorithm: str = "HS256",
|
|
21
21
|
) -> None:
|
|
22
|
+
"""Initialize the JWTFactory.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
secret
|
|
27
|
+
The secret key used to sign the JWT.
|
|
28
|
+
lifetime_hours, optional
|
|
29
|
+
The lifetime of the JWT in hours, by default "12"
|
|
30
|
+
issuer, optional
|
|
31
|
+
The issuer of the JWT, by default "http://localhost"
|
|
32
|
+
jwt_algorithm, optional
|
|
33
|
+
The algorithm used to sign the JWT, by default "HS256"
|
|
34
|
+
|
|
35
|
+
Raises
|
|
36
|
+
------
|
|
37
|
+
ValueError
|
|
38
|
+
If the secret value is empty.
|
|
39
|
+
"""
|
|
22
40
|
if not secret:
|
|
23
41
|
raise ValueError("Secret value cannot be empty")
|
|
24
42
|
if lifetime_hours is None:
|
|
@@ -231,6 +231,7 @@ def {{operationId}}(
|
|
|
231
231
|
status_message='{{message}}',
|
|
232
232
|
data=result,
|
|
233
233
|
{{#vendorExtensions.x-content-type}}data_type='{{vendorExtensions.x-content-type}}'{{/vendorExtensions.x-content-type}}
|
|
234
|
+
{{#vendorExtensions.x-alpha-cookie-support}}response_type='flask'{{/vendorExtensions.x-alpha-cookie-support}}
|
|
234
235
|
)
|
|
235
236
|
return response_object, status_code
|
|
236
237
|
{{/returnType}}
|
|
@@ -6,8 +6,11 @@ from alpha.interfaces.openapi_model import OpenAPIModel
|
|
|
6
6
|
from alpha.interfaces.updateable import Updateable
|
|
7
7
|
from alpha.interfaces.patchable import Patchable
|
|
8
8
|
|
|
9
|
-
# import all
|
|
9
|
+
# import all repository related interfaces
|
|
10
|
+
from alpha.interfaces.api_repository import ApiRepository
|
|
10
11
|
from alpha.interfaces.sql_repository import SqlRepository
|
|
12
|
+
|
|
13
|
+
# import all database related interfaces
|
|
11
14
|
from alpha.interfaces.sql_mapper import SqlMapper
|
|
12
15
|
from alpha.interfaces.sql_database import SqlDatabase
|
|
13
16
|
from alpha.interfaces.unit_of_work import UnitOfWork
|
|
@@ -30,6 +33,7 @@ __all__ = [
|
|
|
30
33
|
"OpenAPIModel",
|
|
31
34
|
"Updateable",
|
|
32
35
|
"Patchable",
|
|
36
|
+
"ApiRepository",
|
|
33
37
|
"SqlRepository",
|
|
34
38
|
"SqlMapper",
|
|
35
39
|
"SqlDatabase",
|