zrb 1.0.0a15__py3-none-any.whl → 1.0.0a17__py3-none-any.whl
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.
- zrb/__main__.py +3 -0
- zrb/builtin/__init__.py +2 -2
- zrb/builtin/git.py +16 -8
- zrb/builtin/git_subtree.py +7 -2
- zrb/builtin/llm/tool/rag.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_input.py +16 -0
- zrb/builtin/project/add/fastapp/fastapp_task.py +92 -0
- zrb/builtin/project/add/fastapp/fastapp_template/_zrb/entity/any_client_method.template.py +27 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/entity/module_template/service/my_entity/my_entity_usecase.py +6 -6
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/entity/module_template/service/my_entity/repository/my_entity_db_repository.py +10 -5
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/entity/module_template/service/my_entity/repository/my_entity_repository.py +5 -5
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/entity/schema.template.py +8 -0
- zrb/builtin/project/add/{fastapp_template/_zrb/entity/create_entity_task.py → fastapp/fastapp_template/_zrb/entity/task.py} +106 -42
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/input.py +1 -1
- zrb/builtin/project/add/{fastapp_template/_zrb/module/create_module_task.py → fastapp/fastapp_template/_zrb/module/task.py} +38 -31
- zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/client/any_client.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/client/api_client.py +6 -0
- zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/client/direct_client.py +2 -2
- zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/client/factory.py +3 -3
- zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/route.py +33 -0
- zrb/builtin/project/add/{fastapp_template/_zrb/main.py → fastapp/fastapp_template/_zrb/task.py} +3 -3
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/base_usecase.py +19 -6
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/config.py +1 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/client/any_client.py +10 -4
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/client/api_client.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/module/auth/client/direct_client.py +6 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/client/factory.py +3 -3
- zrb/builtin/project/add/fastapp/fastapp_template/module/auth/route.py +37 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/service/user/repository/user_db_repository.py +10 -4
- zrb/builtin/project/add/fastapp/fastapp_template/module/auth/service/user/repository/user_repository.py +43 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/service/user/user_usecase.py +10 -4
- zrb/builtin/project/add/fastapp/fastapp_template/module/gateway/route.py +43 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/requirements.txt +1 -1
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/schema/permission.py +8 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/schema/role.py +8 -0
- zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/schema/user.py +8 -0
- zrb/builtin/project/add/fastapp/fastapp_util.py +22 -0
- zrb/builtin/project/create/{create.py → project_task.py} +1 -1
- zrb/builtin/setup/asdf/asdf_helper.py +4 -8
- zrb/builtin/setup/tmux/tmux.py +7 -12
- zrb/builtin/todo.py +14 -19
- zrb/cmd/cmd_val.py +2 -2
- zrb/content_transformer/content_transformer.py +3 -4
- zrb/input/base_input.py +13 -1
- zrb/input/text_input.py +4 -4
- zrb/runner/web_controller/group_info_ui/controller.py +6 -14
- zrb/runner/web_controller/home_page/controller.py +6 -14
- zrb/runner/web_controller/task_ui/controller.py +11 -18
- zrb/session_state_logger/file_session_state_logger.py +4 -7
- zrb/task/cmd_task.py +1 -1
- zrb/task/llm_task.py +3 -5
- zrb/task/scaffolder.py +13 -1
- zrb/util/codemod/{add_code_to_class.py → append_code_to_class.py} +1 -1
- zrb/util/codemod/{add_code_to_function.py → append_code_to_function.py} +3 -1
- zrb/util/codemod/{add_code_to_method.py → append_code_to_method.py} +1 -1
- zrb/util/codemod/{add_key_to_dict.py → append_key_to_dict.py} +1 -1
- zrb/util/codemod/{add_param_to_function_call.py → append_param_to_function_call.py} +1 -1
- zrb/util/codemod/{add_code_to_module.py → prepend_code_to_module.py} +1 -1
- zrb/util/codemod/{add_parent_to_class.py → prepend_parent_to_class.py} +1 -1
- zrb/util/codemod/{add_property_to_class.py → prepend_property_to_class.py} +1 -1
- zrb/util/file.py +18 -0
- zrb/util/git_subtree.py +3 -4
- zrb/util/todo.py +5 -7
- {zrb-1.0.0a15.dist-info → zrb-1.0.0a17.dist-info}/METADATA +2 -2
- zrb-1.0.0a17.dist-info/RECORD +234 -0
- zrb/builtin/project/add/fastapp.py +0 -87
- zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/any_client.py +0 -27
- zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/api_client.py +0 -6
- zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/route.py +0 -19
- zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +0 -6
- zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
- zrb/builtin/project/add/fastapp_template/module/auth/route.py +0 -22
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/user_repository.py +0 -34
- zrb/builtin/project/add/fastapp_template/module/gateway/route.py +0 -27
- zrb-1.0.0a15.dist-info/RECORD +0 -231
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/.gitignore +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/README.md +0 -0
- /zrb/builtin/project/add/{__init__.py → fastapp/fastapp_template/__init__.py} +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/column/create_column_task.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/config.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/entity/module_template/service/my_entity/repository/factory.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/group.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/alembic.ini +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/migration/README +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/migration/env.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/migration/script.py.mako +0 -0
- /zrb/builtin/project/add/{fastapp_template/module/gateway → fastapp/fastapp_template/_zrb/module/template/module_template}/migration/versions/.gitkeep +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module → fastapp/fastapp_template/_zrb/module/template}/module_template/migration_metadata.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/_zrb/module/template/module_template/service}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module/run_module.template.py → fastapp/fastapp_template/_zrb/module/template/task_definition.py} +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/helper.py → fastapp/fastapp_template/_zrb/util.py} +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/_zrb/venv_task.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template/service → fastapp/fastapp_template/common}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/app.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/base_db_repository.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/db_engine.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/error.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/schema.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/main.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/migrate.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/common → fastapp/fastapp_template/module}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/alembic.ini +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/migration/README +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/migration/env.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/migration/script.py.mako +0 -0
- /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/module/auth}/migration/versions/3093c7336477_add_user_table.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/migration_metadata.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/module → fastapp/fastapp_template/module/auth/service}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/module/auth/service → fastapp/fastapp_template/module/auth/service/user}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template/module/auth/service/user → fastapp/fastapp_template/module/auth/service/user/repository}/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/service/user/repository/factory.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/gateway/alembic.ini +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/gateway/migration/README +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/gateway/migration/env.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/gateway/migration/script.py.mako +0 -0
- /zrb/builtin/project/add/{fastapp_template/module/auth/service/user/repository/__init__.py → fastapp/fastapp_template/module/gateway/migration/versions/.gitkeep} +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/gateway/migration_metadata.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/schema/__init__.py +0 -0
- /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/template.env +0 -0
- {zrb-1.0.0a15.dist-info → zrb-1.0.0a17.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a15.dist-info → zrb-1.0.0a17.dist-info}/entry_points.txt +0 -0
@@ -2,10 +2,11 @@ import os
|
|
2
2
|
|
3
3
|
from fastapp_template._zrb.config import APP_DIR
|
4
4
|
from fastapp_template._zrb.group import app_create_group
|
5
|
-
from fastapp_template._zrb.helper import get_existing_module_names
|
6
5
|
from fastapp_template._zrb.input import new_module_input
|
6
|
+
from fastapp_template._zrb.util import get_existing_module_names
|
7
7
|
|
8
8
|
from zrb import AnyContext, Scaffolder, Task, make_task
|
9
|
+
from zrb.util.file import read_file, write_file
|
9
10
|
from zrb.util.string.conversion import to_kebab_case, to_pascal_case, to_snake_case
|
10
11
|
|
11
12
|
|
@@ -22,7 +23,7 @@ async def validate_create_my_app_name_module(ctx: AnyContext):
|
|
22
23
|
scaffold_my_app_name_module = Scaffolder(
|
23
24
|
name="scaffold-my-app-name-module",
|
24
25
|
input=new_module_input,
|
25
|
-
source_path=os.path.join(os.path.dirname(__file__), "module_template"),
|
26
|
+
source_path=os.path.join(os.path.dirname(__file__), "template", "module_template"),
|
26
27
|
render_source_path=False,
|
27
28
|
destination_path=lambda ctx: os.path.join(
|
28
29
|
APP_DIR,
|
@@ -31,7 +32,8 @@ scaffold_my_app_name_module = Scaffolder(
|
|
31
32
|
),
|
32
33
|
transform_content={
|
33
34
|
"module_template": "{to_snake_case(ctx.input.module)}",
|
34
|
-
"
|
35
|
+
"MY_MODULE": "{to_snake_case(ctx.input.module).upper()}",
|
36
|
+
"my_module": "{to_snake_case(ctx.input.module)}",
|
35
37
|
},
|
36
38
|
retries=0,
|
37
39
|
upstream=validate_create_my_app_name_module,
|
@@ -60,8 +62,13 @@ async def register_my_app_name_module_config(ctx: AnyContext):
|
|
60
62
|
config_name = f"APP_{upper_module_name}_BASE_URL"
|
61
63
|
env_name = f"MY_APP_NAME_{upper_module_name}_BASE_URL"
|
62
64
|
# TODO: check before write
|
63
|
-
|
64
|
-
|
65
|
+
write_file(
|
66
|
+
config_file_name,
|
67
|
+
[
|
68
|
+
read_file(config_file_name),
|
69
|
+
f'{config_name} = os.getenv("{env_name}", "{module_base_url}")\n',
|
70
|
+
],
|
71
|
+
)
|
65
72
|
|
66
73
|
|
67
74
|
@make_task(
|
@@ -76,23 +83,24 @@ async def register_my_app_name_module(ctx: AnyContext):
|
|
76
83
|
module_name = to_snake_case(ctx.input.module)
|
77
84
|
import_code = f"from fastapp_template.module.{module_name} import route as {module_name}_route" # noqa
|
78
85
|
assert_code = f"assert {module_name}_route"
|
79
|
-
|
80
|
-
code = f.read()
|
86
|
+
code = read_file(app_main_file_name)
|
81
87
|
new_code = "\n".join([import_code, code.strip(), assert_code, ""])
|
82
88
|
# TODO: check before write
|
83
|
-
|
84
|
-
|
89
|
+
write_file(app_main_file_name, new_code)
|
90
|
+
|
91
|
+
|
92
|
+
# TODO: Register to zrb's config
|
85
93
|
|
86
94
|
|
87
95
|
@make_task(
|
88
|
-
name="
|
96
|
+
name="add-my-app-name-module-task-to-zrb-init",
|
89
97
|
input=new_module_input,
|
90
98
|
upstream=validate_create_my_app_name_module,
|
91
99
|
retries=0,
|
92
100
|
)
|
93
|
-
async def
|
94
|
-
"""Registering module to _zrb's
|
95
|
-
task_main_file_name = os.path.join(APP_DIR, "_zrb", "
|
101
|
+
async def add_my_app_name_module_task_to_zrb_init(ctx: AnyContext):
|
102
|
+
"""Registering module to _zrb's task.py"""
|
103
|
+
task_main_file_name = os.path.join(APP_DIR, "_zrb", "task.py")
|
96
104
|
existing_module_names = get_existing_module_names()
|
97
105
|
module_port = 3001 + len(
|
98
106
|
[
|
@@ -104,33 +112,32 @@ async def register_my_app_name_module_runner(ctx: AnyContext):
|
|
104
112
|
module_snake_name = to_snake_case(ctx.input.module)
|
105
113
|
module_kebab_name = to_kebab_case(ctx.input.module)
|
106
114
|
module_pascal_name = to_pascal_case(ctx.input.module)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
115
|
+
module_runner_code = read_file(
|
116
|
+
os.path.join(os.path.dirname(__file__), "template", "task_definition.py"),
|
117
|
+
{
|
118
|
+
"my_module": module_snake_name,
|
119
|
+
"my-module": module_kebab_name,
|
120
|
+
"My Module": module_pascal_name,
|
121
|
+
"3000": f"{module_port}",
|
122
|
+
},
|
123
|
+
)
|
124
|
+
code = read_file(task_main_file_name)
|
117
125
|
new_code = "\n".join([code.strip(), "", module_runner_code, ""])
|
118
126
|
# TODO: check before write
|
119
|
-
|
120
|
-
f.write(new_code)
|
127
|
+
write_file(task_main_file_name, new_code)
|
121
128
|
|
122
129
|
|
123
130
|
create_my_app_name_module = app_create_group.add_task(
|
124
131
|
Task(
|
125
132
|
name="create-my-app-name-module",
|
126
133
|
description="🧩 Create new module on My App Name",
|
134
|
+
upstream=[
|
135
|
+
scaffold_my_app_name_module,
|
136
|
+
register_my_app_name_module,
|
137
|
+
register_my_app_name_module_config,
|
138
|
+
add_my_app_name_module_task_to_zrb_init,
|
139
|
+
],
|
127
140
|
retries=0,
|
128
141
|
),
|
129
142
|
alias="module",
|
130
143
|
)
|
131
|
-
create_my_app_name_module << [
|
132
|
-
scaffold_my_app_name_module,
|
133
|
-
register_my_app_name_module,
|
134
|
-
register_my_app_name_module_config,
|
135
|
-
register_my_app_name_module_runner,
|
136
|
-
]
|
@@ -1,6 +1,6 @@
|
|
1
|
-
from fastapp_template.module.module_template.client.any_client import
|
1
|
+
from fastapp_template.module.module_template.client.any_client import AnyClient
|
2
2
|
from fastapp_template.module.module_template.service.user.usecase import user_usecase
|
3
3
|
|
4
4
|
|
5
|
-
class DirectClient(
|
5
|
+
class DirectClient(AnyClient):
|
6
6
|
pass
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from fastapp_template.config import APP_COMMUNICATION
|
2
|
-
from fastapp_template.module.module_template.client.any_client import
|
2
|
+
from fastapp_template.module.module_template.client.any_client import AnyClient
|
3
3
|
from fastapp_template.module.module_template.client.api_client import APIClient
|
4
4
|
from fastapp_template.module.module_template.client.direct_client import DirectClient
|
5
5
|
|
6
6
|
if APP_COMMUNICATION == "direct":
|
7
|
-
client:
|
7
|
+
client: AnyClient = DirectClient()
|
8
8
|
elif APP_COMMUNICATION == "api":
|
9
|
-
client:
|
9
|
+
client: AnyClient = APIClient()
|
zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/route.py
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
from fastapi import FastAPI
|
2
|
+
from fastapp_template.common.app import app
|
3
|
+
from fastapp_template.common.schema import BasicResponse
|
4
|
+
from fastapp_template.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
|
5
|
+
|
6
|
+
|
7
|
+
def serve_health_check(app: FastAPI):
|
8
|
+
@app.api_route("/health", methods=["GET", "HEAD"], response_model=BasicResponse)
|
9
|
+
async def health():
|
10
|
+
"""
|
11
|
+
Microservice's health check
|
12
|
+
"""
|
13
|
+
return BasicResponse(message="ok")
|
14
|
+
|
15
|
+
|
16
|
+
def serve_readiness_check(app: FastAPI):
|
17
|
+
@app.api_route("/readiness", methods=["GET", "HEAD"], response_model=BasicResponse)
|
18
|
+
async def readiness():
|
19
|
+
"""
|
20
|
+
Microservice's readiness check
|
21
|
+
"""
|
22
|
+
return BasicResponse(message="ok")
|
23
|
+
|
24
|
+
|
25
|
+
def serve_route(app: FastAPI):
|
26
|
+
if APP_MODE != "microservices" or "my_module" not in APP_MODULES:
|
27
|
+
return
|
28
|
+
if APP_MAIN_MODULE == "my_module":
|
29
|
+
serve_health_check(app)
|
30
|
+
serve_readiness_check(app)
|
31
|
+
|
32
|
+
|
33
|
+
serve_route(app)
|
zrb/builtin/project/add/{fastapp_template/_zrb/main.py → fastapp/fastapp_template/_zrb/task.py}
RENAMED
@@ -2,18 +2,18 @@ import os
|
|
2
2
|
|
3
3
|
from fastapp_template._zrb.column.create_column_task import create_my_app_name_column
|
4
4
|
from fastapp_template._zrb.config import ACTIVATE_VENV_SCRIPT, APP_DIR
|
5
|
-
from fastapp_template._zrb.entity.
|
5
|
+
from fastapp_template._zrb.entity.task import create_my_app_name_entity
|
6
6
|
from fastapp_template._zrb.group import (
|
7
7
|
app_create_migration_group,
|
8
8
|
app_migrate_group,
|
9
9
|
app_run_group,
|
10
10
|
)
|
11
|
-
from fastapp_template._zrb.
|
11
|
+
from fastapp_template._zrb.module.task import create_my_app_name_module
|
12
|
+
from fastapp_template._zrb.util import (
|
12
13
|
create_migration,
|
13
14
|
migrate_module,
|
14
15
|
run_microservice,
|
15
16
|
)
|
16
|
-
from fastapp_template._zrb.module.create_module_task import create_my_app_name_module
|
17
17
|
from fastapp_template._zrb.venv_task import prepare_venv
|
18
18
|
|
19
19
|
from zrb import CmdTask, Env, EnvFile, Task
|
zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/common/base_usecase.py
RENAMED
@@ -67,6 +67,12 @@ class RouteParam:
|
|
67
67
|
class BaseUsecase:
|
68
68
|
_route_params: dict[str, RouteParam] = {}
|
69
69
|
|
70
|
+
def __init__(self):
|
71
|
+
self._route_params: dict[str, RouteParam] = {}
|
72
|
+
for name, method in self.__class__.__dict__.items():
|
73
|
+
if hasattr(method, "__route_param__"):
|
74
|
+
self._route_params[name] = getattr(method, "__route_param__")
|
75
|
+
|
70
76
|
@classmethod
|
71
77
|
def route(
|
72
78
|
cls,
|
@@ -100,7 +106,15 @@ class BaseUsecase:
|
|
100
106
|
"""
|
101
107
|
|
102
108
|
def decorator(func: Callable):
|
103
|
-
|
109
|
+
@wraps(func)
|
110
|
+
async def wrapped(*args, **kwargs):
|
111
|
+
return await func(*args, **kwargs)
|
112
|
+
|
113
|
+
# Inject __route_param__ property to the method
|
114
|
+
# Method with __route_param__ property will automatically
|
115
|
+
# registered to self._route_param and will be automatically exposed
|
116
|
+
# into DirectClient and APIClient
|
117
|
+
wrapped.__route_param__ = RouteParam(
|
104
118
|
path=path,
|
105
119
|
response_model=response_model,
|
106
120
|
status_code=status_code,
|
@@ -126,11 +140,6 @@ class BaseUsecase:
|
|
126
140
|
generate_unique_id_function=generate_unique_id_function,
|
127
141
|
func=func,
|
128
142
|
)
|
129
|
-
|
130
|
-
@wraps(func)
|
131
|
-
async def wrapped(*args, **kwargs):
|
132
|
-
return await func(*args, **kwargs)
|
133
|
-
|
134
143
|
return wrapped
|
135
144
|
|
136
145
|
return decorator
|
@@ -144,6 +153,8 @@ class BaseUsecase:
|
|
144
153
|
for name, details in _methods.items():
|
145
154
|
func = details.func
|
146
155
|
client_method = create_direct_client_method(func, self)
|
156
|
+
# Use __get__ to make a bounded method,
|
157
|
+
# ensuring that client_method use DirectClient as `self`
|
147
158
|
setattr(DirectClient, name, client_method.__get__(DirectClient))
|
148
159
|
return DirectClient
|
149
160
|
|
@@ -156,6 +167,8 @@ class BaseUsecase:
|
|
156
167
|
# Dynamically generate methods
|
157
168
|
for name, param in _methods.items():
|
158
169
|
client_method = create_api_client_method(param, base_url)
|
170
|
+
# Use __get__ to make a bounded method,
|
171
|
+
# ensuring that client_method use APIClient as `self`
|
159
172
|
setattr(APIClient, name, client_method.__get__(APIClient))
|
160
173
|
return APIClient
|
161
174
|
|
@@ -8,6 +8,7 @@ APP_MODULES = [
|
|
8
8
|
for module in os.getenv("MY_APP_NAME_MODULES", "").split(",")
|
9
9
|
if module.strip() != ""
|
10
10
|
]
|
11
|
+
APP_MAIN_MODULE = APP_MODULES[0] if len(APP_MODULES) > 0 else None
|
11
12
|
APP_PORT = int(os.getenv("MY_APP_NAME_PORT", "3000"))
|
12
13
|
APP_COMMUNICATION = os.getenv(
|
13
14
|
"MY_APP_NAME_COMMUNICATION", "direct" if APP_MODE == "monolith" else "api"
|
@@ -1,9 +1,13 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
|
3
|
-
from fastapp_template.schema.user import
|
3
|
+
from fastapp_template.schema.user import (
|
4
|
+
UserCreateWithAudit,
|
5
|
+
UserResponse,
|
6
|
+
UserUpdateWithAudit,
|
7
|
+
)
|
4
8
|
|
5
9
|
|
6
|
-
class
|
10
|
+
class AnyClient(ABC):
|
7
11
|
@abstractmethod
|
8
12
|
async def get_user_by_id(self, user_id: str) -> UserResponse:
|
9
13
|
pass
|
@@ -14,12 +18,14 @@ class BaseClient(ABC):
|
|
14
18
|
|
15
19
|
@abstractmethod
|
16
20
|
async def create_user(
|
17
|
-
self, data:
|
21
|
+
self, data: UserCreateWithAudit | list[UserCreateWithAudit]
|
18
22
|
) -> UserResponse | list[UserResponse]:
|
19
23
|
pass
|
20
24
|
|
21
25
|
@abstractmethod
|
22
|
-
async def update_user(
|
26
|
+
async def update_user(
|
27
|
+
self, user_id: str, data: UserUpdateWithAudit
|
28
|
+
) -> UserResponse:
|
23
29
|
pass
|
24
30
|
|
25
31
|
@abstractmethod
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from fastapp_template.config import APP_AUTH_BASE_URL
|
2
|
-
from fastapp_template.module.auth.client.any_client import
|
2
|
+
from fastapp_template.module.auth.client.any_client import AnyClient
|
3
3
|
from fastapp_template.module.auth.service.user.user_usecase import user_usecase
|
4
4
|
|
5
5
|
|
6
|
-
class APIClient(user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL),
|
6
|
+
class APIClient(user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL), AnyClient):
|
7
7
|
pass
|
zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template}/module/auth/client/factory.py
RENAMED
@@ -1,9 +1,9 @@
|
|
1
1
|
from fastapp_template.config import APP_COMMUNICATION
|
2
|
-
from fastapp_template.module.auth.client.any_client import
|
2
|
+
from fastapp_template.module.auth.client.any_client import AnyClient
|
3
3
|
from fastapp_template.module.auth.client.api_client import APIClient
|
4
4
|
from fastapp_template.module.auth.client.direct_client import DirectClient
|
5
5
|
|
6
6
|
if APP_COMMUNICATION == "direct":
|
7
|
-
client:
|
7
|
+
client: AnyClient = DirectClient()
|
8
8
|
elif APP_COMMUNICATION == "api":
|
9
|
-
client:
|
9
|
+
client: AnyClient = APIClient()
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from fastapi import FastAPI
|
2
|
+
from fastapp_template.common.app import app
|
3
|
+
from fastapp_template.common.schema import BasicResponse
|
4
|
+
from fastapp_template.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
|
5
|
+
from fastapp_template.module.auth.service.user.user_usecase import user_usecase
|
6
|
+
|
7
|
+
|
8
|
+
def serve_health_check(app: FastAPI):
|
9
|
+
@app.api_route("/health", methods=["GET", "HEAD"], response_model=BasicResponse)
|
10
|
+
async def health():
|
11
|
+
"""
|
12
|
+
Microservice's health check
|
13
|
+
"""
|
14
|
+
return BasicResponse(message="ok")
|
15
|
+
|
16
|
+
|
17
|
+
def serve_readiness_check(app: FastAPI):
|
18
|
+
@app.api_route("/readiness", methods=["GET", "HEAD"], response_model=BasicResponse)
|
19
|
+
async def readiness():
|
20
|
+
"""
|
21
|
+
Microservice's readiness check
|
22
|
+
"""
|
23
|
+
return BasicResponse(message="ok")
|
24
|
+
|
25
|
+
|
26
|
+
def serve_route(app: FastAPI):
|
27
|
+
if APP_MODE != "microservices" or "auth" not in APP_MODULES:
|
28
|
+
return
|
29
|
+
if APP_MAIN_MODULE == "auth":
|
30
|
+
serve_health_check(app)
|
31
|
+
serve_readiness_check(app)
|
32
|
+
|
33
|
+
# Serve user endpoints for APIClient
|
34
|
+
user_usecase.serve_route(app)
|
35
|
+
|
36
|
+
|
37
|
+
serve_route(app)
|
@@ -3,7 +3,12 @@ from fastapp_template.common.error import NotFoundError
|
|
3
3
|
from fastapp_template.module.auth.service.user.repository.user_repository import (
|
4
4
|
UserRepository,
|
5
5
|
)
|
6
|
-
from fastapp_template.schema.user import
|
6
|
+
from fastapp_template.schema.user import (
|
7
|
+
User,
|
8
|
+
UserCreateWithAudit,
|
9
|
+
UserResponse,
|
10
|
+
UserUpdateWithAudit,
|
11
|
+
)
|
7
12
|
from passlib.context import CryptContext
|
8
13
|
from sqlalchemy.ext.asyncio import AsyncSession
|
9
14
|
from sqlmodel import Session, select
|
@@ -17,12 +22,13 @@ def hash_password(password: str) -> str:
|
|
17
22
|
|
18
23
|
|
19
24
|
class UserDBRepository(
|
20
|
-
BaseDBRepository[User, UserResponse,
|
25
|
+
BaseDBRepository[User, UserResponse, UserCreateWithAudit, UserUpdateWithAudit],
|
26
|
+
UserRepository,
|
21
27
|
):
|
22
28
|
db_model = User
|
23
29
|
response_model = UserResponse
|
24
|
-
create_model =
|
25
|
-
update_model =
|
30
|
+
create_model = UserCreateWithAudit
|
31
|
+
update_model = UserUpdateWithAudit
|
26
32
|
entity_name = "user"
|
27
33
|
column_preprocessors = {"password": hash_password}
|
28
34
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
|
3
|
+
from fastapp_template.schema.user import (
|
4
|
+
User,
|
5
|
+
UserCreateWithAudit,
|
6
|
+
UserResponse,
|
7
|
+
UserUpdateWithAudit,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
class UserRepository(ABC):
|
12
|
+
|
13
|
+
@abstractmethod
|
14
|
+
async def create(self, user_data: UserCreateWithAudit) -> UserResponse:
|
15
|
+
pass
|
16
|
+
|
17
|
+
@abstractmethod
|
18
|
+
async def get_by_id(self, user_id: str) -> UserResponse:
|
19
|
+
pass
|
20
|
+
|
21
|
+
@abstractmethod
|
22
|
+
async def get_all(self) -> list[User]:
|
23
|
+
pass
|
24
|
+
|
25
|
+
@abstractmethod
|
26
|
+
async def update(
|
27
|
+
self, user_id: str, user_data: UserUpdateWithAudit
|
28
|
+
) -> UserResponse:
|
29
|
+
pass
|
30
|
+
|
31
|
+
@abstractmethod
|
32
|
+
async def delete(self, user_id: str) -> UserResponse:
|
33
|
+
pass
|
34
|
+
|
35
|
+
@abstractmethod
|
36
|
+
async def create_bulk(
|
37
|
+
self, user_data_list: list[UserCreateWithAudit]
|
38
|
+
) -> list[UserResponse]:
|
39
|
+
pass
|
40
|
+
|
41
|
+
@abstractmethod
|
42
|
+
async def get_by_credentials(self, username: str, password: str) -> UserResponse:
|
43
|
+
pass
|
@@ -3,7 +3,11 @@ from fastapp_template.module.auth.service.user.repository.factory import user_re
|
|
3
3
|
from fastapp_template.module.auth.service.user.repository.user_repository import (
|
4
4
|
UserRepository,
|
5
5
|
)
|
6
|
-
from fastapp_template.schema.user import
|
6
|
+
from fastapp_template.schema.user import (
|
7
|
+
UserCreateWithAudit,
|
8
|
+
UserResponse,
|
9
|
+
UserUpdateWithAudit,
|
10
|
+
)
|
7
11
|
|
8
12
|
|
9
13
|
class UserUsecase(BaseUsecase):
|
@@ -30,16 +34,18 @@ class UserUsecase(BaseUsecase):
|
|
30
34
|
response_model=UserResponse | list[UserResponse],
|
31
35
|
)
|
32
36
|
async def create_user(
|
33
|
-
self, data:
|
37
|
+
self, data: UserCreateWithAudit | list[UserCreateWithAudit]
|
34
38
|
) -> UserResponse | list[UserResponse]:
|
35
|
-
if isinstance(data,
|
39
|
+
if isinstance(data, UserCreateWithAudit):
|
36
40
|
return await self.user_repository.create(data)
|
37
41
|
return await self.user_repository.create_bulk(data)
|
38
42
|
|
39
43
|
@BaseUsecase.route(
|
40
44
|
"/api/v1/users/{user_id}", methods=["put"], response_model=UserResponse
|
41
45
|
)
|
42
|
-
async def update_user(
|
46
|
+
async def update_user(
|
47
|
+
self, user_id: str, data: UserUpdateWithAudit
|
48
|
+
) -> UserResponse:
|
43
49
|
return await self.user_repository.update(user_id, data)
|
44
50
|
|
45
51
|
@BaseUsecase.route(
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from fastapi import FastAPI
|
2
|
+
from fastapp_template.common.app import app
|
3
|
+
from fastapp_template.common.schema import BasicResponse
|
4
|
+
from fastapp_template.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
|
5
|
+
from fastapp_template.module.auth.client.factory import client as auth_client
|
6
|
+
from fastapp_template.schema.user import UserCreate, UserResponse
|
7
|
+
|
8
|
+
|
9
|
+
def serve_health_check(app: FastAPI):
|
10
|
+
@app.api_route("/health", methods=["GET", "HEAD"], response_model=BasicResponse)
|
11
|
+
async def health():
|
12
|
+
"""
|
13
|
+
My App Name's health check
|
14
|
+
"""
|
15
|
+
return BasicResponse(message="ok")
|
16
|
+
|
17
|
+
|
18
|
+
def serve_readiness_check(app: FastAPI):
|
19
|
+
@app.api_route("/readiness", methods=["GET", "HEAD"], response_model=BasicResponse)
|
20
|
+
async def readiness():
|
21
|
+
"""
|
22
|
+
My App Name's readiness check
|
23
|
+
"""
|
24
|
+
return BasicResponse(message="ok")
|
25
|
+
|
26
|
+
|
27
|
+
def serve_route(app: FastAPI):
|
28
|
+
if APP_MODE != "monolith" and "gateway" not in APP_MODULES:
|
29
|
+
return
|
30
|
+
if APP_MODE == "monolith" or APP_MAIN_MODULE == "gateway":
|
31
|
+
serve_health_check(app)
|
32
|
+
serve_readiness_check(app)
|
33
|
+
|
34
|
+
@app.get("/api/v1/users", response_model=list[UserResponse])
|
35
|
+
async def auth_get_all_users() -> UserResponse:
|
36
|
+
return await auth_client.get_all_users()
|
37
|
+
|
38
|
+
@app.post("/api/v1/users", response_model=UserResponse | list[UserResponse])
|
39
|
+
async def auth_create_user(data: UserCreate | list[UserCreate]):
|
40
|
+
return await auth_client.create_user(data)
|
41
|
+
|
42
|
+
|
43
|
+
serve_route(app)
|
@@ -12,11 +12,19 @@ class PermissionCreate(PermissionBase):
|
|
12
12
|
description: str
|
13
13
|
|
14
14
|
|
15
|
+
class PermissionCreateWithAudit(PermissionCreate):
|
16
|
+
created_by: str
|
17
|
+
|
18
|
+
|
15
19
|
class PermissionUpdate(SQLModel):
|
16
20
|
name: str | None = None
|
17
21
|
description: str | None = None
|
18
22
|
|
19
23
|
|
24
|
+
class PermissionUpdateWithAudit(PermissionUpdate):
|
25
|
+
updated_by: str
|
26
|
+
|
27
|
+
|
20
28
|
class PermissionResponse(PermissionBase):
|
21
29
|
id: str
|
22
30
|
|
@@ -12,11 +12,19 @@ class RoleCreate(RoleBase):
|
|
12
12
|
description: str
|
13
13
|
|
14
14
|
|
15
|
+
class RoleCreateWithAudit(RoleCreate):
|
16
|
+
created_by: str
|
17
|
+
|
18
|
+
|
15
19
|
class RoleUpdate(SQLModel):
|
16
20
|
name: str | None = None
|
17
21
|
description: str | None = None
|
18
22
|
|
19
23
|
|
24
|
+
class RoleUpdateWithAudit(RoleUpdate):
|
25
|
+
updated_by: str
|
26
|
+
|
27
|
+
|
20
28
|
class RoleResponse(RoleBase):
|
21
29
|
id: str
|
22
30
|
|
@@ -12,11 +12,19 @@ class UserCreate(UserBase):
|
|
12
12
|
password: str
|
13
13
|
|
14
14
|
|
15
|
+
class UserCreateWithAudit(UserCreate):
|
16
|
+
created_by: str
|
17
|
+
|
18
|
+
|
15
19
|
class UserUpdate(SQLModel):
|
16
20
|
username: str | None = None
|
17
21
|
password: str | None = None
|
18
22
|
|
19
23
|
|
24
|
+
class UserUpdateWithAudit(UserUpdate):
|
25
|
+
updated_by: str
|
26
|
+
|
27
|
+
|
20
28
|
class UserResponse(UserBase):
|
21
29
|
id: str
|
22
30
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from zrb.util.string.conversion import double_quote, to_snake_case
|
2
|
+
|
3
|
+
|
4
|
+
def get_zrb_init_import_code(old_code: str) -> str | None:
|
5
|
+
code = "from zrb import load_file"
|
6
|
+
if code in old_code:
|
7
|
+
return None
|
8
|
+
return code
|
9
|
+
|
10
|
+
|
11
|
+
def get_zrb_init_load_app_name_task(app: str) -> str:
|
12
|
+
snake_app_name = to_snake_case(app)
|
13
|
+
load_file_param = ", ".join(
|
14
|
+
[double_quote(part) for part in [snake_app_name, "_zrb", "task.py"]]
|
15
|
+
)
|
16
|
+
return "\n".join(
|
17
|
+
[
|
18
|
+
f"# Load {app} automation",
|
19
|
+
f"{snake_app_name} = load_file(os.path.join(_DIR, {load_file_param}))",
|
20
|
+
f"assert {snake_app_name}",
|
21
|
+
]
|
22
|
+
)
|
@@ -21,7 +21,7 @@ scaffold_project = Scaffolder(
|
|
21
21
|
name="project",
|
22
22
|
description="Project name",
|
23
23
|
prompt="Project name",
|
24
|
-
default_str=lambda ctx: os.path.basename(ctx.input
|
24
|
+
default_str=lambda ctx: os.path.basename(ctx.input.project_dir),
|
25
25
|
),
|
26
26
|
],
|
27
27
|
source_path=os.path.join(_DIR, "project-template"),
|