alpha-python 0.6.0__tar.gz → 0.6.1__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.6.1/PKG-INFO +210 -0
- alpha_python-0.6.1/README.md +153 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/pyproject.toml +12 -5
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/cli.py +27 -23
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/encoder.py +4 -3
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/jwt_factory.py +10 -7
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/password_factory.py +8 -1
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/api_generate_handler.py +5 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/__main__.mustache +26 -9
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/controller.mustache +23 -22
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/json_patch.py +1 -1
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/order_by.py +4 -2
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/query_clause.py +2 -2
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/token_factory.py +5 -3
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/models/identity.py +5 -5
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/oidc_provider.py +0 -2
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/services/authentication_service.py +10 -4
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/logging_configurator.py +1 -1
- alpha_python-0.6.1/src/alpha/utils/openapi_test/response.py +12 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/service.py +0 -6
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/response_object.py +10 -1
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/verify_identity.py +7 -7
- alpha_python-0.6.1/src/alpha_python.egg-info/PKG-INFO +210 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha_python.egg-info/SOURCES.txt +1 -0
- alpha_python-0.6.0/PKG-INFO +0 -117
- alpha_python-0.6.0/README.md +0 -60
- alpha_python-0.6.0/src/alpha_python.egg-info/PKG-INFO +0 -117
- {alpha_python-0.6.0 → alpha_python-0.6.1}/LICENSE +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/setup.cfg +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/adapters/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/adapters/rest_api_unit_of_work.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/adapters/sqla_unit_of_work.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/containers/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/containers/container.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/base_model.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/group.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/life_cycle_base.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/role.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/domain/models/user.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/exceptions.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/_type_conversion_matrix.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/_type_mapping.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/class_factories.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/default_field_factory.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/field_iterator.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/logging_handler_factory.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/model_class_factory.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/models/factory_classes.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/request_factory.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/response_factory.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/factories/type_factories.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/api_run_handler.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/base_handler.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/gen-code.sh +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/models/argument.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/models/command.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/models/section.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/models/subparser.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/run-api.sh +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/Dockerfile.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/README.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/__init__model.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/__init__test.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/base_model.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/controller_test.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/dockerignore.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/encoder.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/git_push.sh.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/gitignore.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/model.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/openapi.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/param_type.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/requirements.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/security_controller_.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/setup.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/test-requirements.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/tox.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/travis.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/typing_utils.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/handlers/templates/python-flask/util.mustache +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/connectors/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/connectors/ldap_connector.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/connectors/oidc_connector.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/connectors/sql_alchemy.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/databases/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/databases/sql_alchemy.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/filter_operators.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/infra/models/search_filter.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/api_repository.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/attrs_instance.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/dataclass_instance.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/factories.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/handler.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/openapi_model.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/patchable.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/providers.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/pydantic_instance.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/sql_database.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/sql_mapper.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/sql_repository.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/unit_of_work.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/interfaces/updatable.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/mixins/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/mixins/group_lifecycle.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/mixins/jwt_provider.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/mixins/user_lifecycle.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/api_key_provider.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/database_provider.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/ldap_provider.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/models/credentials.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/providers/models/token.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/py.typed +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/repositories/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/repositories/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/repositories/models/repository_model.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/repositories/rest_api_repository.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/repositories/sql_alchemy_repository.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/services/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/services/models/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/services/models/cookie.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/services/user_lifecycle_management.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/_http_codes.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/cookie.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/is_attrs.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/is_pydantic.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/logging_level_checker.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/__init__.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/container.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/exceptions.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/models.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/openapi_test/orm.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/request_headers.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/secret_generator.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha/utils/version_checker.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha_python.egg-info/dependency_links.txt +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha_python.egg-info/entry_points.txt +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha_python.egg-info/requires.txt +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/src/alpha_python.egg-info/top_level.txt +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/tests/test_cli.py +0 -0
- {alpha_python-0.6.0 → alpha_python-0.6.1}/tests/test_encoder.py +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpha-python
|
|
3
|
+
Version: 0.6.1
|
|
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
|
+
Author-email: Bart Reijling <bart@reijling.eu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/breijling/alpha
|
|
8
|
+
Project-URL: Issues, https://github.com/breijling/alpha/issues
|
|
9
|
+
Project-URL: Documentation, https://alpha-python.readthedocs.io/en/latest/
|
|
10
|
+
Project-URL: Changelog, https://alpha-python.readthedocs.io/en/latest/changelog/
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Requires-Python: <3.15,>=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: attrs>=25.4.0
|
|
23
|
+
Requires-Dist: gunicorn>=23.0.0
|
|
24
|
+
Requires-Dist: jsonpatch>=1.33
|
|
25
|
+
Requires-Dist: numpy>=2.3.5
|
|
26
|
+
Requires-Dist: pandas>=1.13
|
|
27
|
+
Requires-Dist: pydantic>=2.12.5
|
|
28
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
29
|
+
Requires-Dist: six>=1.17.0
|
|
30
|
+
Requires-Dist: sqlalchemy>=2.0.44
|
|
31
|
+
Requires-Dist: requests>=2.28.1
|
|
32
|
+
Requires-Dist: dependency-injector[yaml]!=4.48.3,<5.0.0,>=4.42.0
|
|
33
|
+
Requires-Dist: argon2-cffi>=25.1.0
|
|
34
|
+
Requires-Dist: httpx
|
|
35
|
+
Requires-Dist: cryptography
|
|
36
|
+
Provides-Extra: api-generator
|
|
37
|
+
Requires-Dist: openapi-generator-cli==7.14.0; extra == "api-generator"
|
|
38
|
+
Requires-Dist: jdk4py; extra == "api-generator"
|
|
39
|
+
Provides-Extra: flask
|
|
40
|
+
Requires-Dist: connexion[swagger-ui]<3,>=2.14.2; extra == "flask"
|
|
41
|
+
Requires-Dist: swagger-ui-bundle>=0.0.2; extra == "flask"
|
|
42
|
+
Requires-Dist: python_dateutil>=2.6.0; extra == "flask"
|
|
43
|
+
Requires-Dist: itsdangerous==1.1.0; extra == "flask"
|
|
44
|
+
Requires-Dist: MarkupSafe<2.0.2; extra == "flask"
|
|
45
|
+
Requires-Dist: Jinja2==2.11.2; extra == "flask"
|
|
46
|
+
Requires-Dist: Flask<2,>=1.1.2; extra == "flask"
|
|
47
|
+
Requires-Dist: Werkzeug<2.1.0,>=1.0.1; extra == "flask"
|
|
48
|
+
Requires-Dist: flask-cors>=3.0.10; extra == "flask"
|
|
49
|
+
Requires-Dist: Flask-Compress>=1.13; extra == "flask"
|
|
50
|
+
Provides-Extra: mysql
|
|
51
|
+
Requires-Dist: pymysql>=1.1.2; extra == "mysql"
|
|
52
|
+
Provides-Extra: postgresql
|
|
53
|
+
Requires-Dist: psycopg2-binary>=2.9.11; extra == "postgresql"
|
|
54
|
+
Provides-Extra: ldap
|
|
55
|
+
Requires-Dist: ldap3>=2.9.1; extra == "ldap"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
# Alpha
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
## Badges
|
|
63
|
+
|
|
64
|
+
[](https://badge.fury.io/py/alpha-python)
|
|
65
|
+
[](https://pypistats.org/packages/alpha-python)
|
|
66
|
+
[](https://github.com/breijling/alpha/actions/workflows/python-app.yml)
|
|
67
|
+
[](https://pypi.org/project/alpha-python)
|
|
68
|
+
[](https://coveralls.io/github/BReijling/alpha?branch=main)
|
|
69
|
+
[](https://docs.astral.sh/uv/)
|
|
70
|
+
[](https://mypy-lang.org/)
|
|
71
|
+
[](https://docs.pytest.org/)
|
|
72
|
+
[](https://www.python.org/dev/peps/pep-0008/)
|
|
73
|
+
[](https://github.com/astral-sh/ruff)
|
|
74
|
+
[](https://alpha-python.readthedocs.io/en/latest/)
|
|
75
|
+
[](https://choosealicense.com/licenses/mit/)
|
|
76
|
+
[](https://github.com/sponsors/BReijling)
|
|
77
|
+
|
|
78
|
+
## TL;DR
|
|
79
|
+
|
|
80
|
+
Alpha provides a comprehensive set of tools for building Python applications that interact with APIs and databases, including API code generation, authentication and authorization, database access layers, error handling, logging, and more. It is designed to be the first dependency you add to your project, providing a solid foundation for your application's architecture.
|
|
81
|
+
|
|
82
|
+
## Documentation
|
|
83
|
+
|
|
84
|
+
Full documentation is available at [alpha-python.readthedocs.io](https://alpha-python.readthedocs.io/).
|
|
85
|
+
|
|
86
|
+
## Installation
|
|
87
|
+
|
|
88
|
+
The library is still in development, but you can already install it using pip:
|
|
89
|
+
|
|
90
|
+
```shell
|
|
91
|
+
pip install alpha-python
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If you want to use the alpha cli for generating API code, you can install it using pip as well:
|
|
95
|
+
|
|
96
|
+
```shell
|
|
97
|
+
pip install alpha-python[api-generator]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If you want to add the library to your API project, you can add it to your pyproject.toml file:
|
|
101
|
+
|
|
102
|
+
```shell
|
|
103
|
+
# Poetry example
|
|
104
|
+
poetry add alpha-python --extras "flask, postgresql"
|
|
105
|
+
poetry add --dev alpha-python --extras "api-generator"
|
|
106
|
+
|
|
107
|
+
# UV example
|
|
108
|
+
uv add alpha-python --extra flask --extra postgresql
|
|
109
|
+
uv add --dev alpha-python --extra api-generator
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Features
|
|
113
|
+
|
|
114
|
+
- API code generation
|
|
115
|
+
- Authentication and authorization
|
|
116
|
+
- Database interaction
|
|
117
|
+
- Logging
|
|
118
|
+
- Error handling
|
|
119
|
+
- And much more!
|
|
120
|
+
|
|
121
|
+
## Usage
|
|
122
|
+
|
|
123
|
+
The library contains many components. Below are a few practical examples that map to the guides in the documentation.
|
|
124
|
+
|
|
125
|
+
### 1) API code generation using OpenAPI spec
|
|
126
|
+
|
|
127
|
+
```shell
|
|
128
|
+
alpha api gen --spec-file specification/openapi.yaml --service-package my_app
|
|
129
|
+
|
|
130
|
+
alpha api run --port 8080
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2) Authenticate with Keycloak (OIDC)
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from alpha import KeyCloakOIDCConnector, KeyCloakProvider, PasswordCredentials
|
|
137
|
+
|
|
138
|
+
keycloak_connector = KeyCloakOIDCConnector(
|
|
139
|
+
base_url="https://keycloak.example.com",
|
|
140
|
+
realm="myrealm",
|
|
141
|
+
client_id="myclient",
|
|
142
|
+
client_secret="myclientsecret",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
keycloak_provider = KeyCloakProvider(connector=keycloak_connector)
|
|
146
|
+
|
|
147
|
+
credentials = PasswordCredentials(username="user1", password="user1_password")
|
|
148
|
+
identity = keycloak_provider.authenticate(credentials)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3) Query data using SqlAlchemyDatabase + SqlAlchemyRepository
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from alpha import SqlAlchemyDatabase, SqlAlchemyRepository
|
|
155
|
+
from my_app import User
|
|
156
|
+
|
|
157
|
+
db = SqlAlchemyDatabase(conn_str="postgresql://user:password@localhost:5432/mydatabase")
|
|
158
|
+
|
|
159
|
+
with db.get_session() as session:
|
|
160
|
+
users = SqlAlchemyRepository[User](session=session, default_model=User)
|
|
161
|
+
user = users.get_by_id(1)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 4) Use Unit of Work for transactional operations
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from alpha import (
|
|
168
|
+
RepositoryModel,
|
|
169
|
+
SqlAlchemyDatabase,
|
|
170
|
+
SqlAlchemyRepository,
|
|
171
|
+
SqlAlchemyUnitOfWork,
|
|
172
|
+
)
|
|
173
|
+
from my_app import User, OrmMapper
|
|
174
|
+
|
|
175
|
+
db = SqlAlchemyDatabase(..., mapper=OrmMapper)
|
|
176
|
+
repositories = [
|
|
177
|
+
RepositoryModel(
|
|
178
|
+
name="users",
|
|
179
|
+
repository=SqlAlchemyRepository[User],
|
|
180
|
+
default_model=User,
|
|
181
|
+
)
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
uow = SqlAlchemyUnitOfWork(db=db, repos=repositories)
|
|
185
|
+
|
|
186
|
+
with uow:
|
|
187
|
+
user = uow.users.get_by_id(1)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
See also:
|
|
191
|
+
|
|
192
|
+
- Design principles and patterns: https://alpha-python.readthedocs.io/en/latest/concepts/design-principles/
|
|
193
|
+
- Dependency injection concept: https://alpha-python.readthedocs.io/en/latest/concepts/dependency-injection/
|
|
194
|
+
- API code generation guide: https://alpha-python.readthedocs.io/en/latest/guides/api-generation/
|
|
195
|
+
- Authentication guide: https://alpha-python.readthedocs.io/en/latest/guides/authentication/
|
|
196
|
+
- Database interaction guide: https://alpha-python.readthedocs.io/en/latest/guides/database-interaction/
|
|
197
|
+
|
|
198
|
+
## Contributing
|
|
199
|
+
|
|
200
|
+
If you want to contribute to the development of this library, you can fork the repository and create a pull request with your changes.
|
|
201
|
+
|
|
202
|
+
## Support
|
|
203
|
+
|
|
204
|
+
If Alpha saves you time in production, consider supporting development by buying me a coffee! Your support helps me to continue improving the library and adding new features. Thank you!
|
|
205
|
+
|
|
206
|
+
<a href="https://www.buymeacoffee.com/breijling"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=breijling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" /></a>
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
This library is licensed under the MIT License. See the LICENSE file for more information.
|
|
@@ -0,0 +1,153 @@
|
|
|
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://pypistats.org/packages/alpha-python)
|
|
9
|
+
[](https://github.com/breijling/alpha/actions/workflows/python-app.yml)
|
|
10
|
+
[](https://pypi.org/project/alpha-python)
|
|
11
|
+
[](https://coveralls.io/github/BReijling/alpha?branch=main)
|
|
12
|
+
[](https://docs.astral.sh/uv/)
|
|
13
|
+
[](https://mypy-lang.org/)
|
|
14
|
+
[](https://docs.pytest.org/)
|
|
15
|
+
[](https://www.python.org/dev/peps/pep-0008/)
|
|
16
|
+
[](https://github.com/astral-sh/ruff)
|
|
17
|
+
[](https://alpha-python.readthedocs.io/en/latest/)
|
|
18
|
+
[](https://choosealicense.com/licenses/mit/)
|
|
19
|
+
[](https://github.com/sponsors/BReijling)
|
|
20
|
+
|
|
21
|
+
## TL;DR
|
|
22
|
+
|
|
23
|
+
Alpha provides a comprehensive set of tools for building Python applications that interact with APIs and databases, including API code generation, authentication and authorization, database access layers, error handling, logging, and more. It is designed to be the first dependency you add to your project, providing a solid foundation for your application's architecture.
|
|
24
|
+
|
|
25
|
+
## Documentation
|
|
26
|
+
|
|
27
|
+
Full documentation is available at [alpha-python.readthedocs.io](https://alpha-python.readthedocs.io/).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
The library is still in development, but you can already install it using pip:
|
|
32
|
+
|
|
33
|
+
```shell
|
|
34
|
+
pip install alpha-python
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If you want to use the alpha cli for generating API code, you can install it using pip as well:
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
pip install alpha-python[api-generator]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If you want to add the library to your API project, you can add it to your pyproject.toml file:
|
|
44
|
+
|
|
45
|
+
```shell
|
|
46
|
+
# Poetry example
|
|
47
|
+
poetry add alpha-python --extras "flask, postgresql"
|
|
48
|
+
poetry add --dev alpha-python --extras "api-generator"
|
|
49
|
+
|
|
50
|
+
# UV example
|
|
51
|
+
uv add alpha-python --extra flask --extra postgresql
|
|
52
|
+
uv add --dev alpha-python --extra api-generator
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- API code generation
|
|
58
|
+
- Authentication and authorization
|
|
59
|
+
- Database interaction
|
|
60
|
+
- Logging
|
|
61
|
+
- Error handling
|
|
62
|
+
- And much more!
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
The library contains many components. Below are a few practical examples that map to the guides in the documentation.
|
|
67
|
+
|
|
68
|
+
### 1) API code generation using OpenAPI spec
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
alpha api gen --spec-file specification/openapi.yaml --service-package my_app
|
|
72
|
+
|
|
73
|
+
alpha api run --port 8080
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2) Authenticate with Keycloak (OIDC)
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from alpha import KeyCloakOIDCConnector, KeyCloakProvider, PasswordCredentials
|
|
80
|
+
|
|
81
|
+
keycloak_connector = KeyCloakOIDCConnector(
|
|
82
|
+
base_url="https://keycloak.example.com",
|
|
83
|
+
realm="myrealm",
|
|
84
|
+
client_id="myclient",
|
|
85
|
+
client_secret="myclientsecret",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
keycloak_provider = KeyCloakProvider(connector=keycloak_connector)
|
|
89
|
+
|
|
90
|
+
credentials = PasswordCredentials(username="user1", password="user1_password")
|
|
91
|
+
identity = keycloak_provider.authenticate(credentials)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 3) Query data using SqlAlchemyDatabase + SqlAlchemyRepository
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from alpha import SqlAlchemyDatabase, SqlAlchemyRepository
|
|
98
|
+
from my_app import User
|
|
99
|
+
|
|
100
|
+
db = SqlAlchemyDatabase(conn_str="postgresql://user:password@localhost:5432/mydatabase")
|
|
101
|
+
|
|
102
|
+
with db.get_session() as session:
|
|
103
|
+
users = SqlAlchemyRepository[User](session=session, default_model=User)
|
|
104
|
+
user = users.get_by_id(1)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 4) Use Unit of Work for transactional operations
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from alpha import (
|
|
111
|
+
RepositoryModel,
|
|
112
|
+
SqlAlchemyDatabase,
|
|
113
|
+
SqlAlchemyRepository,
|
|
114
|
+
SqlAlchemyUnitOfWork,
|
|
115
|
+
)
|
|
116
|
+
from my_app import User, OrmMapper
|
|
117
|
+
|
|
118
|
+
db = SqlAlchemyDatabase(..., mapper=OrmMapper)
|
|
119
|
+
repositories = [
|
|
120
|
+
RepositoryModel(
|
|
121
|
+
name="users",
|
|
122
|
+
repository=SqlAlchemyRepository[User],
|
|
123
|
+
default_model=User,
|
|
124
|
+
)
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
uow = SqlAlchemyUnitOfWork(db=db, repos=repositories)
|
|
128
|
+
|
|
129
|
+
with uow:
|
|
130
|
+
user = uow.users.get_by_id(1)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See also:
|
|
134
|
+
|
|
135
|
+
- Design principles and patterns: https://alpha-python.readthedocs.io/en/latest/concepts/design-principles/
|
|
136
|
+
- Dependency injection concept: https://alpha-python.readthedocs.io/en/latest/concepts/dependency-injection/
|
|
137
|
+
- API code generation guide: https://alpha-python.readthedocs.io/en/latest/guides/api-generation/
|
|
138
|
+
- Authentication guide: https://alpha-python.readthedocs.io/en/latest/guides/authentication/
|
|
139
|
+
- Database interaction guide: https://alpha-python.readthedocs.io/en/latest/guides/database-interaction/
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
If you want to contribute to the development of this library, you can fork the repository and create a pull request with your changes.
|
|
144
|
+
|
|
145
|
+
## Support
|
|
146
|
+
|
|
147
|
+
If Alpha saves you time in production, consider supporting development by buying me a coffee! Your support helps me to continue improving the library and adding new features. Thank you!
|
|
148
|
+
|
|
149
|
+
<a href="https://www.buymeacoffee.com/breijling"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=breijling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" /></a>
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
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.6.
|
|
3
|
+
version = "0.6.1"
|
|
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 = [
|
|
@@ -80,7 +80,10 @@ dev = [
|
|
|
80
80
|
"ipykernel>=7.2.0",
|
|
81
81
|
"flask<2",
|
|
82
82
|
"httpx>=0.28.1",
|
|
83
|
-
"tox>=4.
|
|
83
|
+
"tox>=4.0.0",
|
|
84
|
+
"types-ldap3",
|
|
85
|
+
"types-requests",
|
|
86
|
+
"pandas-stubs",
|
|
84
87
|
]
|
|
85
88
|
# docs = [
|
|
86
89
|
# "mkdocs-material>=9.5",
|
|
@@ -156,7 +159,8 @@ source = ["src"]
|
|
|
156
159
|
omit = [
|
|
157
160
|
"tests/*",
|
|
158
161
|
"__init__.py",
|
|
159
|
-
"_http_codes.py"
|
|
162
|
+
"_http_codes.py",
|
|
163
|
+
"src/alpha/utils/openapi_test/*"
|
|
160
164
|
]
|
|
161
165
|
|
|
162
166
|
[tool.black]
|
|
@@ -172,10 +176,13 @@ force_grid_wrap = 0
|
|
|
172
176
|
|
|
173
177
|
[tool.mypy]
|
|
174
178
|
python_version = "3.11"
|
|
175
|
-
exclude = [
|
|
179
|
+
exclude = ["^tests/", "src/alpha/utils/openapi_test"]
|
|
176
180
|
|
|
177
181
|
[[tool.mypy.overrides]]
|
|
178
|
-
module = [
|
|
182
|
+
module = [
|
|
183
|
+
"flask",
|
|
184
|
+
"flask.*",
|
|
185
|
+
]
|
|
179
186
|
ignore_missing_imports = true
|
|
180
187
|
|
|
181
188
|
[tool.ruff]
|
|
@@ -20,18 +20,18 @@ def main(sections: list[Section] = Provide[Container.sections]) -> None:
|
|
|
20
20
|
|
|
21
21
|
# Create the main parser
|
|
22
22
|
parser = argparse.ArgumentParser(
|
|
23
|
-
description=
|
|
23
|
+
description="Alpha command line interface.",
|
|
24
24
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
25
25
|
)
|
|
26
26
|
subparsers = parser.add_subparsers(
|
|
27
|
-
title=
|
|
28
|
-
dest=
|
|
27
|
+
title="Use one of the sub categories to run commands on",
|
|
28
|
+
dest="section",
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
# Parser dict to store in all parsers to match later on when finding a
|
|
32
32
|
# handler.
|
|
33
|
-
section_parsers = {}
|
|
34
|
-
command_parsers = {}
|
|
33
|
+
section_parsers: dict[str, argparse.ArgumentParser] = {}
|
|
34
|
+
command_parsers: dict[str, dict[str, argparse.ArgumentParser]] = {}
|
|
35
35
|
|
|
36
36
|
# Create all sections
|
|
37
37
|
for section in sections:
|
|
@@ -43,7 +43,7 @@ def main(sections: list[Section] = Provide[Container.sections]) -> None:
|
|
|
43
43
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
44
44
|
)
|
|
45
45
|
section_subparser = section_parsers[section.name].add_subparsers(
|
|
46
|
-
dest=
|
|
46
|
+
dest="command"
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
# Create all commands per section
|
|
@@ -88,8 +88,8 @@ def main(sections: list[Section] = Provide[Container.sections]) -> None:
|
|
|
88
88
|
# Get all arguments and remove the section and command so they can be
|
|
89
89
|
# 'kwarged' into the Handler set_arguments function.
|
|
90
90
|
handler_args = vars(args)
|
|
91
|
-
del handler_args[
|
|
92
|
-
del handler_args[
|
|
91
|
+
del handler_args["section"]
|
|
92
|
+
del handler_args["command"]
|
|
93
93
|
|
|
94
94
|
# Find the right handler
|
|
95
95
|
for section in sections:
|
|
@@ -102,7 +102,7 @@ def main(sections: list[Section] = Provide[Container.sections]) -> None:
|
|
|
102
102
|
command.handler.handle_command()
|
|
103
103
|
return
|
|
104
104
|
|
|
105
|
-
print(
|
|
105
|
+
print("No handler found, you should never read this")
|
|
106
106
|
return
|
|
107
107
|
|
|
108
108
|
|
|
@@ -118,53 +118,57 @@ def _guess_current_package_name() -> str:
|
|
|
118
118
|
"""
|
|
119
119
|
|
|
120
120
|
cwd = os.getcwd()
|
|
121
|
-
pyproject_path = os.path.join(cwd,
|
|
121
|
+
pyproject_path = os.path.join(cwd, "pyproject.toml")
|
|
122
122
|
|
|
123
123
|
# look for pyproject.toml file in subfolders
|
|
124
124
|
if not os.path.isfile(pyproject_path):
|
|
125
125
|
for entry in os.scandir(cwd):
|
|
126
126
|
if not entry.is_dir():
|
|
127
127
|
continue
|
|
128
|
-
possible_path = os.path.join(entry.path,
|
|
128
|
+
possible_path = os.path.join(entry.path, "pyproject.toml")
|
|
129
129
|
if os.path.isfile(possible_path):
|
|
130
130
|
pyproject_path = possible_path
|
|
131
131
|
break
|
|
132
132
|
|
|
133
133
|
if os.path.isfile(pyproject_path):
|
|
134
134
|
try:
|
|
135
|
-
with open(pyproject_path,
|
|
135
|
+
with open(pyproject_path, "rb") as f:
|
|
136
136
|
pyproject_data = tomllib.load(f)
|
|
137
137
|
name = None
|
|
138
138
|
try:
|
|
139
|
-
if
|
|
140
|
-
name = pyproject_data[
|
|
141
|
-
elif
|
|
142
|
-
|
|
139
|
+
if "project" in pyproject_data:
|
|
140
|
+
name = pyproject_data["project"]["name"]
|
|
141
|
+
elif (
|
|
142
|
+
"tool" in pyproject_data
|
|
143
|
+
and "poetry" in pyproject_data["tool"]
|
|
144
|
+
):
|
|
145
|
+
name = pyproject_data["tool"]["poetry"]["name"]
|
|
143
146
|
if name is not None:
|
|
144
|
-
return name.replace(
|
|
147
|
+
return name.replace("-", "_")
|
|
145
148
|
except KeyError:
|
|
146
|
-
print(
|
|
149
|
+
print("Could not find project name in pyproject.toml")
|
|
147
150
|
except Exception:
|
|
148
151
|
pass
|
|
149
152
|
else:
|
|
150
|
-
print(
|
|
153
|
+
print("Could not find pyproject.toml")
|
|
151
154
|
|
|
152
155
|
# Fallback to use the current folder name
|
|
153
|
-
print(
|
|
156
|
+
print("Guessing package name from folder")
|
|
154
157
|
return os.path.basename(cwd)
|
|
155
158
|
|
|
159
|
+
|
|
156
160
|
def init() -> None:
|
|
157
161
|
"""Init the container and wire it to the main function."""
|
|
158
162
|
container = Container()
|
|
159
163
|
guessed_name = _guess_current_package_name()
|
|
160
164
|
if guessed_name:
|
|
161
|
-
container.config.api_package_name.from_value(f
|
|
165
|
+
container.config.api_package_name.from_value(f"{guessed_name}_api")
|
|
162
166
|
container.config.service_package_name.from_value(guessed_name)
|
|
163
167
|
container.config.container_import.from_value(
|
|
164
|
-
f
|
|
168
|
+
f"from {guessed_name}.containers.container import Container"
|
|
165
169
|
)
|
|
166
170
|
container.config.init_container_from.from_value(guessed_name)
|
|
167
|
-
container.config.init_container_function.from_value(
|
|
171
|
+
container.config.init_container_function.from_value("init_container")
|
|
168
172
|
container.wire(modules=[sys.modules[__name__]])
|
|
169
173
|
|
|
170
174
|
main()
|
|
@@ -10,9 +10,10 @@ from json import encoder
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
from uuid import UUID
|
|
12
12
|
|
|
13
|
-
import numpy as np
|
|
14
|
-
import pandas as pd
|
|
15
|
-
import six
|
|
13
|
+
import numpy as np # type: ignore[import-untyped]
|
|
14
|
+
import pandas as pd # type: ignore[import-untyped]
|
|
15
|
+
import six # type: ignore[import-untyped]
|
|
16
|
+
|
|
16
17
|
|
|
17
18
|
from alpha.interfaces.openapi_model import OpenAPIModel
|
|
18
19
|
|
|
@@ -34,7 +34,10 @@ class JWTFactory:
|
|
|
34
34
|
Parameters
|
|
35
35
|
----------
|
|
36
36
|
secret
|
|
37
|
-
The secret key used to sign the JWT.
|
|
37
|
+
The secret key used to sign the JWT. A secret value should be a
|
|
38
|
+
minimum of 32 characters for security reasons. This value should be
|
|
39
|
+
kept confidential and not exposed in the source code or version
|
|
40
|
+
control system.
|
|
38
41
|
lifetime_hours
|
|
39
42
|
The lifetime of the JWT in hours, by default None. This parameter
|
|
40
43
|
is ignored if lifetime_seconds is provided. The parameter is
|
|
@@ -71,13 +74,13 @@ class JWTFactory:
|
|
|
71
74
|
stacklevel=2,
|
|
72
75
|
)
|
|
73
76
|
|
|
74
|
-
if lifetime_seconds is None and lifetime_hours is None:
|
|
75
|
-
lifetime_seconds = (
|
|
76
|
-
900 # Default to 15 minutes if no lifetime is provided
|
|
77
|
-
)
|
|
78
|
-
elif lifetime_seconds is None and lifetime_hours is not None:
|
|
77
|
+
if lifetime_seconds is None and lifetime_hours is not None:
|
|
79
78
|
lifetime_seconds = 3600 * int(lifetime_hours)
|
|
80
79
|
|
|
80
|
+
lifetime_seconds = (
|
|
81
|
+
900 if lifetime_seconds is None else lifetime_seconds
|
|
82
|
+
) # Default to 15 minutes if no lifetime is provided
|
|
83
|
+
|
|
81
84
|
self.JWT_SECRET: str = secret
|
|
82
85
|
self.JWT_ISSUER = issuer
|
|
83
86
|
self.JWT_ALGORITHM = jwt_algorithm
|
|
@@ -113,7 +116,7 @@ class JWTFactory:
|
|
|
113
116
|
The generated JWT token as a string.
|
|
114
117
|
"""
|
|
115
118
|
now = datetime.now(tz=timezone.utc)
|
|
116
|
-
exp = now + timedelta(seconds=self.JWT_LIFETIME_SECONDS)
|
|
119
|
+
exp = now + timedelta(seconds=float(self.JWT_LIFETIME_SECONDS))
|
|
117
120
|
|
|
118
121
|
token_payload: dict[str, Any] = {
|
|
119
122
|
"sub": subject,
|
|
@@ -11,6 +11,11 @@ from alpha import exceptions
|
|
|
11
11
|
class PasswordFactory:
|
|
12
12
|
"""This class provides methods for hashing and verifying passwords using
|
|
13
13
|
the argon2 library.
|
|
14
|
+
|
|
15
|
+
Keep in mind that changing the password hasher in a production environment
|
|
16
|
+
may lead to issues with existing password hashes, so it is recommended to
|
|
17
|
+
use the default hasher unless you have specific requirements. Or configure
|
|
18
|
+
the password hasher before you deploy your application to production.
|
|
14
19
|
"""
|
|
15
20
|
|
|
16
21
|
def __init__(
|
|
@@ -22,7 +27,9 @@ class PasswordFactory:
|
|
|
22
27
|
----------
|
|
23
28
|
password_hasher
|
|
24
29
|
An optional password hasher instance. If not provided, a default
|
|
25
|
-
argon2.PasswordHasher with a salt length of 16 will be used.
|
|
30
|
+
argon2.PasswordHasher with a salt length of 16 will be used. This
|
|
31
|
+
allows for flexibility in case you want to use a custom password
|
|
32
|
+
hasher.
|
|
26
33
|
"""
|
|
27
34
|
self._password_hasher = password_hasher or argon2.PasswordHasher(
|
|
28
35
|
salt_len=16
|
|
@@ -187,6 +187,11 @@ class ApiGenerateHandler(BaseHandler):
|
|
|
187
187
|
"""Copy mustache templates to the templates folder in the working
|
|
188
188
|
directory
|
|
189
189
|
"""
|
|
190
|
+
if self.generator_name is None:
|
|
191
|
+
raise InvalidArgumentsException(
|
|
192
|
+
"Generator name is required to copy templates."
|
|
193
|
+
)
|
|
194
|
+
|
|
190
195
|
shutil.rmtree(self.project_templates_folder, ignore_errors=True)
|
|
191
196
|
shutil.copytree(
|
|
192
197
|
src=os.path.join(
|