alpha-python 0.1.0__tar.gz → 0.2.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.1.0/src/alpha_python.egg-info → alpha_python-0.2.1}/PKG-INFO +22 -1
- {alpha_python-0.1.0 → alpha_python-0.2.1}/pyproject.toml +51 -1
- alpha_python-0.2.1/src/alpha/__init__.py +14 -0
- alpha_python-0.2.1/src/alpha/cli.py +147 -0
- alpha_python-0.2.1/src/alpha/containers/container.py +190 -0
- alpha_python-0.2.1/src/alpha/domain/models/__init__.py +2 -0
- alpha_python-0.2.1/src/alpha/domain/models/life_cycle_base.py +10 -0
- alpha_python-0.2.1/src/alpha/domain/models/user.py +66 -0
- alpha_python-0.2.1/src/alpha/exceptions.py +182 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/field_iterator.py +39 -3
- alpha_python-0.2.1/src/alpha/factories/jwt_factory.py +133 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/model_class_factory.py +7 -7
- alpha_python-0.2.1/src/alpha/handlers/api_generate_handler.py +216 -0
- alpha_python-0.2.1/src/alpha/handlers/api_run_handler.py +48 -0
- alpha_python-0.2.1/src/alpha/handlers/base_handler.py +18 -0
- alpha_python-0.2.1/src/alpha/handlers/gen-code.sh +28 -0
- alpha_python-0.2.1/src/alpha/handlers/models/argument.py +14 -0
- alpha_python-0.2.1/src/alpha/handlers/models/command.py +15 -0
- alpha_python-0.2.1/src/alpha/handlers/models/section.py +12 -0
- alpha_python-0.2.1/src/alpha/handlers/models/subparser.py +11 -0
- alpha_python-0.2.1/src/alpha/handlers/run-api.sh +12 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/Dockerfile.mustache +21 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/README.mustache +60 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/__init__model.mustache +7 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/__init__test.mustache +16 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/__main__.mustache +82 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/base_model.mustache +73 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/controller.mustache +331 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/controller_test.mustache +57 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/dockerignore.mustache +75 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/encoder.mustache +29 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/git_push.sh.mustache +57 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/gitignore.mustache +66 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/model.mustache +173 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/openapi.mustache +1 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/param_type.mustache +1 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/requirements.mustache +19 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/security_controller_.mustache +89 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/setup.mustache +52 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/test-requirements.mustache +13 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/tox.mustache +11 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/travis.mustache +17 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/typing_utils.mustache +32 -0
- alpha_python-0.2.1/src/alpha/handlers/templates/python-flask/util.mustache +148 -0
- alpha_python-0.2.1/src/alpha/infra/connectors/ldap_connector.py +124 -0
- alpha_python-0.1.0/src/alpha/infra/database/sql_alchemy_database.py → alpha_python-0.2.1/src/alpha/infra/databases/sql_alchemy.py +42 -39
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/infra/models/filter_operators.py +3 -3
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/infra/models/json_patch.py +2 -4
- alpha_python-0.2.1/src/alpha/interfaces/handler.py +18 -0
- alpha_python-0.2.1/src/alpha/interfaces/providers.py +174 -0
- alpha_python-0.2.1/src/alpha/interfaces/pydantic_instance.py +9 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/token_factory.py +14 -5
- alpha_python-0.2.1/src/alpha/mixins/jwt_provider.py +69 -0
- alpha_python-0.2.1/src/alpha/providers/api_key_provider.py +0 -0
- alpha_python-0.2.1/src/alpha/providers/database_provider.py +12 -0
- alpha_python-0.2.1/src/alpha/providers/keycloak_provider.py +16 -0
- alpha_python-0.2.1/src/alpha/providers/ldap_provider.py +254 -0
- alpha_python-0.2.1/src/alpha/providers/local_provider.py +0 -0
- alpha_python-0.2.1/src/alpha/providers/models/__init__.py +0 -0
- alpha_python-0.2.1/src/alpha/providers/models/credentials.py +21 -0
- alpha_python-0.2.1/src/alpha/providers/models/identity.py +344 -0
- alpha_python-0.2.1/src/alpha/providers/models/token.py +7 -0
- alpha_python-0.2.1/src/alpha/py.typed +0 -0
- alpha_python-0.2.1/src/alpha/repositories/__init__.py +0 -0
- alpha_python-0.2.1/src/alpha/repositories/models/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/repositories/models/repository_model.py +2 -2
- alpha_python-0.1.0/src/alpha/repositories/default_sql_repository.py → alpha_python-0.2.1/src/alpha/repositories/sql_alchemy_repository.py +5 -5
- alpha_python-0.2.1/src/alpha/services/__init__.py +0 -0
- alpha_python-0.2.1/src/alpha/services/authentication_service.py +194 -0
- alpha_python-0.2.1/src/alpha/utils/__init__.py +0 -0
- alpha_python-0.2.1/src/alpha/utils/is_pydantic.py +18 -0
- alpha_python-0.2.1/src/alpha/utils/verify_identity.py +64 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1/src/alpha_python.egg-info}/PKG-INFO +22 -1
- alpha_python-0.2.1/src/alpha_python.egg-info/SOURCES.txt +126 -0
- alpha_python-0.2.1/src/alpha_python.egg-info/entry_points.txt +2 -0
- alpha_python-0.2.1/src/alpha_python.egg-info/requires.txt +35 -0
- alpha_python-0.1.0/src/alpha/exceptions.py +0 -99
- alpha_python-0.1.0/src/alpha/infra/database/sql_alchemy_view.py +0 -48
- alpha_python-0.1.0/src/alpha/services/authentication_service.py +0 -71
- alpha_python-0.1.0/src/alpha_python.egg-info/SOURCES.txt +0 -66
- alpha_python-0.1.0/src/alpha_python.egg-info/requires.txt +0 -9
- {alpha_python-0.1.0 → alpha_python-0.2.1}/LICENSE +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/README.md +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/setup.cfg +0 -0
- {alpha_python-0.1.0/src/alpha → alpha_python-0.2.1/src/alpha/adapters}/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/adapters/sqla_unit_of_work.py +0 -0
- {alpha_python-0.1.0/src/alpha/adapters → alpha_python-0.2.1/src/alpha/containers}/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/domain/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/domain/models/base_model.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/encoder.py +0 -0
- {alpha_python-0.1.0/src/alpha/domain/models → alpha_python-0.2.1/src/alpha/factories}/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/_type_conversion_matrix.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/_type_mapping.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/class_factories.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/default_field_factory.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/logging_handler_factory.py +0 -0
- {alpha_python-0.1.0/src/alpha/factories → alpha_python-0.2.1/src/alpha/factories/models}/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/models/factory_classes.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/request_factory.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/response_factory.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/factories/type_factories.py +0 -0
- {alpha_python-0.1.0/src/alpha/factories/models → alpha_python-0.2.1/src/alpha/handlers}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/infra → alpha_python-0.2.1/src/alpha/handlers/models}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/infra/database → alpha_python-0.2.1/src/alpha/handlers/templates}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/infra/models → alpha_python-0.2.1/src/alpha/infra}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/interfaces → alpha_python-0.2.1/src/alpha/infra/connectors}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/repositories → alpha_python-0.2.1/src/alpha/infra/databases}/__init__.py +0 -0
- {alpha_python-0.1.0/src/alpha/repositories → alpha_python-0.2.1/src/alpha/infra}/models/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/infra/models/order_by.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/infra/models/query_clause.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/infra/models/search_filter.py +0 -0
- {alpha_python-0.1.0/src/alpha/services → alpha_python-0.2.1/src/alpha/interfaces}/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/attrs_instance.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/dataclass_instance.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/factories.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/openapi_model.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/patchable.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/sql_database.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/sql_mapper.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/sql_repository.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/unit_of_work.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/interfaces/updateable.py +0 -0
- {alpha_python-0.1.0/src/alpha/utils → alpha_python-0.2.1/src/alpha/mixins}/__init__.py +0 -0
- /alpha_python-0.1.0/src/alpha/py.typed → /alpha_python-0.2.1/src/alpha/providers/__init__.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/_http_codes.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/is_attrs.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/logging_configurator.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/logging_level_checker.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/response_object.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha/utils/version_check.py +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha_python.egg-info/dependency_links.txt +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/src/alpha_python.egg-info/top_level.txt +0 -0
- {alpha_python-0.1.0 → alpha_python-0.2.1}/tests/test_encoder.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpha-python
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
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
|
|
@@ -15,6 +15,27 @@ Requires-Dist: pydantic>=2.12.5
|
|
|
15
15
|
Requires-Dist: pyjwt>=2.10.1
|
|
16
16
|
Requires-Dist: six>=1.17.0
|
|
17
17
|
Requires-Dist: sqlalchemy>=2.0.44
|
|
18
|
+
Requires-Dist: requests>=2.28.1
|
|
19
|
+
Requires-Dist: dependency-injector<5.0.0,>=4.48.3
|
|
20
|
+
Provides-Extra: api-generator
|
|
21
|
+
Requires-Dist: openapi-generator-cli==7.14.0; extra == "api-generator"
|
|
22
|
+
Requires-Dist: jdk4py; extra == "api-generator"
|
|
23
|
+
Provides-Extra: flask
|
|
24
|
+
Requires-Dist: connexion[swagger-ui]<3,>=2.14.2; extra == "flask"
|
|
25
|
+
Requires-Dist: swagger-ui-bundle>=0.0.2; extra == "flask"
|
|
26
|
+
Requires-Dist: python_dateutil>=2.6.0; extra == "flask"
|
|
27
|
+
Requires-Dist: itsdangerous==1.1.0; extra == "flask"
|
|
28
|
+
Requires-Dist: MarkupSafe<2.0.2; extra == "flask"
|
|
29
|
+
Requires-Dist: Jinja2==2.11.2; extra == "flask"
|
|
30
|
+
Requires-Dist: Flask<2,>=1.1.2; extra == "flask"
|
|
31
|
+
Requires-Dist: flask-cors>=3.0.10; extra == "flask"
|
|
32
|
+
Requires-Dist: Flask-Compress>=1.13; extra == "flask"
|
|
33
|
+
Provides-Extra: mysql
|
|
34
|
+
Requires-Dist: pymysql>=1.1.2; extra == "mysql"
|
|
35
|
+
Provides-Extra: postgresql
|
|
36
|
+
Requires-Dist: psycopg2-binary>=2.9.11; extra == "postgresql"
|
|
37
|
+
Provides-Extra: ldap
|
|
38
|
+
Requires-Dist: ldap3>=2.9.1; extra == "ldap"
|
|
18
39
|
Dynamic: license-file
|
|
19
40
|
|
|
20
41
|
# alpha
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "alpha-python"
|
|
3
|
-
version = "0.1
|
|
3
|
+
version = "0.2.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 = [
|
|
@@ -17,6 +17,26 @@ dependencies = [
|
|
|
17
17
|
"pyjwt>=2.10.1",
|
|
18
18
|
"six>=1.17.0",
|
|
19
19
|
"sqlalchemy>=2.0.44",
|
|
20
|
+
"requests>=2.28.1",
|
|
21
|
+
"dependency-injector (>=4.48.3,<5.0.0)",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
alpha = "alpha.cli:init"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.package-dir]
|
|
28
|
+
"" = "src"
|
|
29
|
+
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
where = ["src"]
|
|
32
|
+
|
|
33
|
+
[tool.setuptools]
|
|
34
|
+
include-package-data = true
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.package-data]
|
|
37
|
+
"alpha.handlers" = [
|
|
38
|
+
"**/*.mustache",
|
|
39
|
+
"*.sh",
|
|
20
40
|
]
|
|
21
41
|
|
|
22
42
|
[build-system]
|
|
@@ -32,6 +52,36 @@ dev = [
|
|
|
32
52
|
"pytest>=9.0.1",
|
|
33
53
|
"pytest-cov>=7.0.0",
|
|
34
54
|
"ruff>=0.14.7",
|
|
55
|
+
"psycopg2-binary>=2.9.11",
|
|
56
|
+
"pymysql>=1.1.2",
|
|
57
|
+
"ldap3>=2.9.1",
|
|
58
|
+
"cryptography>=46.0.3"
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[project.optional-dependencies]
|
|
62
|
+
api-generator = [
|
|
63
|
+
"openapi-generator-cli==7.14.0",
|
|
64
|
+
"jdk4py"
|
|
65
|
+
]
|
|
66
|
+
flask = [
|
|
67
|
+
"connexion[swagger-ui]>=2.14.2,<3",
|
|
68
|
+
"swagger-ui-bundle>=0.0.2",
|
|
69
|
+
"python_dateutil>=2.6.0",
|
|
70
|
+
"itsdangerous==1.1.0",
|
|
71
|
+
"MarkupSafe<2.0.2",
|
|
72
|
+
"Jinja2==2.11.2",
|
|
73
|
+
"Flask>=1.1.2,<2",
|
|
74
|
+
"flask-cors>=3.0.10",
|
|
75
|
+
"Flask-Compress>=1.13",
|
|
76
|
+
]
|
|
77
|
+
mysql = [
|
|
78
|
+
"pymysql>=1.1.2"
|
|
79
|
+
]
|
|
80
|
+
postgresql = [
|
|
81
|
+
"psycopg2-binary>=2.9.11"
|
|
82
|
+
]
|
|
83
|
+
ldap = [
|
|
84
|
+
"ldap3>=2.9.1"
|
|
35
85
|
]
|
|
36
86
|
|
|
37
87
|
[tool.pytest.ini_options]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from alpha.containers.container import Container
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def init_container() -> Container:
|
|
7
|
+
"""Initialize the alpha package container."""
|
|
8
|
+
CONFIG_PATH = os.getenv("CONFIG_PATH", "./config.yaml")
|
|
9
|
+
|
|
10
|
+
container = Container()
|
|
11
|
+
container.config.from_yaml(CONFIG_PATH)
|
|
12
|
+
|
|
13
|
+
container.wire(modules=[__name__])
|
|
14
|
+
return container
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from dependency_injector.wiring import Provide, inject
|
|
5
|
+
|
|
6
|
+
from alpha.containers.container import Container
|
|
7
|
+
from alpha.handlers.models.section import Section
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@inject
|
|
11
|
+
def main(sections: list[Section] = Provide[Container.sections]) -> None:
|
|
12
|
+
"""Entry point for the alpha cli.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
sections: List[Section]
|
|
17
|
+
List of sections to include in the cli.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# Create the main parser
|
|
21
|
+
parser = argparse.ArgumentParser(
|
|
22
|
+
description='Alpha command line interface.',
|
|
23
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
24
|
+
)
|
|
25
|
+
subparsers = parser.add_subparsers(
|
|
26
|
+
title='Use one of the sub categories to run commands on',
|
|
27
|
+
dest='section',
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Parser dict to store in all parsers to match later on when finding a
|
|
31
|
+
# handler.
|
|
32
|
+
section_parsers = {}
|
|
33
|
+
command_parsers = {}
|
|
34
|
+
|
|
35
|
+
# Create all sections
|
|
36
|
+
for section in sections:
|
|
37
|
+
command_parsers[section.name] = {}
|
|
38
|
+
section_parsers[section.name] = subparsers.add_parser(
|
|
39
|
+
section.name,
|
|
40
|
+
description=section.description,
|
|
41
|
+
help=section.help,
|
|
42
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
43
|
+
)
|
|
44
|
+
section_subparser = section_parsers[section.name].add_subparsers(
|
|
45
|
+
dest='command'
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Create all commands per section
|
|
49
|
+
for command in section.commands:
|
|
50
|
+
command_parsers[section.name][command.name] = (
|
|
51
|
+
section_subparser.add_parser(
|
|
52
|
+
command.name,
|
|
53
|
+
help=command.help,
|
|
54
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Add all arguments for a command
|
|
59
|
+
for argument in command.arguments:
|
|
60
|
+
command_parsers[section.name][command.name].add_argument(
|
|
61
|
+
argument.name,
|
|
62
|
+
help=argument.help,
|
|
63
|
+
default=argument.default,
|
|
64
|
+
**argument.args,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Do the handling for the given section and command in the CLI
|
|
68
|
+
section_argument = None
|
|
69
|
+
command_argument = None
|
|
70
|
+
args = parser.parse_args()
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
section_argument = args.section
|
|
74
|
+
command_argument = args.command
|
|
75
|
+
except AttributeError:
|
|
76
|
+
parser.print_help()
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
if not section_argument:
|
|
80
|
+
# Can not occur, but just in case. Should be handled above
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if not command_argument:
|
|
84
|
+
section_parsers[section_argument].print_help()
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
# Get all arguments and remove the section and command so they can be
|
|
88
|
+
# 'kwarged' into the Handler set_arguments function.
|
|
89
|
+
handler_args = vars(args)
|
|
90
|
+
del handler_args['section']
|
|
91
|
+
del handler_args['command']
|
|
92
|
+
|
|
93
|
+
# Find the right handler
|
|
94
|
+
for section in sections:
|
|
95
|
+
for command in section.commands:
|
|
96
|
+
if (
|
|
97
|
+
section.name == section_argument
|
|
98
|
+
and command.name == command_argument
|
|
99
|
+
):
|
|
100
|
+
command.handler.set_arguments(**handler_args)
|
|
101
|
+
command.handler.handle_command()
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
print('No handler found, you should never read this')
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _guess_current_package_name() -> str | None:
|
|
109
|
+
"""Guess the name of the package where you are generating the API for,
|
|
110
|
+
finding the first (and only) folder in the 'src'-folder.
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
str
|
|
115
|
+
_description_
|
|
116
|
+
"""
|
|
117
|
+
cwd = os.getcwd()
|
|
118
|
+
package_location = f'{cwd}/src'
|
|
119
|
+
if not os.path.isdir(package_location):
|
|
120
|
+
return 'None'
|
|
121
|
+
package_names = [
|
|
122
|
+
name
|
|
123
|
+
for name in os.listdir(package_location)
|
|
124
|
+
if os.path.isdir(os.path.join(package_location, name))
|
|
125
|
+
and not name.startswith('.')
|
|
126
|
+
and not name.endswith('.egg-info')
|
|
127
|
+
]
|
|
128
|
+
if len(package_names) == 0:
|
|
129
|
+
return None
|
|
130
|
+
return package_names[0]
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def init() -> None:
|
|
134
|
+
"""Init the container and wire it to the main function."""
|
|
135
|
+
container = Container()
|
|
136
|
+
guessed_name = _guess_current_package_name()
|
|
137
|
+
if guessed_name:
|
|
138
|
+
container.config.api_package_name.from_value(f'{guessed_name}_api')
|
|
139
|
+
container.config.service_package_name.from_value(guessed_name)
|
|
140
|
+
container.config.container_import.from_value(
|
|
141
|
+
f'from {guessed_name}.containers.container import Container'
|
|
142
|
+
)
|
|
143
|
+
container.config.init_container_from.from_value(guessed_name)
|
|
144
|
+
container.config.init_container_function.from_value('init_container')
|
|
145
|
+
container.wire(modules=[sys.modules[__name__]])
|
|
146
|
+
|
|
147
|
+
main()
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from dependency_injector import containers, providers
|
|
2
|
+
|
|
3
|
+
from alpha.handlers.api_generate_handler import ApiGenerateHandler
|
|
4
|
+
from alpha.handlers.api_run_handler import ApiRunHandler
|
|
5
|
+
from alpha.handlers.models.command import Command
|
|
6
|
+
from alpha.handlers.models.section import Section
|
|
7
|
+
from alpha.handlers.models.argument import Argument
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Container(containers.DeclarativeContainer):
|
|
11
|
+
"""Dependency injection container for the alpha package."""
|
|
12
|
+
|
|
13
|
+
config = providers.Configuration()
|
|
14
|
+
|
|
15
|
+
api_gen_command = providers.Factory(
|
|
16
|
+
Command,
|
|
17
|
+
name='gen',
|
|
18
|
+
help=(
|
|
19
|
+
"Generate the API code and watch OpenAPI spec file. The API code "
|
|
20
|
+
"will be generated into the ./api folder."
|
|
21
|
+
),
|
|
22
|
+
handler=providers.Factory(ApiGenerateHandler),
|
|
23
|
+
arguments=providers.List(
|
|
24
|
+
providers.Factory(
|
|
25
|
+
Argument,
|
|
26
|
+
default='specification/openapi.yaml',
|
|
27
|
+
name='--spec-file',
|
|
28
|
+
help='Path to the specification file',
|
|
29
|
+
args={
|
|
30
|
+
'type': str,
|
|
31
|
+
'nargs': '?',
|
|
32
|
+
},
|
|
33
|
+
),
|
|
34
|
+
providers.Factory(
|
|
35
|
+
Argument,
|
|
36
|
+
default=config.api_package_name,
|
|
37
|
+
name='--api-package',
|
|
38
|
+
help=(
|
|
39
|
+
"Name of the API package to generate. Automatically "
|
|
40
|
+
"determined or guessed. If incorrect, "
|
|
41
|
+
"just use this argument."
|
|
42
|
+
),
|
|
43
|
+
args={
|
|
44
|
+
'type': str,
|
|
45
|
+
'nargs': '?',
|
|
46
|
+
},
|
|
47
|
+
),
|
|
48
|
+
providers.Factory(
|
|
49
|
+
Argument,
|
|
50
|
+
default=config.service_package_name,
|
|
51
|
+
name='--service-package',
|
|
52
|
+
help=(
|
|
53
|
+
"Name of the service package to use. Automatically "
|
|
54
|
+
"determined or guessed. If incorrect, "
|
|
55
|
+
"just use this argument."
|
|
56
|
+
),
|
|
57
|
+
args={
|
|
58
|
+
'type': str,
|
|
59
|
+
'nargs': '?',
|
|
60
|
+
},
|
|
61
|
+
),
|
|
62
|
+
providers.Factory(
|
|
63
|
+
Argument,
|
|
64
|
+
default=config.container_import,
|
|
65
|
+
name='--container-import',
|
|
66
|
+
help=(
|
|
67
|
+
"Name of the container to use. Automatically "
|
|
68
|
+
"determined or guessed. If incorrect, "
|
|
69
|
+
"just use this argument. When no container is used, "
|
|
70
|
+
"use empty string for this variable"
|
|
71
|
+
),
|
|
72
|
+
args={
|
|
73
|
+
'type': str,
|
|
74
|
+
'nargs': '?',
|
|
75
|
+
},
|
|
76
|
+
),
|
|
77
|
+
providers.Factory(
|
|
78
|
+
Argument,
|
|
79
|
+
default=config.init_container_from,
|
|
80
|
+
name='--init-container-from',
|
|
81
|
+
help=(
|
|
82
|
+
"Location of where the container initialize function "
|
|
83
|
+
"should be imported from."
|
|
84
|
+
),
|
|
85
|
+
args={
|
|
86
|
+
'type': str,
|
|
87
|
+
'nargs': '?',
|
|
88
|
+
},
|
|
89
|
+
),
|
|
90
|
+
providers.Factory(
|
|
91
|
+
Argument,
|
|
92
|
+
default=config.init_container_function,
|
|
93
|
+
name='--init-container-function',
|
|
94
|
+
help="Name of the container initialize function.",
|
|
95
|
+
args={
|
|
96
|
+
'type': str,
|
|
97
|
+
'nargs': '?',
|
|
98
|
+
},
|
|
99
|
+
),
|
|
100
|
+
providers.Factory(
|
|
101
|
+
Argument,
|
|
102
|
+
default='post_process.py',
|
|
103
|
+
name='--post-process-file',
|
|
104
|
+
help="Path to the post process file to use after generation",
|
|
105
|
+
args={
|
|
106
|
+
'type': str,
|
|
107
|
+
'nargs': '?',
|
|
108
|
+
},
|
|
109
|
+
),
|
|
110
|
+
providers.Factory(
|
|
111
|
+
Argument,
|
|
112
|
+
default='python-flask',
|
|
113
|
+
name='--generator-name',
|
|
114
|
+
help="Name of the openapi generator to use",
|
|
115
|
+
args={
|
|
116
|
+
'type': str,
|
|
117
|
+
'nargs': '?',
|
|
118
|
+
},
|
|
119
|
+
),
|
|
120
|
+
providers.Factory(
|
|
121
|
+
Argument,
|
|
122
|
+
default=False,
|
|
123
|
+
name='--no-watch',
|
|
124
|
+
help=(
|
|
125
|
+
"To prevent watching the spec file for changes and only "
|
|
126
|
+
"run the generation once."
|
|
127
|
+
),
|
|
128
|
+
args={
|
|
129
|
+
'action': 'store_true',
|
|
130
|
+
},
|
|
131
|
+
),
|
|
132
|
+
providers.Factory(
|
|
133
|
+
Argument,
|
|
134
|
+
default=False,
|
|
135
|
+
name='--templates-only',
|
|
136
|
+
help=(
|
|
137
|
+
"Only create a templates folder containing openapi "
|
|
138
|
+
"mustache templates in the current working directory. "
|
|
139
|
+
"Skip generation of API code."
|
|
140
|
+
),
|
|
141
|
+
args={
|
|
142
|
+
'action': 'store_true',
|
|
143
|
+
},
|
|
144
|
+
),
|
|
145
|
+
),
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
api_run_command = providers.Factory(
|
|
149
|
+
Command,
|
|
150
|
+
name='run',
|
|
151
|
+
help='Run API in development mode',
|
|
152
|
+
handler=providers.Factory(ApiRunHandler),
|
|
153
|
+
arguments=providers.List(
|
|
154
|
+
providers.Factory(
|
|
155
|
+
Argument,
|
|
156
|
+
default=config.api_package_name,
|
|
157
|
+
name='--api-package',
|
|
158
|
+
help='Name of the API package to generate',
|
|
159
|
+
args={
|
|
160
|
+
'type': str,
|
|
161
|
+
'nargs': '?',
|
|
162
|
+
},
|
|
163
|
+
),
|
|
164
|
+
providers.Factory(
|
|
165
|
+
Argument,
|
|
166
|
+
default='8080',
|
|
167
|
+
name='--port',
|
|
168
|
+
help='Port to run server on',
|
|
169
|
+
args={
|
|
170
|
+
'type': str,
|
|
171
|
+
'nargs': '?',
|
|
172
|
+
},
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
api_section = providers.Factory(
|
|
178
|
+
Section,
|
|
179
|
+
name='api',
|
|
180
|
+
description='OpenAPI development commands.',
|
|
181
|
+
help=(
|
|
182
|
+
"All commands for generating and developing an API using the "
|
|
183
|
+
"OpenAPI standards"
|
|
184
|
+
),
|
|
185
|
+
commands=providers.List(api_gen_command, api_run_command),
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
sections = providers.List(
|
|
189
|
+
api_section,
|
|
190
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
from typing import Self, 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
|
+
from alpha.providers.models.identity import Identity
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(kw_only=True)
|
|
13
|
+
class User(LifeCycleBase, BaseDomainModel):
|
|
14
|
+
id: UUID | int | str | None = None
|
|
15
|
+
username: str | None = None
|
|
16
|
+
password: str | None = None
|
|
17
|
+
role: str | None = None
|
|
18
|
+
email: str | None = None
|
|
19
|
+
phone: str | None = None
|
|
20
|
+
display_name: str | None = None
|
|
21
|
+
permissions: Sequence[str] | None = None
|
|
22
|
+
groups: Sequence[str] | None = None
|
|
23
|
+
is_active: bool = True
|
|
24
|
+
admin: bool = False
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def from_identity(cls, identity: Identity) -> Self:
|
|
28
|
+
"""Create a User instance from an Identity instance.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
identity
|
|
33
|
+
Identity object to convert.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
User instance created from the Identity.
|
|
38
|
+
"""
|
|
39
|
+
return cls(
|
|
40
|
+
id=identity.subject,
|
|
41
|
+
username=identity.username,
|
|
42
|
+
email=identity.email,
|
|
43
|
+
display_name=identity.display_name,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def update(self, obj: DomainModel) -> DomainModel:
|
|
47
|
+
"""Update the User instance with data from another User instance.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
user
|
|
52
|
+
User object to update from.
|
|
53
|
+
"""
|
|
54
|
+
if not isinstance(obj, User):
|
|
55
|
+
raise TypeError("User.update expects a User instance.")
|
|
56
|
+
|
|
57
|
+
self.username = obj.username
|
|
58
|
+
self.email = obj.email
|
|
59
|
+
self.phone = obj.phone
|
|
60
|
+
self.display_name = obj.display_name
|
|
61
|
+
self.permissions = obj.permissions
|
|
62
|
+
self.groups = obj.groups
|
|
63
|
+
self.updated_at = datetime.now(tz=timezone.utc)
|
|
64
|
+
self.is_active = obj.is_active
|
|
65
|
+
self.admin = obj.admin
|
|
66
|
+
return cast(DomainModel, self)
|