kctl-api 0.2.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.
Files changed (66) hide show
  1. kctl_api/__init__.py +3 -0
  2. kctl_api/__main__.py +5 -0
  3. kctl_api/cli.py +238 -0
  4. kctl_api/commands/__init__.py +1 -0
  5. kctl_api/commands/ai.py +250 -0
  6. kctl_api/commands/aliases.py +84 -0
  7. kctl_api/commands/apps.py +172 -0
  8. kctl_api/commands/auth.py +313 -0
  9. kctl_api/commands/automation.py +242 -0
  10. kctl_api/commands/build_cmd.py +87 -0
  11. kctl_api/commands/clean.py +182 -0
  12. kctl_api/commands/config_cmd.py +443 -0
  13. kctl_api/commands/dashboard.py +139 -0
  14. kctl_api/commands/db.py +599 -0
  15. kctl_api/commands/deploy.py +84 -0
  16. kctl_api/commands/deps.py +289 -0
  17. kctl_api/commands/dev.py +136 -0
  18. kctl_api/commands/docker_cmd.py +252 -0
  19. kctl_api/commands/doctor_cmd.py +286 -0
  20. kctl_api/commands/env.py +289 -0
  21. kctl_api/commands/files.py +250 -0
  22. kctl_api/commands/fmt_cmd.py +58 -0
  23. kctl_api/commands/health.py +479 -0
  24. kctl_api/commands/jobs.py +169 -0
  25. kctl_api/commands/lint_cmd.py +81 -0
  26. kctl_api/commands/logs.py +258 -0
  27. kctl_api/commands/marketplace.py +316 -0
  28. kctl_api/commands/monitor_cmd.py +243 -0
  29. kctl_api/commands/notifications.py +132 -0
  30. kctl_api/commands/odoo_proxy.py +182 -0
  31. kctl_api/commands/openapi.py +299 -0
  32. kctl_api/commands/perf.py +307 -0
  33. kctl_api/commands/rate_limit.py +223 -0
  34. kctl_api/commands/realtime.py +100 -0
  35. kctl_api/commands/redis_cmd.py +609 -0
  36. kctl_api/commands/routes_cmd.py +277 -0
  37. kctl_api/commands/saas.py +145 -0
  38. kctl_api/commands/scaffold.py +362 -0
  39. kctl_api/commands/security_cmd.py +350 -0
  40. kctl_api/commands/services.py +191 -0
  41. kctl_api/commands/shell.py +197 -0
  42. kctl_api/commands/skill_cmd.py +58 -0
  43. kctl_api/commands/streams.py +309 -0
  44. kctl_api/commands/stripe_cmd.py +105 -0
  45. kctl_api/commands/tenant_ai.py +169 -0
  46. kctl_api/commands/test_cmd.py +95 -0
  47. kctl_api/commands/users.py +302 -0
  48. kctl_api/commands/webhooks.py +56 -0
  49. kctl_api/commands/workflows.py +127 -0
  50. kctl_api/commands/ws.py +323 -0
  51. kctl_api/core/__init__.py +1 -0
  52. kctl_api/core/async_client.py +120 -0
  53. kctl_api/core/callbacks.py +88 -0
  54. kctl_api/core/client.py +190 -0
  55. kctl_api/core/config.py +260 -0
  56. kctl_api/core/db.py +65 -0
  57. kctl_api/core/exceptions.py +43 -0
  58. kctl_api/core/output.py +5 -0
  59. kctl_api/core/plugins.py +26 -0
  60. kctl_api/core/redis.py +35 -0
  61. kctl_api/core/resolve.py +47 -0
  62. kctl_api/core/utils.py +109 -0
  63. kctl_api-0.2.0.dist-info/METADATA +34 -0
  64. kctl_api-0.2.0.dist-info/RECORD +66 -0
  65. kctl_api-0.2.0.dist-info/WHEEL +4 -0
  66. kctl_api-0.2.0.dist-info/entry_points.txt +2 -0
kctl_api/core/utils.py ADDED
@@ -0,0 +1,109 @@
1
+ """Shared utility functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ # Known apps in the kodemeio-fastapi monorepo
8
+ KNOWN_APPS: dict[str, dict[str, str]] = {
9
+ "api-main": {"type": "API", "port": "8000", "module": "kodemeio_api_main"},
10
+ "ai-main": {"type": "AI API", "port": "8010", "module": "kodemeio_ai_main"},
11
+ "odoo-mm": {"type": "Integration", "port": "8003", "module": "kodemeio_odoo_mm"},
12
+ "plane-mm": {"type": "Integration", "port": "8004", "module": "kodemeio_plane_mm"},
13
+ "webhook-github": {"type": "Webhook", "port": "8005", "module": "kodemeio_webhook_github"},
14
+ "webhook-chatwoot": {"type": "Webhook", "port": "8006", "module": "kodemeio_webhook_chatwoot"},
15
+ "events-sync": {"type": "Events", "port": "", "module": "kodemeio_events_sync"},
16
+ "agent-main": {"type": "Agent", "port": "", "module": "kodemeio_agent_main"},
17
+ "etl-main": {"type": "ETL", "port": "", "module": "kodemeio_etl_main"},
18
+ "mcp-main": {"type": "MCP", "port": "", "module": "kodemeio_mcp_main"},
19
+ "scheduler-main": {"type": "Scheduler", "port": "", "module": "kodemeio_scheduler_main"},
20
+ "stream-main": {"type": "Stream", "port": "8002", "module": "kodemeio_stream_main"},
21
+ "ctl-main": {"type": "CLI", "port": "", "module": "kodemeio_cli_main"},
22
+ "tenant-ai-main": {"type": "Tenant AI", "port": "", "module": "kodemeio_tenant_ai_main"},
23
+ }
24
+
25
+
26
+ def service_status_color(status: str) -> str:
27
+ """Return Rich color markup for service status."""
28
+ colors = {
29
+ "running": "[green]running[/green]",
30
+ "healthy": "[green]healthy[/green]",
31
+ "unhealthy": "[red]unhealthy[/red]",
32
+ "stopped": "[dim]stopped[/dim]",
33
+ "starting": "[yellow]starting[/yellow]",
34
+ "error": "[red]error[/red]",
35
+ "ok": "[green]ok[/green]",
36
+ }
37
+ return colors.get(status.lower(), status)
38
+
39
+
40
+ def role_color(role: str) -> str:
41
+ """Return Rich color markup for user role."""
42
+ colors = {
43
+ "admin": "[bold red]admin[/bold red]",
44
+ "user": "[cyan]user[/cyan]",
45
+ }
46
+ return colors.get(role.lower(), role)
47
+
48
+
49
+ def tier_color(tier: str) -> str:
50
+ """Return Rich color markup for user tier."""
51
+ colors = {
52
+ "admin": "[bold red]admin[/bold red]",
53
+ "premium": "[bold yellow]premium[/bold yellow]",
54
+ "user": "[cyan]user[/cyan]",
55
+ "free": "[dim]free[/dim]",
56
+ }
57
+ return colors.get(tier.lower(), tier)
58
+
59
+
60
+ def find_project_root() -> Path:
61
+ """Find the kodemeio-fastapi project root.
62
+
63
+ Resolution order:
64
+ 1. Walk up from CWD looking for markers (pyproject.toml with kodemeio-fastapi, docker-compose.yml + apps/)
65
+ 2. Read ``project_root`` from config profile (~/.config/kodemeio/config.yaml)
66
+ 3. Fall back to CWD
67
+ """
68
+ # 1. CWD walk (fast, no config I/O)
69
+ cwd = Path.cwd()
70
+ for parent in [cwd, *cwd.parents]:
71
+ pyproject = parent / "pyproject.toml"
72
+ if pyproject.exists():
73
+ try:
74
+ content = pyproject.read_text()
75
+ if 'name = "kodemeio-fastapi"' in content:
76
+ return parent
77
+ except Exception:
78
+ pass
79
+ if (parent / "docker-compose.yml").exists() and (parent / "apps").is_dir():
80
+ return parent
81
+
82
+ # 2. Config profile fallback
83
+ try:
84
+ from kctl_api.core.config import get_project_root_from_config
85
+
86
+ config_root = get_project_root_from_config()
87
+ if config_root is not None:
88
+ return config_root
89
+ except Exception:
90
+ pass
91
+
92
+ # 3. CWD fallback
93
+ return cwd
94
+
95
+
96
+ def human_size(size_bytes: int | float) -> str:
97
+ """Format byte count as human-readable string."""
98
+ for unit in ("B", "KB", "MB", "GB", "TB"):
99
+ if abs(size_bytes) < 1024:
100
+ return f"{size_bytes:.1f} {unit}"
101
+ size_bytes /= 1024
102
+ return f"{size_bytes:.1f} PB"
103
+
104
+
105
+ def mask_secret(value: str, show_chars: int = 4) -> str:
106
+ """Mask a secret string, showing only the last N characters."""
107
+ if not value or len(value) <= show_chars:
108
+ return "***"
109
+ return f"***{value[-show_chars:]}"
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: kctl-api
3
+ Version: 0.2.0
4
+ Summary: Kodemeio API CLI - manage your FastAPI platform
5
+ Author-email: Kodemeio <dev@kodeme.io>
6
+ License-Expression: MIT
7
+ Keywords: api,cli,fastapi,kodemeio,rest
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: System Administrators
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: System :: Systems Administration
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: httpx>=0.28.0
17
+ Requires-Dist: kctl-lib>=0.4.0
18
+ Provides-Extra: all
19
+ Requires-Dist: asyncpg>=0.30.0; extra == 'all'
20
+ Requires-Dist: redis>=5.0.0; extra == 'all'
21
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.0; extra == 'all'
22
+ Provides-Extra: db
23
+ Requires-Dist: asyncpg>=0.30.0; extra == 'db'
24
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.0; extra == 'db'
25
+ Provides-Extra: dev
26
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
27
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
28
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
29
+ Requires-Dist: pytest-httpx>=0.35.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
32
+ Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
33
+ Provides-Extra: redis
34
+ Requires-Dist: redis>=5.0.0; extra == 'redis'
@@ -0,0 +1,66 @@
1
+ kctl_api/__init__.py,sha256=Vlkbhn3ncthEoN2V5MLQn_eeMajEIW9Hh0LbHX8JJIE,57
2
+ kctl_api/__main__.py,sha256=zxgO82u5ch50ue_nnR-X7JfCFzpM0hr88sq5FFAp4bo,82
3
+ kctl_api/cli.py,sha256=InWwpo1KXciTHQW3Z6YNdknEHUGTsPCcWawsJit14FE,9113
4
+ kctl_api/commands/__init__.py,sha256=fNB66xHJTlbQl3f7UQralX19ZSDz6P1mWY9gcnGnw-o,35
5
+ kctl_api/commands/ai.py,sha256=dqkT-QmfJEHEnmzyA0CuiCPruowBjtQ3nAuNaK3OTT4,8100
6
+ kctl_api/commands/aliases.py,sha256=wjK_Pk03BDPJNj6_U3-9fRCF3I1RI0hDvZx2plPyuMc,3026
7
+ kctl_api/commands/apps.py,sha256=YLgD6j_pN5n78q-yjuPBqn8iQNhBYYfq9NGJvjI_3w8,5154
8
+ kctl_api/commands/auth.py,sha256=nmWvqQarf1lQcyhpzG2rl3R44hc1gKyKR6Cy1FVZ24c,10278
9
+ kctl_api/commands/automation.py,sha256=U6t21LmAPl8pwvGE4H-I_xCz47lIoNmRv-hn2ZyHt7c,7845
10
+ kctl_api/commands/build_cmd.py,sha256=Om2wllEfl-TDdI3voleuMmeHyMwvcjB_Flrgh4qUcZg,2805
11
+ kctl_api/commands/clean.py,sha256=lObvQMwRa7Urr2cg1496lqekR4UodWjVtT3ABmnDQt4,6568
12
+ kctl_api/commands/config_cmd.py,sha256=5-duFy9mOKCFJCgWzYno73YiAGG0AkiUtrHg8glWXkI,14510
13
+ kctl_api/commands/dashboard.py,sha256=7E1_whoQcYHRC5pGKt_eN5tLZ4e5W8YfPK8LmvXnyEU,4808
14
+ kctl_api/commands/db.py,sha256=QI-V9lo9S0qOGqFifX7jE45RDvlCMNT7jFfIOx3VBj4,20069
15
+ kctl_api/commands/deploy.py,sha256=VYeu20I4PJdqBHK75JVWO3QyAn1hQdqSp-id7oYQeRI,3070
16
+ kctl_api/commands/deps.py,sha256=iqQVTfmqxwcbfSPiJGf8y-PkiAASAQEiShAfJocW6bk,9991
17
+ kctl_api/commands/dev.py,sha256=G6RYlaFDMJBHeGrNJmmjAsAeu-mrHT32AzJvPy-ljlI,4803
18
+ kctl_api/commands/docker_cmd.py,sha256=G1JQpy3zTLuhUGLunDNy6Z96njqUlLa6oQuSnpMV3SI,7524
19
+ kctl_api/commands/doctor_cmd.py,sha256=wrtqVDrbB0NekGQth7Cj1Ip72HluU3wkM6-Jp8e3OsM,9170
20
+ kctl_api/commands/env.py,sha256=ZhjLlfEZQQ058B7SbmXXK8lrCfd2W03B89BqkLm1qs4,10092
21
+ kctl_api/commands/files.py,sha256=wEjvUuwmdhmx_jdj94aXRC5Buf3GqNTwj9-aqaIF6tU,8348
22
+ kctl_api/commands/fmt_cmd.py,sha256=3R1qHRSe9ubwsfupFkWko1PHBTX5XpD02TVE1qpE9RU,1732
23
+ kctl_api/commands/health.py,sha256=KQpoKVqjKEfLAtGXS00K6bpofCyZAOlBsx0foqjcOUg,16159
24
+ kctl_api/commands/jobs.py,sha256=liM0FfkQdaMxPjSPMZbgOfSQNAheQwNxzPkgfvFM6gE,5286
25
+ kctl_api/commands/lint_cmd.py,sha256=5I1P0JdKSjgtIhH-K8pj3o_vO2nkY7EbnQ8sYcA7sBI,2375
26
+ kctl_api/commands/logs.py,sha256=aYuThlOHIaFJuWsJRPEfnSIZKLi_pISVl9lhaDvlyr8,9146
27
+ kctl_api/commands/marketplace.py,sha256=4xIGZ9QjMHVklpc4FHxcY41trvkRCInRiwGAb_RaOrM,10153
28
+ kctl_api/commands/monitor_cmd.py,sha256=27xCojDxGjFIuhIcXgD3nBWE8XZbeUHQPQMQny9lIjc,8797
29
+ kctl_api/commands/notifications.py,sha256=LFLd8d9rY_MytfQI_a7UoDIBX3yPqEcz88QxmFPRor4,4466
30
+ kctl_api/commands/odoo_proxy.py,sha256=swMvBUMHubOfvdVWuB9Z5gpJ1ThM0IEoIQt5IX4oBVE,6104
31
+ kctl_api/commands/openapi.py,sha256=lYiedbo3oC8PoNjNeygCCuYLitwphWnG_u6e_7jH_Z0,10552
32
+ kctl_api/commands/perf.py,sha256=m8cdZfWFTyKaeSEIYD6odN0H6tLrencePkGYBTF5Gg4,10919
33
+ kctl_api/commands/rate_limit.py,sha256=r5YE1TTUwypTSWZacjPT0LtU3cS7yMpVNCud3-sm74g,7570
34
+ kctl_api/commands/realtime.py,sha256=D6c46aSnsLp1S0r_Y8ATIMJ2qQbesTvmzuzNEDOZMqo,3248
35
+ kctl_api/commands/redis_cmd.py,sha256=i4ISRaXYKs0Z-nMVJo4C2MqtT9SuTyG4Xf2JXOQAQ4s,19194
36
+ kctl_api/commands/routes_cmd.py,sha256=5TaDVF5OV--JoookRjPynaERPNuUpHMCoiCHzsswXfU,9247
37
+ kctl_api/commands/saas.py,sha256=Mz3S_b1gydiDq-aKSXNmOCezfeU-be19Vm4bcKcnCGI,4710
38
+ kctl_api/commands/scaffold.py,sha256=zg1l-niKLOZfM_tBDcTgQepaN3BCv2kmMzsm-gCMuI0,12720
39
+ kctl_api/commands/security_cmd.py,sha256=4j29fMbDMO8LZ89qphYqWTGnV0GwQOkSc9gNcjQhw4U,12022
40
+ kctl_api/commands/services.py,sha256=66fq1imKJa5acRF96sWoOohfNCpIdCcsLSck61Ff9gE,6216
41
+ kctl_api/commands/shell.py,sha256=95jqn1u4WSp36zMgaNu5mXptkNnKDAmel8Lx9_ahA38,5336
42
+ kctl_api/commands/skill_cmd.py,sha256=8SxwdX3e8flNOqYheu4tY6HZcJ592VBXxuPFk8STIgw,1772
43
+ kctl_api/commands/streams.py,sha256=2i-JWV--JVWK8KCCH1au-wjuD6ztLkD12aOqBNgZIQ4,10071
44
+ kctl_api/commands/stripe_cmd.py,sha256=segH1LsyPZp2oE7vcKHBmIOnQrCtCTH8uHZFkrTOtks,3497
45
+ kctl_api/commands/tenant_ai.py,sha256=lJ1Ucn0AfBqcobSvIMNCOWTThE6FTJNhP_ZgcL0szSM,5473
46
+ kctl_api/commands/test_cmd.py,sha256=C0CKOwUuYG-xZNEo9sDYq0lNY7t7dLo35YjfSmgnfBU,3256
47
+ kctl_api/commands/users.py,sha256=R0X7prMNgngzljYEQ55I88mhF9kzZ1TSz1U7hMDTvdQ,10039
48
+ kctl_api/commands/webhooks.py,sha256=1ae0TzT50es6cvXqf6dQp26g2jogcsOL5Rd9aotjoQg,2245
49
+ kctl_api/commands/workflows.py,sha256=NgJwF5RzqyL4hmGCUoy7a_cUWyvURlLD_sSAMhy3UOM,4059
50
+ kctl_api/commands/ws.py,sha256=Nf4wq_TuT7jEsF3u5mh7JQykh3rXnGhyh_dSXRpHwtk,11858
51
+ kctl_api/core/__init__.py,sha256=1E1CQ_u3wHjRaO3ZJ531KP1r_ZaCjz1nvvcg_0t5Vbw,40
52
+ kctl_api/core/async_client.py,sha256=cQXfu7CnJFeu1b7of0cc0afBYnH9aC7YcPvc0wGuYgs,4097
53
+ kctl_api/core/callbacks.py,sha256=te9QQ3qObkKZbdToH5r3OSK5RPkN-E7pt7xaoTFtRN0,2978
54
+ kctl_api/core/client.py,sha256=Q2yYCoKwmLwUSck0DBG1yxeYF8VPuzyh2jxvhQeh3V8,6845
55
+ kctl_api/core/config.py,sha256=Izk2nH85K311QYN01X1FA6x7hutnMUIMSNGKY0zbKGw,7745
56
+ kctl_api/core/db.py,sha256=-dm1oVGA4Evg7nWTb9U-g90Pq-gMQ4CjdczQD3Rv_RA,1843
57
+ kctl_api/core/exceptions.py,sha256=FRU2C2u2BuWVeqXUNfajsQ9bZu_7x-psDTOdQ_e5NEg,1155
58
+ kctl_api/core/output.py,sha256=irTgk_u3pGmOEViFXq1Tr10SFB0qFqiAc9hwpig7Dw8,110
59
+ kctl_api/core/plugins.py,sha256=8yOowxgD7ykeraDSyWw3zMqCgNSKYRuzV5bW9366tdg,847
60
+ kctl_api/core/redis.py,sha256=GC5ZP8SuSZ1GD76V2W-DHHStfPKKHdMxkZOdb1kL-qs,932
61
+ kctl_api/core/resolve.py,sha256=_7FdRQbFOJyFWnWwGCw-7Ox3638G0eNzr3PnPWlZ3jM,1297
62
+ kctl_api/core/utils.py,sha256=o7bZLOA_33pUtsdp3kFu_lXqEiySNAH3qS3xAH2y1ZY,4072
63
+ kctl_api-0.2.0.dist-info/METADATA,sha256=WwDI6Wood7eexcgg6lLZNdqIVl7dNnxqod4rd0YAupw,1354
64
+ kctl_api-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
65
+ kctl_api-0.2.0.dist-info/entry_points.txt,sha256=rkHu58uDHn-s_Fjj4_JyGzjlkAqdhOe-ptvjXCZwDRw,47
66
+ kctl_api-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ kctl-api = kctl_api.cli:_run