scaffold-ca-python 0.3.0__py3-none-any.whl → 0.5.0__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.
- scaffold_ca_python/commands/generate_use_case.py +23 -13
- scaffold_ca_python/core/module_locator.py +19 -2
- scaffold_ca_python/core/name_utils.py +8 -0
- scaffold_ca_python/factory/entry_points/ep_mcp.py +13 -0
- scaffold_ca_python/factory/simple/delete_module_factory.py +1 -1
- scaffold_ca_python/factory/simple/use_case_factory.py +4 -4
- scaffold_ca_python/templates/entry_point/mcp/app.py.jinja2 +2 -1
- scaffold_ca_python/templates/entry_point/mcp/routes.py.jinja2 +25 -0
- scaffold_ca_python/templates/entry_point/mcp/test_app.py.jinja2 +17 -0
- scaffold_ca_python/templates/entry_point/mcp/test_routes.py.jinja2 +25 -0
- scaffold_ca_python/templates/use_case/test_use_case.py.jinja2 +1 -1
- {scaffold_ca_python-0.3.0.dist-info → scaffold_ca_python-0.5.0.dist-info}/METADATA +2 -2
- {scaffold_ca_python-0.3.0.dist-info → scaffold_ca_python-0.5.0.dist-info}/RECORD +16 -14
- {scaffold_ca_python-0.3.0.dist-info → scaffold_ca_python-0.5.0.dist-info}/WHEEL +0 -0
- {scaffold_ca_python-0.3.0.dist-info → scaffold_ca_python-0.5.0.dist-info}/entry_points.txt +0 -0
- {scaffold_ca_python-0.3.0.dist-info → scaffold_ca_python-0.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -10,43 +10,53 @@ from scaffold_ca_python.commands._shared import (
|
|
|
10
10
|
build_and_persist,
|
|
11
11
|
console,
|
|
12
12
|
ensure_absent,
|
|
13
|
+
fail,
|
|
13
14
|
print_dry_run_tree,
|
|
14
15
|
require_project_root,
|
|
15
16
|
validate_name_or_exit,
|
|
16
17
|
)
|
|
17
18
|
from scaffold_ca_python.core.module_builder import ModuleBuilder
|
|
18
|
-
from scaffold_ca_python.core.name_utils import to_snake_case, validate_module_name
|
|
19
|
-
from scaffold_ca_python.core.project_detector import load_project_context
|
|
19
|
+
from scaffold_ca_python.core.name_utils import strip_usecase_suffix, to_snake_case, validate_module_name
|
|
20
|
+
from scaffold_ca_python.core.project_detector import load_project_context, resolve_tests_root
|
|
20
21
|
from scaffold_ca_python.factory.simple.use_case_factory import UseCaseFactory
|
|
21
22
|
from scaffold_ca_python.models.context import ModuleContext
|
|
22
23
|
from scaffold_ca_python.models.layer import Layer
|
|
23
24
|
|
|
24
25
|
_GUC_HELP = "Scaffold a use case in domain/usecase/. Alias 'guc'."
|
|
25
26
|
_GUC_EPILOG = (
|
|
26
|
-
"Example:\n\n * scaffold guc --name create_order
|
|
27
|
+
"Example:\n\n * scaffold guc --name create_order (creates domain/usecase/create_order_usecase.py)\n\n"
|
|
28
|
+
" * scaffold generate-use-case --name create_order\n\n"
|
|
27
29
|
)
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
def _generate_use_case_impl(name: str, dry_run: bool) -> None:
|
|
31
33
|
validate_name_or_exit(name, validate_module_name)
|
|
34
|
+
base = strip_usecase_suffix(to_snake_case(name))
|
|
35
|
+
if not base:
|
|
36
|
+
fail(
|
|
37
|
+
f"Use case name '{name}' is only the 'usecase' suffix.",
|
|
38
|
+
hint="Use a descriptive name such as 'create_order'.",
|
|
39
|
+
)
|
|
32
40
|
project_root = require_project_root()
|
|
33
41
|
project_ctx = load_project_context(project_root)
|
|
34
|
-
module_ctx = ModuleContext(name=
|
|
42
|
+
module_ctx = ModuleContext(name=base, layer=Layer.DOMAIN_USECASE, project=project_ctx)
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
src_path = project_root / "src" / project_ctx.python_package / "domain" / "usecase" / f"{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
module = f"{base}_usecase"
|
|
45
|
+
src_path = project_root / "src" / project_ctx.python_package / "domain" / "usecase" / f"{module}.py"
|
|
46
|
+
test_path = resolve_tests_root(project_root) / "domain" / "usecase" / f"test_{module}.py"
|
|
47
|
+
for path in (src_path, test_path):
|
|
48
|
+
ensure_absent(
|
|
49
|
+
path,
|
|
50
|
+
project_root,
|
|
51
|
+
kind="File",
|
|
52
|
+
hint="Choose a different name or remove the existing file first.",
|
|
53
|
+
)
|
|
44
54
|
|
|
45
55
|
builder = ModuleBuilder(project_root=project_root, project_ctx=project_ctx, module_ctx=module_ctx, dry_run=dry_run)
|
|
46
56
|
created = build_and_persist(UseCaseFactory(), builder)
|
|
47
57
|
|
|
48
58
|
if dry_run:
|
|
49
|
-
print_dry_run_tree(
|
|
59
|
+
print_dry_run_tree(module, created, project_root)
|
|
50
60
|
return
|
|
51
61
|
|
|
52
62
|
msg = (
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from scaffold_ca_python.core.name_utils import strip_usecase_suffix
|
|
7
8
|
from scaffold_ca_python.core.project_detector import resolve_tests_root
|
|
8
9
|
|
|
9
10
|
|
|
@@ -11,7 +12,7 @@ def find_module_targets(project_root: Path, pkg: str, snake: str) -> list[tuple[
|
|
|
11
12
|
"""Return ``(src_path, test_path | None)`` pairs for every match of *snake*.
|
|
12
13
|
|
|
13
14
|
Searches in order: domain/model/<snake>/ (package), domain/model/<snake>.py (legacy flat),
|
|
14
|
-
domain/usecase, driven_adapters,
|
|
15
|
+
domain/usecase (``<base>_usecase.py`` first, then legacy ``<snake>.py``), driven_adapters,
|
|
15
16
|
entry_points, helpers.
|
|
16
17
|
"""
|
|
17
18
|
src_root = project_root / "src" / pkg
|
|
@@ -24,9 +25,25 @@ def find_module_targets(project_root: Path, pkg: str, snake: str) -> list[tuple[
|
|
|
24
25
|
model_pkg_test = tests_root / "domain" / "model" / snake
|
|
25
26
|
candidates.append((model_pkg, model_pkg_test if model_pkg_test.exists() else None))
|
|
26
27
|
|
|
28
|
+
usecase_pairs: list[tuple[Path, Path]] = []
|
|
29
|
+
base = strip_usecase_suffix(snake)
|
|
30
|
+
if base:
|
|
31
|
+
usecase_pairs.append(
|
|
32
|
+
(
|
|
33
|
+
src_root / "domain" / "usecase" / f"{base}_usecase.py",
|
|
34
|
+
tests_root / "domain" / "usecase" / f"test_{base}_usecase.py",
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
legacy_usecase = (
|
|
38
|
+
src_root / "domain" / "usecase" / f"{snake}.py",
|
|
39
|
+
tests_root / "domain" / "usecase" / f"test_{snake}.py",
|
|
40
|
+
)
|
|
41
|
+
if legacy_usecase not in usecase_pairs:
|
|
42
|
+
usecase_pairs.append(legacy_usecase)
|
|
43
|
+
|
|
27
44
|
for src_rel, test_rel in [
|
|
28
45
|
(src_root / "domain" / "model" / f"{snake}.py", tests_root / "domain" / "model" / f"test_{snake}.py"),
|
|
29
|
-
|
|
46
|
+
*usecase_pairs,
|
|
30
47
|
]:
|
|
31
48
|
if src_rel.exists():
|
|
32
49
|
candidates.append((src_rel, test_rel if test_rel.exists() else None))
|
|
@@ -9,6 +9,9 @@ NAME_RE = re.compile(r"^[a-z][a-z0-9]*([_-][a-z0-9]+)*$")
|
|
|
9
9
|
# Stricter pattern for module/class-generating commands: snake_case only (no hyphens).
|
|
10
10
|
MODULE_NAME_RE = re.compile(r"^[a-z][a-z0-9]*(_[a-z0-9]+)*$")
|
|
11
11
|
|
|
12
|
+
# Trailing use case suffixes (applied to "_" + name so a bare "usecase" also matches)
|
|
13
|
+
_USECASE_SUFFIX_RE = re.compile(r"(?:_(?:usecase|use_case))+$")
|
|
14
|
+
|
|
12
15
|
# Matches transitions: lowercase→uppercase and letter→digit boundary runs
|
|
13
16
|
_CAMEL_BOUNDARY_RE = re.compile(r"(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])")
|
|
14
17
|
|
|
@@ -50,6 +53,11 @@ def to_snake_case(name: str) -> str:
|
|
|
50
53
|
return s.lower()
|
|
51
54
|
|
|
52
55
|
|
|
56
|
+
def strip_usecase_suffix(name: str) -> str:
|
|
57
|
+
"""Remove every trailing ``_usecase`` / ``_use_case`` suffix from *name* (may return an empty string)."""
|
|
58
|
+
return _USECASE_SUFFIX_RE.sub("", f"_{name}").removeprefix("_")
|
|
59
|
+
|
|
60
|
+
|
|
53
61
|
def to_kebab_case(name: str) -> str:
|
|
54
62
|
"""Convert *name* (PascalCase, snake_case, or already kebab-case) to kebab-case."""
|
|
55
63
|
# Normalise underscores to hyphens first (snake_case support)
|
|
@@ -29,7 +29,9 @@ class EntryPointMcp(EntryPointFactory):
|
|
|
29
29
|
Always queues:
|
|
30
30
|
- src/infrastructure/entry_points/mcp_server/__init__.py
|
|
31
31
|
- src/infrastructure/entry_points/mcp_server/tools.py
|
|
32
|
+
- src/infrastructure/entry_points/mcp_server/routes.py
|
|
32
33
|
- tests/infrastructure/entry_points/mcp_server/test_tools.py
|
|
34
|
+
- tests/infrastructure/entry_points/mcp_server/test_routes.py
|
|
33
35
|
|
|
34
36
|
Conditionally queues (when builder params are True):
|
|
35
37
|
- resources.py + test_resources.py (with_resources=True)
|
|
@@ -66,12 +68,23 @@ class EntryPointMcp(EntryPointFactory):
|
|
|
66
68
|
builder.render(f"{base}/tools.py.jinja2", ctx_dict),
|
|
67
69
|
template_name=f"{base}/tools.py.jinja2",
|
|
68
70
|
)
|
|
71
|
+
builder.add_file(
|
|
72
|
+
src_dir / "routes.py",
|
|
73
|
+
builder.render(f"{base}/routes.py.jinja2", ctx_dict),
|
|
74
|
+
template_name=f"{base}/routes.py.jinja2",
|
|
75
|
+
)
|
|
69
76
|
builder.add_file(
|
|
70
77
|
test_dir / "test_tools.py",
|
|
71
78
|
builder.render(f"{base}/test_tools.py.jinja2", ctx_dict),
|
|
72
79
|
template_name=f"{base}/test_tools.py.jinja2",
|
|
73
80
|
is_test=True,
|
|
74
81
|
)
|
|
82
|
+
builder.add_file(
|
|
83
|
+
test_dir / "test_routes.py",
|
|
84
|
+
builder.render(f"{base}/test_routes.py.jinja2", ctx_dict),
|
|
85
|
+
template_name=f"{base}/test_routes.py.jinja2",
|
|
86
|
+
is_test=True,
|
|
87
|
+
)
|
|
75
88
|
|
|
76
89
|
# Optional: resources
|
|
77
90
|
if with_resources:
|
|
@@ -22,7 +22,7 @@ class DeleteModuleFactory(ModuleFactory):
|
|
|
22
22
|
|
|
23
23
|
Finds and deletes modules across:
|
|
24
24
|
- domain/model/<snake>/ (package) or domain/model/<snake>.py (legacy)
|
|
25
|
-
- domain/usecase/<snake>.py
|
|
25
|
+
- domain/usecase/<base>_usecase.py or domain/usecase/<snake>.py (legacy)
|
|
26
26
|
- infrastructure/driven_adapters/<snake>/
|
|
27
27
|
- infrastructure/entry_points/<snake>/
|
|
28
28
|
- infrastructure/helpers/<snake>/
|
|
@@ -19,8 +19,8 @@ class UseCaseFactory(ModuleFactory):
|
|
|
19
19
|
"""Build domain use case files.
|
|
20
20
|
|
|
21
21
|
Queues files:
|
|
22
|
-
- src/domain/usecase/{snake_name}.py
|
|
23
|
-
- tests/domain/usecase/test_{snake_name}.py
|
|
22
|
+
- src/domain/usecase/{snake_name}_usecase.py
|
|
23
|
+
- tests/domain/usecase/test_{snake_name}_usecase.py
|
|
24
24
|
|
|
25
25
|
No dependencies injected (async/await are built-in).
|
|
26
26
|
"""
|
|
@@ -45,14 +45,14 @@ class UseCaseFactory(ModuleFactory):
|
|
|
45
45
|
|
|
46
46
|
# Add source file
|
|
47
47
|
builder.add_file(
|
|
48
|
-
src_dir / f"{snake_name}.py",
|
|
48
|
+
src_dir / f"{snake_name}_usecase.py",
|
|
49
49
|
builder.render(f"{base}/use_case.py.jinja2", ctx_dict),
|
|
50
50
|
template_name=f"{base}/use_case.py.jinja2",
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
# Add test file
|
|
54
54
|
builder.add_file(
|
|
55
|
-
test_dir / f"test_{snake_name}.py",
|
|
55
|
+
test_dir / f"test_{snake_name}_usecase.py",
|
|
56
56
|
builder.render(f"{base}/test_use_case.py.jinja2", ctx_dict),
|
|
57
57
|
template_name=f"{base}/test_use_case.py.jinja2",
|
|
58
58
|
is_test=True,
|
|
@@ -9,7 +9,7 @@ from starlette.applications import Starlette
|
|
|
9
9
|
from starlette.routing import Mount
|
|
10
10
|
|
|
11
11
|
from {{ project.python_package }}.application.config.container import Container
|
|
12
|
-
from {{ project.python_package }}.infrastructure.entry_points.mcp_server import tools
|
|
12
|
+
from {{ project.python_package }}.infrastructure.entry_points.mcp_server import routes, tools
|
|
13
13
|
{%- if with_resources %}
|
|
14
14
|
from {{ project.python_package }}.infrastructure.entry_points.mcp_server import resources
|
|
15
15
|
{%- endif %}
|
|
@@ -18,6 +18,7 @@ from {{ project.python_package }}.infrastructure.entry_points.mcp_server import
|
|
|
18
18
|
{%- endif %}
|
|
19
19
|
|
|
20
20
|
mcp: FastMCP = FastMCP("{{ project.name }}", stateless_http=True)
|
|
21
|
+
routes.bind_routes(mcp)
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
@asynccontextmanager
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""MCP custom routes binding — register non-MCP HTTP routes such as the health check."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from mcp.server.fastmcp import FastMCP
|
|
6
|
+
from starlette.requests import Request
|
|
7
|
+
from starlette.responses import JSONResponse, Response
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def bind_routes(mcp: FastMCP) -> None:
|
|
11
|
+
"""
|
|
12
|
+
Bind routes to the FastMCP instance.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@mcp.custom_route(name="health_check", path="/api/v1/health", methods=["GET"])
|
|
16
|
+
async def health_check(_request: Request) -> Response:
|
|
17
|
+
"""
|
|
18
|
+
Health check endpoint to verify the server is running.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
JSON response indicating the server is healthy.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
response_data = {"status": "ok"}
|
|
25
|
+
return JSONResponse(response_data)
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import FastMCP
|
|
6
6
|
from starlette.applications import Starlette
|
|
7
|
+
from starlette.testclient import TestClient
|
|
7
8
|
|
|
8
9
|
from {{ project.python_package }}.application import app as app_module
|
|
9
10
|
|
|
@@ -28,3 +29,19 @@ def test_start_server_has_routes() -> None:
|
|
|
28
29
|
def test_lifespan_is_callable() -> None:
|
|
29
30
|
"""lifespan must be a callable (async context manager factory)."""
|
|
30
31
|
assert callable(app_module.lifespan)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_health_route_registered_once() -> None:
|
|
35
|
+
"""Repeated start_server() calls must not duplicate the health route."""
|
|
36
|
+
app_module.start_server()
|
|
37
|
+
server = app_module.start_server()
|
|
38
|
+
health = [r for r in server.routes[0].routes if getattr(r, "path", None) == "/api/v1/health"]
|
|
39
|
+
assert len(health) == 1
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_health_route_reachable_through_start_server() -> None:
|
|
43
|
+
"""The health route is not shadowed by the Mount('/')."""
|
|
44
|
+
client = TestClient(app_module.start_server())
|
|
45
|
+
response = client.get("/api/v1/health")
|
|
46
|
+
assert response.status_code == 200
|
|
47
|
+
assert response.json() == {"status": "ok"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Tests for {{ project.python_package }}.infrastructure.entry_points.mcp_server.routes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from mcp.server.fastmcp import FastMCP
|
|
6
|
+
from starlette.testclient import TestClient
|
|
7
|
+
|
|
8
|
+
from {{ project.python_package }}.infrastructure.entry_points.mcp_server.routes import bind_routes
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _client() -> TestClient:
|
|
12
|
+
mcp = FastMCP("test")
|
|
13
|
+
bind_routes(mcp)
|
|
14
|
+
return TestClient(mcp.streamable_http_app())
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_health_check_returns_ok() -> None:
|
|
18
|
+
response = _client().get("/api/v1/health")
|
|
19
|
+
assert response.status_code == 200
|
|
20
|
+
assert response.json() == {"status": "ok"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_health_check_rejects_post() -> None:
|
|
24
|
+
response = _client().post("/api/v1/health")
|
|
25
|
+
assert response.status_code == 405
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scaffold-ca-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Scaffolder to generate Clean Architecture apps
|
|
5
5
|
Project-URL: Homepage, https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
6
6
|
Project-URL: Repository, https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
@@ -128,7 +128,7 @@ scaffold gm --name order --dry-run
|
|
|
128
128
|
|
|
129
129
|
### scaffold guc
|
|
130
130
|
|
|
131
|
-
Scaffold a use case in `domain/usecase/`.
|
|
131
|
+
Scaffold a use case in `domain/usecase/`. The module is always named `<name>_usecase.py` and the class `<Name>UseCase`. Writing `_usecase` in `--name` is optional and the suffix is never duplicated: `create_order`, `create_order_usecase` and `create_order_use_case` all create `create_order_usecase.py` with `CreateOrderUseCase`.
|
|
132
132
|
|
|
133
133
|
```bash
|
|
134
134
|
scaffold guc --name create_order
|
|
@@ -11,15 +11,15 @@ scaffold_ca_python/commands/generate_helper.py,sha256=O98ua5Fj3judGxF_vmTYbm_j-q
|
|
|
11
11
|
scaffold_ca_python/commands/generate_model.py,sha256=GBHPkoTYrABNdmdILWGLuQFM4ppzYbuHyunjhc-o4Dc,3387
|
|
12
12
|
scaffold_ca_python/commands/generate_pipeline.py,sha256=Ip-rN4nSbwaUbtJ49awAs4LDURsrDTQsZdG5kBCLdyE,3773
|
|
13
13
|
scaffold_ca_python/commands/generate_project.py,sha256=5KRsPI_WiWQVY1d_0AblUHKdDQCWpXJA7MaOCHae0fE,5312
|
|
14
|
-
scaffold_ca_python/commands/generate_use_case.py,sha256=
|
|
14
|
+
scaffold_ca_python/commands/generate_use_case.py,sha256=3uKYZik9eF23Z9QMM2psGNWuW2AhxkB468urum5N8WA,3441
|
|
15
15
|
scaffold_ca_python/commands/update_project.py,sha256=7bu2neRasxEtYK2rIvx0CFISSx9D64BNCkijp90zWGk,2367
|
|
16
16
|
scaffold_ca_python/commands/validate_structure.py,sha256=p_bYTgOl4_TrC80z-v2teSsssc9xghlkCYlUp3SuzHo,2526
|
|
17
17
|
scaffold_ca_python/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
scaffold_ca_python/core/file_writer.py,sha256=KdnNrq33Jsvqs1IQf0jbUKdXls4jBSWAizw4uJhMalU,5561
|
|
19
19
|
scaffold_ca_python/core/mcp_tool_spec.py,sha256=mPLN7vOSgWFWxHQQxmr0fWEaimHWI-9A0oP7ob73-rU,10602
|
|
20
20
|
scaffold_ca_python/core/module_builder.py,sha256=AHC3szEdfS3i3q74IM6USZTHWEUK6QizL6NEKcHCrrI,6837
|
|
21
|
-
scaffold_ca_python/core/module_locator.py,sha256=
|
|
22
|
-
scaffold_ca_python/core/name_utils.py,sha256=
|
|
21
|
+
scaffold_ca_python/core/module_locator.py,sha256=FFAwA7Vajxg0JgHoVXc1HpvdB67clvkv_BFVwiQDxHA,2552
|
|
22
|
+
scaffold_ca_python/core/name_utils.py,sha256=IpXAieBKFe7QbOY4K8gNsjr4NXUfJX5MBCy2bQyPIk4,2958
|
|
23
23
|
scaffold_ca_python/core/openapi_routes.py,sha256=RCQS7mHufWJZgbLI1cxGli-xGbU7p7WI95fHJhDnIss,1098
|
|
24
24
|
scaffold_ca_python/core/project_detector.py,sha256=vcDAFCGgQVDMQ2MivJVUmn5Yyj58vGpTbzKhZTBQNtw,3524
|
|
25
25
|
scaffold_ca_python/core/pyproject_writer.py,sha256=zpxgubt-XSZR5domgL4LG_9AWD9b_cNrDM8fuHmZRzE,7792
|
|
@@ -35,15 +35,15 @@ scaffold_ca_python/factory/entry_points/__init__.py,sha256=ylyCH8R8iORQjHkx-bzy4
|
|
|
35
35
|
scaffold_ca_python/factory/entry_points/base.py,sha256=DOhL2jniv-LdiNIgFINgXX-i6krRO2EAvJAi7L_ZisA,1892
|
|
36
36
|
scaffold_ca_python/factory/entry_points/ep_agent.py,sha256=ODql04XDXya3ANYez38M3AYoUeRh9OmW7nxGmWHRgIY,3410
|
|
37
37
|
scaffold_ca_python/factory/entry_points/ep_generic.py,sha256=L51mO007f6LtgBzOAmBlW4dClLK9IzQf3rJjNUbd9xk,2823
|
|
38
|
-
scaffold_ca_python/factory/entry_points/ep_mcp.py,sha256=
|
|
38
|
+
scaffold_ca_python/factory/entry_points/ep_mcp.py,sha256=TVJrEFRrviB5tw6RbVtOIbzzgr-hmN0s1XQs5qIJguA,6244
|
|
39
39
|
scaffold_ca_python/factory/entry_points/ep_restapi.py,sha256=PFkt9TH1aN6YO8w4zAeoqFOuibC8oc7qJUbFfX9YI_U,5951
|
|
40
40
|
scaffold_ca_python/factory/pipelines/__init__.py,sha256=0YPpPGsZ6A3-udHTSZDyUHleLFLQQh1V5IL6AB0qJ6g,557
|
|
41
41
|
scaffold_ca_python/factory/pipelines/pipeline_factory.py,sha256=s4fpuyhdxXiwko-LlM6Pv-QJdRGQJb17KVrC-DW6ojo,842
|
|
42
42
|
scaffold_ca_python/factory/simple/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
scaffold_ca_python/factory/simple/delete_module_factory.py,sha256=
|
|
43
|
+
scaffold_ca_python/factory/simple/delete_module_factory.py,sha256=v_Kl-m7bxvCwUsdQuCPq66uPksuLFLYvbsTNdE4Cs8Q,1696
|
|
44
44
|
scaffold_ca_python/factory/simple/helper_factory.py,sha256=nBVOu_kGBVrEGnXFa918GPo-UFlcW-Y5-Uk6bwYWuhQ,2295
|
|
45
45
|
scaffold_ca_python/factory/simple/model_factory.py,sha256=YdUpBvGgUrz4zzXMG2p8d6PWit62B9esjLZG49dT5PU,2467
|
|
46
|
-
scaffold_ca_python/factory/simple/use_case_factory.py,sha256=
|
|
46
|
+
scaffold_ca_python/factory/simple/use_case_factory.py,sha256=CUY2SkneFWv-KukK-Cdn2KoLZwgYukNa25Hv15SQYx8,1986
|
|
47
47
|
scaffold_ca_python/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
48
|
scaffold_ca_python/models/context.py,sha256=Itp-YyPgY-0yNYA9YlCXrmPfa5nEVklGAOJQGHfBdHE,1909
|
|
49
49
|
scaffold_ca_python/models/file_operation.py,sha256=R5Tu3KBvUnSmH5QZXBQTPoQjvr4YdH1YOKsKS9ICH_Q,1698
|
|
@@ -70,13 +70,15 @@ scaffold_ca_python/templates/entry_point/generic/entrypoint_main.py.jinja2,sha25
|
|
|
70
70
|
scaffold_ca_python/templates/entry_point/generic/handler.py.jinja2,sha256=glCst1soTiKG_gDdq5C-OogzljOJ_QooaW_boYt7gsg,417
|
|
71
71
|
scaffold_ca_python/templates/entry_point/generic/test_handler.py.jinja2,sha256=gRhvVabkylQ8z06JZ9L2CHdTa83oxL1X4ldR3_DZQWg,1195
|
|
72
72
|
scaffold_ca_python/templates/entry_point/mcp/__init__.py.jinja2,sha256=8J_YmIXHUh26PkaxeM8z5lf-dtK0da1T4haOM8U6Y9A,38
|
|
73
|
-
scaffold_ca_python/templates/entry_point/mcp/app.py.jinja2,sha256=
|
|
73
|
+
scaffold_ca_python/templates/entry_point/mcp/app.py.jinja2,sha256=2Kfi3AjRvJi7ee1vO0PyUa4pfX8j1GcsHO89GmQy6JU,1948
|
|
74
74
|
scaffold_ca_python/templates/entry_point/mcp/prompts.py.jinja2,sha256=PUFRtuWlEzR7bg7zY0O8dx-5tNrEZXrNZ5XgBoUMulQ,765
|
|
75
75
|
scaffold_ca_python/templates/entry_point/mcp/resources.py.jinja2,sha256=ZV_2WwklhSGhVFel3stS00zmPJuTlznfvFrpiM9dDKo,840
|
|
76
|
+
scaffold_ca_python/templates/entry_point/mcp/routes.py.jinja2,sha256=_JRXwnCMSJ-YBhEsxs-2JuVVQQ5sLeDDnkGB_8E4UJs,752
|
|
76
77
|
scaffold_ca_python/templates/entry_point/mcp/server.py.jinja2,sha256=gVzJm_ugY9E7-1RYIfbEKduDR71gluq4l3OB_aTRr1w,656
|
|
77
|
-
scaffold_ca_python/templates/entry_point/mcp/test_app.py.jinja2,sha256=
|
|
78
|
+
scaffold_ca_python/templates/entry_point/mcp/test_app.py.jinja2,sha256=mvP2BXW_OK4HvPjl1dfHs-y7r9FIYViJ3BCBtAqX8iY,1643
|
|
78
79
|
scaffold_ca_python/templates/entry_point/mcp/test_prompts.py.jinja2,sha256=Y9C7z7jpjoTKANlFB6hNJUUw2abt5qF2C4Nm7MkvDvA,1566
|
|
79
80
|
scaffold_ca_python/templates/entry_point/mcp/test_resources.py.jinja2,sha256=2jHfPqyJ4TJZJupxe8T7gVz2ysaqZHcAog6186ie2CI,1763
|
|
81
|
+
scaffold_ca_python/templates/entry_point/mcp/test_routes.py.jinja2,sha256=aYVWQXiRguziMtOnvZc5uwnhgYhsH87yrIDPM4gz95g,753
|
|
80
82
|
scaffold_ca_python/templates/entry_point/mcp/test_tool_stub.py.jinja2,sha256=Tq4uDcZc77bCC9gCVidmM5HmtjPfACaHBoQW0qEhIWo,295
|
|
81
83
|
scaffold_ca_python/templates/entry_point/mcp/test_tools.py.jinja2,sha256=bd_8nvLuqPApKIYQoBhEokMYZrPYFUn1pnDEIOVxwCo,1550
|
|
82
84
|
scaffold_ca_python/templates/entry_point/mcp/tool_stub.py.jinja2,sha256=VaGWAUF-BFQ7EeOHXUHQ2H-Mzr1UfbfziDsS7EVWUCc,289
|
|
@@ -119,10 +121,10 @@ scaffold_ca_python/templates/project/application/config/container.py.jinja2,sha2
|
|
|
119
121
|
scaffold_ca_python/templates/project/application/config/driven_adapters_container.py.jinja2,sha256=WhRpupvLP8tOJgp4IJ0A5RitntfRPVFjCDUjhAhBt8U,464
|
|
120
122
|
scaffold_ca_python/templates/project/application/config/resource_container.py.jinja2,sha256=k3wy8uSD7GJZNEf379fv2lMEzdq5eaNqmoaOw9Jq1vs,643
|
|
121
123
|
scaffold_ca_python/templates/project/application/config/usecases_container.py.jinja2,sha256=3fEHe6mkXkDHlfO5nhLqzLB7ccTpqwtjHZfLyfysbro,527
|
|
122
|
-
scaffold_ca_python/templates/use_case/test_use_case.py.jinja2,sha256=
|
|
124
|
+
scaffold_ca_python/templates/use_case/test_use_case.py.jinja2,sha256=spomnRHeXWiWjy3QHQt839yIMFDUqA7h-Wq4KfZxAyg,372
|
|
123
125
|
scaffold_ca_python/templates/use_case/use_case.py.jinja2,sha256=KPtaK1wvZ-7qHdDZyuVfqXTPYwJdNUMPXQZGuKZFA7Y,217
|
|
124
|
-
scaffold_ca_python-0.
|
|
125
|
-
scaffold_ca_python-0.
|
|
126
|
-
scaffold_ca_python-0.
|
|
127
|
-
scaffold_ca_python-0.
|
|
128
|
-
scaffold_ca_python-0.
|
|
126
|
+
scaffold_ca_python-0.5.0.dist-info/METADATA,sha256=LzgbMKXGUltT5VqAjcy4iM1WLe3EzI65blOTxX8N6Cw,7475
|
|
127
|
+
scaffold_ca_python-0.5.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
128
|
+
scaffold_ca_python-0.5.0.dist-info/entry_points.txt,sha256=4PyYg6mNCvAlt2yF_o1-QR2CBXiowYGpNyqcP88tu6I,104
|
|
129
|
+
scaffold_ca_python-0.5.0.dist-info/licenses/LICENSE,sha256=3ZZEP7DK_h3lEjS8r-DvQCec2q7zAqqq7HmSq6cuL0E,1068
|
|
130
|
+
scaffold_ca_python-0.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|