csrd-utils 0.3.45__tar.gz → 0.3.47__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.
Files changed (87) hide show
  1. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/PKG-INFO +1 -1
  2. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/pyproject.toml +1 -1
  3. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/__main__.py +4 -8
  4. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/cluster.py +31 -14
  5. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/generator.py +61 -15
  6. csrd_utils-0.3.45/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/pyproject.toml +0 -58
  7. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/.gitignore +0 -0
  8. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/README.md +0 -0
  9. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/__init__.py +0 -0
  10. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/audit.py +0 -0
  11. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/augmentor.py +0 -0
  12. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/doctor.py +0 -0
  13. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
  14. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
  15. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/manifest.yaml +0 -0
  16. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/requirements.fragment +0 -0
  17. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
  18. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
  19. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
  20. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
  21. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/manifest.yaml +0 -0
  22. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/requirements.fragment +0 -0
  23. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
  24. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
  25. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
  26. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
  27. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
  28. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
  29. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
  30. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
  31. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
  32. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
  33. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
  34. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
  35. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
  36. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
  37. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
  38. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
  39. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
  40. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
  41. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/manifest.yaml +0 -0
  42. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/requirements.fragment +0 -0
  43. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
  44. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
  45. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
  46. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
  47. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
  48. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/fragments.py +0 -0
  49. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/resources.py +0 -0
  50. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
  51. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
  52. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
  53. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.cookiecutterignore +0 -0
  54. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  55. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  56. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  57. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  58. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/cache.py +0 -0
  59. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
  60. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/upstreams.py +0 -0
  61. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  62. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/delegates.py +0 -0
  63. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
  64. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/worker_broker.py +0 -0
  65. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/docker-compose.yml +0 -0
  66. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/__init__.py +0 -0
  67. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/logging.py +0 -0
  68. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/py.typed +0 -0
  69. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  70. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
  71. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  72. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  73. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
  74. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/test_logging_middleware.py +0 -0
  75. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
  76. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/test_items.py +0 -0
  77. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_cache.py +0 -0
  78. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_database_settings.py +0 -0
  79. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_delegates.py +0 -0
  80. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_settings_contracts.py +0 -0
  81. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_worker_broker.py +0 -0
  82. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  83. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  84. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  85. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
  86. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/__init__.py +0 -0
  87. {csrd_utils-0.3.45 → csrd_utils-0.3.47}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csrd-utils
3
- Version: 0.3.45
3
+ Version: 0.3.47
4
4
  Summary: CLI utilities for csrd service generation and feature augmentation
5
5
  Project-URL: Repository, https://github.com/csrd-api/fastapi-common
6
6
  Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/utils
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "csrd-utils"
3
- version = "0.3.45"
3
+ version = "0.3.47"
4
4
  description = "CLI utilities for csrd service generation and feature augmentation"
5
5
  license = { text = "MIT" }
6
6
  requires-python = ">=3.12"
@@ -784,9 +784,7 @@ def _extract_service(config: ExtractWorkspaceServiceArgs) -> dict[str, object]:
784
784
  _load_workspace_cluster_spec(target_workspace), source_service_spec, target_workspace.name
785
785
  )
786
786
  _save_workspace_cluster_spec(target_workspace, target_spec)
787
- target_cluster_root = generate_cluster(
788
- target_spec, target_workspace, force=True, workspace_mode=True
789
- )
787
+ target_cluster_root = generate_cluster(target_spec, target_workspace, force=True)
790
788
 
791
789
  source_cluster_root = None
792
790
  if mode == "move":
@@ -795,9 +793,7 @@ def _extract_service(config: ExtractWorkspaceServiceArgs) -> dict[str, object]:
795
793
  _load_workspace_cluster_spec(source_workspace), service_root.name, source_workspace.name
796
794
  )
797
795
  _save_workspace_cluster_spec(source_workspace, source_spec)
798
- source_cluster_root = generate_cluster(
799
- source_spec, source_workspace, force=True, workspace_mode=True
800
- )
796
+ source_cluster_root = generate_cluster(source_spec, source_workspace, force=True)
801
797
 
802
798
  return {
803
799
  "ok": True,
@@ -897,7 +893,7 @@ def _maybe_update_workspace_cluster(
897
893
  service_config,
898
894
  overwrite=service_config["overwrite_if_exists"],
899
895
  )
900
- return generate_cluster(updated_spec, workspace_root, force=True, workspace_mode=True)
896
+ return generate_cluster(updated_spec, workspace_root, force=True)
901
897
 
902
898
  service_roots = _workspace_service_roots(workspace_root)
903
899
  generated_name = generated_service.name
@@ -914,7 +910,7 @@ def _maybe_update_workspace_cluster(
914
910
  }
915
911
  normalized = normalize_cluster_spec(bootstrap_spec)
916
912
  _save_workspace_cluster_spec(workspace_root, normalized)
917
- return generate_cluster(normalized, workspace_root, force=True, workspace_mode=True)
913
+ return generate_cluster(normalized, workspace_root, force=True)
918
914
 
919
915
 
920
916
  def _build_parser() -> argparse.ArgumentParser:
@@ -426,6 +426,21 @@ def _build_readme(spec: ClusterSpec) -> str:
426
426
  lines.append(f"- `{service['name']}` ({service['type']}) on port `{service['port']}`")
427
427
  lines.extend(
428
428
  [
429
+ "",
430
+ "## Tests",
431
+ "",
432
+ "From the workspace root, run all tests:",
433
+ "",
434
+ "```bash",
435
+ "pytest",
436
+ "```",
437
+ "",
438
+ "Run tests for a specific service:",
439
+ "",
440
+ "```bash",
441
+ "pytest tests/unit/{service_name}",
442
+ "pytest tests/acceptance/{service_name}",
443
+ "```",
429
444
  "",
430
445
  "## Run",
431
446
  "",
@@ -456,23 +471,20 @@ def _build_smoke(spec: ClusterSpec) -> str:
456
471
  return "\n".join(lines) + "\n"
457
472
 
458
473
 
459
- def generate_cluster(
460
- spec: ClusterSpec, output_dir: Path, force: bool = False, workspace_mode: bool = False
461
- ) -> Path:
462
- normalized = normalize_cluster_spec(spec)
463
-
464
- if workspace_mode:
465
- # In workspace mode, write files directly to output_dir (workspace root)
466
- cluster_root = output_dir.resolve()
467
- else:
468
- # In standalone mode, create a subdirectory with cluster name
469
- cluster_root = output_dir.resolve() / normalized["cluster"]["name"]
474
+ def generate_cluster(spec: ClusterSpec, output_dir: Path, force: bool = False) -> Path:
475
+ """Generate cluster scaffold in workspace mode.
470
476
 
477
+ Always operates at workspace root (no standalone mode).
478
+ """
479
+ normalized = normalize_cluster_spec(spec)
480
+ cluster_root = output_dir.resolve()
471
481
  cluster_root.mkdir(parents=True, exist_ok=True)
472
482
 
473
- if any(cluster_root.iterdir()) and not force:
483
+ # In workspace mode, check if we'd overwrite existing cluster artifacts
484
+ compose_file = cluster_root / "docker-compose.yml"
485
+ if compose_file.exists() and not force:
474
486
  raise FileExistsError(
475
- f"Target directory already exists and is not empty: {cluster_root}. Use --force to overwrite."
487
+ f"Cluster files already exist in {cluster_root}. Use --force to overwrite."
476
488
  )
477
489
 
478
490
  compose = render_compose(normalized)
@@ -480,7 +492,12 @@ def generate_cluster(
480
492
  yaml.safe_dump(compose, sort_keys=False), encoding="utf-8"
481
493
  )
482
494
  (cluster_root / ".env.example").write_text(_build_env(normalized), encoding="utf-8")
483
- (cluster_root / "README.md").write_text(_build_readme(normalized), encoding="utf-8")
495
+
496
+ # In workspace mode, preserve existing README (workspace-level, not cluster-specific)
497
+ readme_path = cluster_root / "README.md"
498
+ if not readme_path.exists():
499
+ readme_path.write_text(_build_readme(normalized), encoding="utf-8")
500
+
484
501
  smoke_path = cluster_root / "smoke.sh"
485
502
  smoke_path.write_text(_build_smoke(normalized), encoding="utf-8")
486
503
  smoke_path.chmod(0o755)
@@ -9,14 +9,64 @@ from cookiecutter.main import cookiecutter
9
9
 
10
10
  from .resources import templates_path
11
11
 
12
- _WORKSPACE_PYTEST_TOML = """\
13
- # Workspace-level tool configuration.
14
- # Add [project] and [build-system] sections if you need to publish this workspace as a package.
12
+ _WORKSPACE_PYPROJECT_BASE = """\
13
+ [build-system]
14
+ requires = ["hatchling"]
15
+ build-backend = "hatchling.build"
16
+
17
+ [project]
18
+ name = "workspace"
19
+ version = "0.1.0"
20
+ description = "Multi-service workspace"
21
+ readme = "README.md"
22
+ requires-python = ">=3.12"
23
+ license = {text = "MIT"}
24
+
25
+ dependencies = [
26
+ "fastapi>=0.110",
27
+ "uvicorn[standard]>=0.27",
28
+ "pydantic[email]>=2.5",
29
+ "csrd-versioning>=0.1.0",
30
+ "csrd-lifespan>=0.1.0",
31
+ "csrd-repository>=0.1.0",
32
+ "csrd-context>=0.1.0",
33
+ "httpx>=0.25",
34
+ "celery[redis]>=5.3",
35
+ "celery[amqp]>=5.3",
36
+ "redis>=5.0",
37
+ "csrd-logging>=0.1.0",
38
+ ]
39
+
40
+ [project.optional-dependencies]
41
+ dev = [
42
+ "pytest>=7.4",
43
+ "pytest-asyncio>=0.21",
44
+ "mypy>=1.7",
45
+ "ruff>=0.1",
46
+ ]
15
47
 
16
48
  [tool.pytest.ini_options]
17
49
  asyncio_mode = "auto"
18
50
  testpaths = ["tests"]
19
51
  pythonpath = ["src"]
52
+
53
+ [tool.mypy]
54
+ python_version = "3.12"
55
+ warn_return_any = true
56
+ warn_unused_configs = true
57
+ disallow_untyped_defs = true
58
+ strict = true
59
+
60
+ [tool.ruff]
61
+ target-version = "py312"
62
+ line-length = 100
63
+
64
+ [tool.ruff.lint]
65
+ select = ["E", "F", "W", "I", "N", "UP", "BLE", "FBT", "A", "C4", "PIE", "SIM", "RUF"]
66
+ ignore = ["E501"]
67
+
68
+ [tool.ruff.lint.isort]
69
+ known-first-party = [""]
20
70
  """
21
71
 
22
72
  _WORKSPACE_README = """\
@@ -257,25 +307,21 @@ def _move_tests_to_workspace_root(
257
307
 
258
308
 
259
309
  def _write_workspace_pyproject(workspace_root: Path) -> None:
260
- """Write or update workspace-level pyproject.toml with pytest configuration.
310
+ """Write workspace-level pyproject.toml with full build/project/tool configuration.
261
311
 
262
- If the file does not exist it is created from scratch. If it already exists
263
- and already contains a ``[tool.pytest.ini_options]`` section it is left
264
- untouched (the user may have customised it). Otherwise the pytest block is
265
- appended so that a second ``generate_service`` call on the same workspace
266
- gains the config without clobbering prior edits.
312
+ Creates complete pyproject.toml on first generation. On subsequent generations,
313
+ only writes if the file doesn't exist or lacks [project] section (user customization).
267
314
  """
268
315
  dst = workspace_root / "pyproject.toml"
269
316
  if dst.exists():
270
317
  existing = dst.read_text(encoding="utf-8")
271
- if "[tool.pytest.ini_options]" in existing:
318
+ # If user already has a [project] section, assume they customized it
319
+ if "[project]" in existing:
272
320
  return
273
- dst.write_text(
274
- existing.rstrip() + "\n\n" + _WORKSPACE_PYTEST_TOML,
275
- encoding="utf-8",
276
- )
321
+ # Otherwise write the full base config
322
+ dst.write_text(_WORKSPACE_PYPROJECT_BASE, encoding="utf-8")
277
323
  else:
278
- dst.write_text(_WORKSPACE_PYTEST_TOML, encoding="utf-8")
324
+ dst.write_text(_WORKSPACE_PYPROJECT_BASE, encoding="utf-8")
279
325
 
280
326
 
281
327
  def _write_workspace_readme(workspace_root: Path) -> None:
@@ -1,58 +0,0 @@
1
- [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
4
-
5
- [project]
6
- name = "{{ cookiecutter.service_name }}"
7
- version = "0.1.0"
8
- description = "{{ cookiecutter.service_description }}"
9
- readme = "README.md"
10
- requires-python = ">=3.12"
11
- license = {text = "MIT"}
12
- authors = [{name = "Generated by csrd", email = "generated@csrd.local"}]
13
- keywords = ["fastapi", "microservice", "csrd"]
14
-
15
- dependencies = [
16
- "fastapi>=0.110",
17
- "uvicorn[standard]>=0.27",
18
- "pydantic[email]>=2.5",
19
- "csrd-versioning @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/versioning",
20
- "csrd-lifespan @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/lifespan",
21
- "csrd-repository @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/repository",
22
- "csrd-context @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/context",
23
- "httpx>=0.25",
24
- "celery[redis]>=5.3",
25
- "celery[amqp]>=5.3",
26
- "redis>=5.0",
27
- "csrd-logging @ git+https://github.com/csrd-api/fastapi-common.git#subdirectory=packages/logging",
28
- ]
29
-
30
- [project.optional-dependencies]
31
- dev = [
32
- "pytest>=7.4",
33
- "pytest-asyncio>=0.21",
34
- "mypy>=1.7",
35
- "ruff>=0.1",
36
- ]
37
-
38
- [tool.hatch.build.targets.wheel]
39
- packages = ["{{cookiecutter.__service_name_snake}}"]
40
-
41
-
42
- [tool.mypy]
43
- python_version = "3.12"
44
- warn_return_any = true
45
- warn_unused_configs = true
46
- disallow_untyped_defs = true
47
- strict = true
48
-
49
- [tool.ruff]
50
- target-version = "py312"
51
- line-length = 100
52
-
53
- [tool.ruff.lint]
54
- select = ["E", "F", "W", "I", "N", "UP", "BLE", "FBT", "A", "C4", "PIE", "SIM", "RUF"]
55
- ignore = ["E501"]
56
-
57
- [tool.ruff.lint.isort]
58
- known-first-party = ["{{cookiecutter.__service_name_snake}}"]
File without changes
File without changes