csrd-utils 0.3.55__tar.gz → 0.3.56__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.55 → csrd_utils-0.3.56}/PKG-INFO +1 -1
  2. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/pyproject.toml +1 -1
  3. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/__main__.py +76 -3
  4. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/.gitignore +0 -0
  5. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/README.md +0 -0
  6. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/__init__.py +0 -0
  7. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/audit.py +0 -0
  8. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/augmentor.py +0 -0
  9. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/cluster.py +0 -0
  10. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/doctor.py +0 -0
  11. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
  12. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
  13. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/manifest.yaml +0 -0
  14. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/requirements.fragment +0 -0
  15. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
  16. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
  17. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
  18. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
  19. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/manifest.yaml +0 -0
  20. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/requirements.fragment +0 -0
  21. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
  22. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
  23. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
  24. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
  25. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
  26. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
  27. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
  28. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
  29. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
  30. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
  31. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
  32. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
  33. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
  34. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
  35. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
  36. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
  37. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
  38. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
  39. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/manifest.yaml +0 -0
  40. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/requirements.fragment +0 -0
  41. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
  42. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
  43. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
  44. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
  45. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
  46. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/fragments.py +0 -0
  47. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/generator.py +0 -0
  48. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/resources.py +0 -0
  49. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
  50. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
  51. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
  52. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.cookiecutterignore +0 -0
  53. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/.dockerignore +0 -0
  54. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/Dockerfile +0 -0
  55. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/README.md +0 -0
  56. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/__init__.py +0 -0
  57. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/cache.py +0 -0
  58. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/__init__.py +0 -0
  59. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/delegates/upstreams.py +0 -0
  60. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/__init__.py +0 -0
  61. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/delegates.py +0 -0
  62. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/item_repository.py +0 -0
  63. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/dependencies/worker_broker.py +0 -0
  64. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/docker-compose.yml +0 -0
  65. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/__init__.py +0 -0
  66. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/middleware/logging.py +0 -0
  67. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/__init__.py +0 -0
  68. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/repositories/item_repository.py +0 -0
  69. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/requirements.txt +0 -0
  70. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/settings.py +0 -0
  71. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/__init__.py +0 -0
  72. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/__init__.py +0 -0
  73. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/acceptance/test_logging_middleware.py +0 -0
  74. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/conftest.py +0 -0
  75. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/test_items.py +0 -0
  76. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/__init__.py +0 -0
  77. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_cache.py +0 -0
  78. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_database_settings.py +0 -0
  79. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_delegates.py +0 -0
  80. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_settings_contracts.py +0 -0
  81. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/tests/unit/test_worker_broker.py +0 -0
  82. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/__init__.py +0 -0
  83. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/__init__.py +0 -0
  84. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/health_view.py +0 -0
  85. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/views/unversioned/items_view.py +0 -0
  86. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.__service_name_snake}}/workers/__init__.py +0 -0
  87. {csrd_utils-0.3.55 → csrd_utils-0.3.56}/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.55
3
+ Version: 0.3.56
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.55"
3
+ version = "0.3.56"
4
4
  description = "CLI utilities for csrd service generation and feature augmentation"
5
5
  license = { text = "MIT" }
6
6
  requires-python = ">=3.12"
@@ -346,7 +346,9 @@ def _collect_new_cluster_config(args: argparse.Namespace) -> GenerateClusterArgs
346
346
  )
347
347
 
348
348
  print("Interactive cluster mode: press Enter to accept defaults.")
349
- cluster_name = _prompt_text("Cluster name", args.name or "my-cluster")
349
+ cluster_name = (
350
+ _prompt_text("Cluster name", args.name or "my-cluster") if not args.name else args.name
351
+ )
350
352
  preset = _prompt_choice("Preset", list(PRESETS.keys()), args.preset)
351
353
  services: list[ServiceSpec] = []
352
354
 
@@ -436,6 +438,70 @@ def _create_workspace(config: GenerateWorkspaceArgs) -> Path:
436
438
  return workspace_root
437
439
 
438
440
 
441
+ def _generate_services_from_cluster_spec(
442
+ spec: ClusterSpec, workspace_root: Path, force: bool = False
443
+ ) -> list[Path]:
444
+ """Scaffold source trees for every service in a cluster spec that lacks one.
445
+
446
+ Derives generate_service arguments from each ServiceSpec so the resulting
447
+ workspace has src/<service>/ code alongside the compose wiring.
448
+ """
449
+
450
+ normalized = normalize_cluster_spec(spec)
451
+ services = normalized["services"]
452
+ port_map = {str(svc["name"]): int(svc["port"]) for svc in services}
453
+
454
+ generated: list[Path] = []
455
+ for service in services:
456
+ name = str(service["name"])
457
+ service_type = str(service["type"])
458
+ port = int(service["port"])
459
+ features = list(service.get("features", []))
460
+ delegates_list = list(service.get("delegates", []))
461
+ broker = str(service.get("broker", "redis"))
462
+
463
+ # Derive upstreams from delegate targets + their ports
464
+ upstreams = ",".join(f"http://{t}:{port_map[t]}" for t in delegates_list if t in port_map)
465
+
466
+ has_database = service_type == "db"
467
+ has_delegates = bool(delegates_list) or service_type == "delegate"
468
+ has_workers = service_type == "worker" or "workers" in features
469
+ has_caching = "caching" in features
470
+ has_structured_logging = "logging" in features
471
+ database = str(service.get("database", "sqlite")) if has_database else "sqlite"
472
+
473
+ src_dir = workspace_root / "src" / name.replace("-", "_")
474
+ if src_dir.exists() and any(src_dir.iterdir()) and not force:
475
+ print(f"Skipped existing service: {name}")
476
+ continue
477
+
478
+ try:
479
+ result = generate_service(
480
+ name=name,
481
+ output_dir=workspace_root,
482
+ description=f"{name} service",
483
+ port=port,
484
+ model_name="Item",
485
+ model_name_plural="items",
486
+ has_database=has_database,
487
+ database=database,
488
+ has_delegates=has_delegates,
489
+ upstreams=upstreams,
490
+ has_workers=has_workers,
491
+ broker=broker,
492
+ has_caching=has_caching,
493
+ cache_backend="redis",
494
+ has_structured_logging=has_structured_logging,
495
+ overwrite_if_exists=force,
496
+ )
497
+ generated.append(result)
498
+ print(f"Generated service: {name}")
499
+ except Exception as exc:
500
+ print(f"WARN: could not scaffold service '{name}': {exc}")
501
+
502
+ return generated
503
+
504
+
439
505
  def _default_service_namespace(output_dir: Path) -> argparse.Namespace:
440
506
  return argparse.Namespace(
441
507
  interactive=True,
@@ -461,7 +527,7 @@ def _default_service_namespace(output_dir: Path) -> argparse.Namespace:
461
527
  def _default_cluster_namespace(output_dir: Path) -> argparse.Namespace:
462
528
  return argparse.Namespace(
463
529
  spec=None,
464
- name=None,
530
+ name=output_dir.name, # Default cluster name to workspace folder name
465
531
  output=output_dir,
466
532
  preset="none",
467
533
  force=False,
@@ -1293,7 +1359,14 @@ def main() -> int:
1293
1359
  cluster_config["output_dir"],
1294
1360
  force=cluster_config["overwrite_if_exists"],
1295
1361
  )
1296
- print(f"Generated cluster at: {generated_cluster}")
1362
+ _save_workspace_cluster_spec(workspace_root, cluster_config["spec"])
1363
+ print(f"Generated cluster scaffold at: {generated_cluster}")
1364
+ scaffolded = _generate_services_from_cluster_spec(
1365
+ cluster_config["spec"],
1366
+ workspace_root,
1367
+ force=cluster_config["overwrite_if_exists"],
1368
+ )
1369
+ print(f"Scaffolded {len(scaffolded)} service(s) under src/.")
1297
1370
  except (FileExistsError, FileNotFoundError, ValueError) as exc:
1298
1371
  print(f"ERROR: {exc}")
1299
1372
  return 1
File without changes
File without changes