quantum-framework 0.18.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 (333) hide show
  1. quantum/__init__.py +1 -0
  2. quantum/cli/__init__.py +2 -0
  3. quantum/cli/admin.py +131 -0
  4. quantum/cli/check.py +223 -0
  5. quantum/cli/commands/__init__.py +15 -0
  6. quantum/cli/commands/build.py +414 -0
  7. quantum/cli/commands/dev.py +185 -0
  8. quantum/cli/commands/docs.py +329 -0
  9. quantum/cli/commands/lint.py +523 -0
  10. quantum/cli/commands/migrate.py +548 -0
  11. quantum/cli/commands/new.py +622 -0
  12. quantum/cli/commands/serve.py +190 -0
  13. quantum/cli/commands/test.py +193 -0
  14. quantum/cli/deploy.py +810 -0
  15. quantum/cli/hot_reload.py +951 -0
  16. quantum/cli/jobs.py +356 -0
  17. quantum/cli/mq.py +582 -0
  18. quantum/cli/pkg.py +390 -0
  19. quantum/cli/runner.py +565 -0
  20. quantum/cli/server_process.py +159 -0
  21. quantum/cli/utils.py +334 -0
  22. quantum/compiler/__init__.py +30 -0
  23. quantum/compiler/base_generator.py +367 -0
  24. quantum/compiler/cli.py +295 -0
  25. quantum/compiler/expression_transformer.py +444 -0
  26. quantum/compiler/javascript/__init__.py +10 -0
  27. quantum/compiler/javascript/generator.py +659 -0
  28. quantum/compiler/optimizer.py +270 -0
  29. quantum/compiler/python/__init__.py +10 -0
  30. quantum/compiler/python/generator.py +883 -0
  31. quantum/compiler/python/runtime.py +863 -0
  32. quantum/compiler/transpiler.py +330 -0
  33. quantum/core/__init__.py +3 -0
  34. quantum/core/ast_nodes.py +2619 -0
  35. quantum/core/config_env.py +54 -0
  36. quantum/core/docs_links.py +8 -0
  37. quantum/core/expression_diagnostics.py +87 -0
  38. quantum/core/expression_stdlib.py +208 -0
  39. quantum/core/expressions.py +677 -0
  40. quantum/core/features/agents/src/__init__.py +30 -0
  41. quantum/core/features/agents/src/ast_node.py +540 -0
  42. quantum/core/features/conditionals/src/__init__.py +8 -0
  43. quantum/core/features/conditionals/src/ast_node.py +68 -0
  44. quantum/core/features/data_import/src/__init__.py +0 -0
  45. quantum/core/features/data_import/src/ast_node.py +292 -0
  46. quantum/core/features/data_import/src/runtime.py +533 -0
  47. quantum/core/features/dump/src/__init__.py +12 -0
  48. quantum/core/features/dump/src/ast_node.py +106 -0
  49. quantum/core/features/dump/src/parser.py +61 -0
  50. quantum/core/features/dump/src/runtime.py +246 -0
  51. quantum/core/features/functions/src/__init__.py +8 -0
  52. quantum/core/features/functions/src/ast_node.py +149 -0
  53. quantum/core/features/game_engine_2d/src/__init__.py +19 -0
  54. quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
  55. quantum/core/features/game_engine_2d/src/parser.py +983 -0
  56. quantum/core/features/invocation/src/__init__.py +0 -0
  57. quantum/core/features/invocation/src/ast_node.py +147 -0
  58. quantum/core/features/invocation/src/runtime.py +332 -0
  59. quantum/core/features/knowledge_base/src/__init__.py +6 -0
  60. quantum/core/features/knowledge_base/src/ast_node.py +113 -0
  61. quantum/core/features/knowledge_base/src/parser.py +82 -0
  62. quantum/core/features/logging/src/__init__.py +12 -0
  63. quantum/core/features/logging/src/ast_node.py +111 -0
  64. quantum/core/features/logging/src/parser.py +50 -0
  65. quantum/core/features/logging/src/runtime.py +190 -0
  66. quantum/core/features/loops/src/__init__.py +8 -0
  67. quantum/core/features/loops/src/ast_node.py +60 -0
  68. quantum/core/features/query/src/__init__.py +0 -0
  69. quantum/core/features/query/src/query_validators.py +20 -0
  70. quantum/core/features/state_management/src/__init__.py +11 -0
  71. quantum/core/features/state_management/src/ast_node.py +121 -0
  72. quantum/core/features/terminal_engine/src/__init__.py +21 -0
  73. quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
  74. quantum/core/features/terminal_engine/src/parser.py +361 -0
  75. quantum/core/features/testing_engine/src/__init__.py +41 -0
  76. quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
  77. quantum/core/features/testing_engine/src/parser.py +604 -0
  78. quantum/core/features/theming/src/__init__.py +48 -0
  79. quantum/core/features/theming/src/ast_node.py +137 -0
  80. quantum/core/features/theming/src/presets.py +405 -0
  81. quantum/core/features/ui_engine/src/__init__.py +20 -0
  82. quantum/core/features/ui_engine/src/ast_nodes.py +1913 -0
  83. quantum/core/features/ui_engine/src/parser.py +1192 -0
  84. quantum/core/features/websocket/src/__init__.py +24 -0
  85. quantum/core/features/websocket/src/ast_node.py +247 -0
  86. quantum/core/guards.py +53 -0
  87. quantum/core/html_compat.py +299 -0
  88. quantum/core/parser.py +1551 -0
  89. quantum/core/parser_registry.py +213 -0
  90. quantum/core/parsers/__init__.py +76 -0
  91. quantum/core/parsers/ai/__init__.py +12 -0
  92. quantum/core/parsers/ai/agent_parser.py +106 -0
  93. quantum/core/parsers/ai/knowledge_parser.py +86 -0
  94. quantum/core/parsers/ai/llm_parser.py +78 -0
  95. quantum/core/parsers/ai/team_parser.py +88 -0
  96. quantum/core/parsers/base.py +322 -0
  97. quantum/core/parsers/composition/__init__.py +10 -0
  98. quantum/core/parsers/composition/import_parser.py +50 -0
  99. quantum/core/parsers/composition/slot_parser.py +48 -0
  100. quantum/core/parsers/control_flow/__init__.py +11 -0
  101. quantum/core/parsers/control_flow/if_parser.py +71 -0
  102. quantum/core/parsers/control_flow/loop_parser.py +105 -0
  103. quantum/core/parsers/control_flow/set_parser.py +93 -0
  104. quantum/core/parsers/data/__init__.py +12 -0
  105. quantum/core/parsers/data/data_parser.py +229 -0
  106. quantum/core/parsers/data/invoke_parser.py +133 -0
  107. quantum/core/parsers/data/query_parser.py +213 -0
  108. quantum/core/parsers/data/transaction_parser.py +86 -0
  109. quantum/core/parsers/events/__init__.py +9 -0
  110. quantum/core/parsers/events/dispatch_event_parser.py +44 -0
  111. quantum/core/parsers/forms/__init__.py +11 -0
  112. quantum/core/parsers/forms/action_parser.py +79 -0
  113. quantum/core/parsers/forms/flash_parser.py +34 -0
  114. quantum/core/parsers/forms/redirect_parser.py +33 -0
  115. quantum/core/parsers/functions/__init__.py +11 -0
  116. quantum/core/parsers/functions/function_parser.py +98 -0
  117. quantum/core/parsers/functions/param_parser.py +73 -0
  118. quantum/core/parsers/functions/return_parser.py +31 -0
  119. quantum/core/parsers/html/__init__.py +10 -0
  120. quantum/core/parsers/html/component_call_parser.py +130 -0
  121. quantum/core/parsers/html/html_parser.py +115 -0
  122. quantum/core/parsers/jobs/__init__.py +11 -0
  123. quantum/core/parsers/jobs/job_parser.py +71 -0
  124. quantum/core/parsers/jobs/schedule_parser.py +62 -0
  125. quantum/core/parsers/jobs/thread_parser.py +57 -0
  126. quantum/core/parsers/messaging/__init__.py +17 -0
  127. quantum/core/parsers/messaging/message_ack_parser.py +30 -0
  128. quantum/core/parsers/messaging/message_nack_parser.py +30 -0
  129. quantum/core/parsers/messaging/message_parser.py +114 -0
  130. quantum/core/parsers/messaging/queue_parser.py +61 -0
  131. quantum/core/parsers/messaging/websocket_parser.py +121 -0
  132. quantum/core/parsers/routing/__init__.py +9 -0
  133. quantum/core/parsers/routing/route_parser.py +41 -0
  134. quantum/core/parsers/scripting/__init__.py +12 -0
  135. quantum/core/parsers/scripting/pyclass_parser.py +62 -0
  136. quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
  137. quantum/core/parsers/scripting/pyimport_parser.py +52 -0
  138. quantum/core/parsers/scripting/python_parser.py +49 -0
  139. quantum/core/parsers/services/__init__.py +12 -0
  140. quantum/core/parsers/services/dump_parser.py +52 -0
  141. quantum/core/parsers/services/file_parser.py +48 -0
  142. quantum/core/parsers/services/log_parser.py +46 -0
  143. quantum/core/parsers/services/mail_parser.py +65 -0
  144. quantum/core/tiers.py +164 -0
  145. quantum/core/xml_lines.py +81 -0
  146. quantum/packages/__init__.py +28 -0
  147. quantum/packages/manager.py +413 -0
  148. quantum/packages/manifest.py +351 -0
  149. quantum/packages/registry.py +399 -0
  150. quantum/packages/resolver.py +336 -0
  151. quantum/plugins/__init__.py +33 -0
  152. quantum/plugins/hooks.py +329 -0
  153. quantum/plugins/loader.py +479 -0
  154. quantum/plugins/manifest.py +336 -0
  155. quantum/plugins/registry.py +371 -0
  156. quantum/runtime/__init__.py +25 -0
  157. quantum/runtime/action_handler.py +532 -0
  158. quantum/runtime/adapters/__init__.py +88 -0
  159. quantum/runtime/adapters/memory_adapter.py +690 -0
  160. quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
  161. quantum/runtime/adapters/redis_adapter.py +582 -0
  162. quantum/runtime/adapters/sqlite_adapter.py +414 -0
  163. quantum/runtime/agent_service.py +1133 -0
  164. quantum/runtime/ast_cache.py +506 -0
  165. quantum/runtime/auth_service.py +267 -0
  166. quantum/runtime/component.py +1048 -0
  167. quantum/runtime/component_composer.py +133 -0
  168. quantum/runtime/component_resolver.py +174 -0
  169. quantum/runtime/conditions.py +54 -0
  170. quantum/runtime/database_service.py +595 -0
  171. quantum/runtime/db_schema.py +100 -0
  172. quantum/runtime/dev_panel.py +178 -0
  173. quantum/runtime/email_service.py +162 -0
  174. quantum/runtime/error_handler.py +295 -0
  175. quantum/runtime/execution_context.py +283 -0
  176. quantum/runtime/executor_registry.py +178 -0
  177. quantum/runtime/executors/__init__.py +71 -0
  178. quantum/runtime/executors/ai/__init__.py +12 -0
  179. quantum/runtime/executors/ai/agent_executor.py +217 -0
  180. quantum/runtime/executors/ai/knowledge_executor.py +114 -0
  181. quantum/runtime/executors/ai/llm_executor.py +153 -0
  182. quantum/runtime/executors/ai/team_executor.py +171 -0
  183. quantum/runtime/executors/base.py +264 -0
  184. quantum/runtime/executors/control_flow/__init__.py +12 -0
  185. quantum/runtime/executors/control_flow/if_executor.py +98 -0
  186. quantum/runtime/executors/control_flow/loop_executor.py +308 -0
  187. quantum/runtime/executors/control_flow/redirect_executor.py +43 -0
  188. quantum/runtime/executors/control_flow/set_executor.py +464 -0
  189. quantum/runtime/executors/data/__init__.py +12 -0
  190. quantum/runtime/executors/data/data_executor.py +156 -0
  191. quantum/runtime/executors/data/invoke_executor.py +228 -0
  192. quantum/runtime/executors/data/query_executor.py +290 -0
  193. quantum/runtime/executors/data/transaction_executor.py +91 -0
  194. quantum/runtime/executors/jobs/__init__.py +11 -0
  195. quantum/runtime/executors/jobs/job_executor.py +190 -0
  196. quantum/runtime/executors/jobs/schedule_executor.py +132 -0
  197. quantum/runtime/executors/jobs/thread_executor.py +127 -0
  198. quantum/runtime/executors/messaging/__init__.py +17 -0
  199. quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
  200. quantum/runtime/executors/messaging/message_executor.py +174 -0
  201. quantum/runtime/executors/messaging/queue_executor.py +103 -0
  202. quantum/runtime/executors/messaging/websocket_executor.py +197 -0
  203. quantum/runtime/executors/scripting/__init__.py +11 -0
  204. quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
  205. quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
  206. quantum/runtime/executors/scripting/python_executor.py +249 -0
  207. quantum/runtime/executors/services/__init__.py +12 -0
  208. quantum/runtime/executors/services/dump_executor.py +72 -0
  209. quantum/runtime/executors/services/file_executor.py +89 -0
  210. quantum/runtime/executors/services/log_executor.py +77 -0
  211. quantum/runtime/executors/services/mail_executor.py +81 -0
  212. quantum/runtime/expression_cache.py +498 -0
  213. quantum/runtime/file_upload_service.py +326 -0
  214. quantum/runtime/function_registry.py +118 -0
  215. quantum/runtime/game_builder.py +166 -0
  216. quantum/runtime/game_code_generator.py +2371 -0
  217. quantum/runtime/game_templates.py +2006 -0
  218. quantum/runtime/godot_code_generator.py +4681 -0
  219. quantum/runtime/godot_templates.py +1449 -0
  220. quantum/runtime/job_executor.py +1599 -0
  221. quantum/runtime/knowledge_service.py +546 -0
  222. quantum/runtime/llm_cache.py +100 -0
  223. quantum/runtime/llm_providers.py +704 -0
  224. quantum/runtime/llm_service.py +287 -0
  225. quantum/runtime/local_server.py +28 -0
  226. quantum/runtime/logging_setup.py +141 -0
  227. quantum/runtime/message_broker.py +364 -0
  228. quantum/runtime/message_queue_service.py +571 -0
  229. quantum/runtime/param_validation.py +218 -0
  230. quantum/runtime/pypy_compat.py +317 -0
  231. quantum/runtime/python_bridge.py +698 -0
  232. quantum/runtime/query_validators.py +304 -0
  233. quantum/runtime/renderer.py +734 -0
  234. quantum/runtime/service_container.py +470 -0
  235. quantum/runtime/table_params.py +163 -0
  236. quantum/runtime/terminal_builder.py +76 -0
  237. quantum/runtime/terminal_code_generator.py +607 -0
  238. quantum/runtime/terminal_templates.py +243 -0
  239. quantum/runtime/testing_builder.py +77 -0
  240. quantum/runtime/testing_code_generator.py +833 -0
  241. quantum/runtime/testing_templates.py +85 -0
  242. quantum/runtime/ui_builder.py +222 -0
  243. quantum/runtime/ui_console.py +405 -0
  244. quantum/runtime/ui_desktop.py +56 -0
  245. quantum/runtime/ui_form_rules.py +193 -0
  246. quantum/runtime/ui_html_adapter.py +2567 -0
  247. quantum/runtime/ui_html_templates.py +2106 -0
  248. quantum/runtime/ui_mobile_adapter.py +1832 -0
  249. quantum/runtime/ui_mobile_templates.py +1003 -0
  250. quantum/runtime/ui_page_renderer.py +392 -0
  251. quantum/runtime/ui_pager.py +73 -0
  252. quantum/runtime/ui_table_edit.py +139 -0
  253. quantum/runtime/ui_textual_adapter.py +1866 -0
  254. quantum/runtime/ui_textual_templates.py +45 -0
  255. quantum/runtime/ui_tokens.py +465 -0
  256. quantum/runtime/ui_validator.py +365 -0
  257. quantum/runtime/ui_view.py +221 -0
  258. quantum/runtime/validators.py +256 -0
  259. quantum/runtime/web_server.py +2131 -0
  260. quantum/runtime/websocket_adapter.py +501 -0
  261. quantum/runtime/websocket_service.py +585 -0
  262. quantum/runtime/websocket_transport.py +289 -0
  263. quantum/runtime/wsgi.py +101 -0
  264. quantum/services.py +109 -0
  265. quantum/utils/__init__.py +1 -0
  266. quantum_admin/__init__.py +4 -0
  267. quantum_admin/assets/quantum-admin-connectors.js +123 -0
  268. quantum_admin/assets/quantum-admin.css +2058 -0
  269. quantum_admin/assets/quantum-source-highlight.js +106 -0
  270. quantum_admin/backend/__init__.py +4 -0
  271. quantum_admin/backend/audit_service.py +346 -0
  272. quantum_admin/backend/auth_service.py +394 -0
  273. quantum_admin/backend/component_discovery.py +766 -0
  274. quantum_admin/backend/config_generator.py +586 -0
  275. quantum_admin/backend/connector_service.py +1016 -0
  276. quantum_admin/backend/crud.py +557 -0
  277. quantum_admin/backend/database.py +226 -0
  278. quantum_admin/backend/db_setup_service.py +193 -0
  279. quantum_admin/backend/deploy_service.py +698 -0
  280. quantum_admin/backend/docker_service.py +422 -0
  281. quantum_admin/backend/environment_service.py +418 -0
  282. quantum_admin/backend/git_service.py +370 -0
  283. quantum_admin/backend/health_service.py +390 -0
  284. quantum_admin/backend/job_service.py +347 -0
  285. quantum_admin/backend/log_service.py +331 -0
  286. quantum_admin/backend/main.py +14426 -0
  287. quantum_admin/backend/models.py +986 -0
  288. quantum_admin/backend/pipeline_service.py +812 -0
  289. quantum_admin/backend/resource_manager.py +1118 -0
  290. quantum_admin/backend/schemas.py +419 -0
  291. quantum_admin/backend/secret_manager.py +277 -0
  292. quantum_admin/backend/settings_service.py +488 -0
  293. quantum_admin/backend/template_service.py +710 -0
  294. quantum_admin/backend/test_execution_service.py +364 -0
  295. quantum_admin/backend/test_generator.py +782 -0
  296. quantum_admin/backend/webhook_service.py +454 -0
  297. quantum_admin/backend/websocket_manager.py +360 -0
  298. quantum_admin/components/admin/_layout/AdminShell.q +121 -0
  299. quantum_admin/components/admin/agents.q +107 -0
  300. quantum_admin/components/admin/app/[name].q +558 -0
  301. quantum_admin/components/admin/applications.q +160 -0
  302. quantum_admin/components/admin/component/[...path].q +205 -0
  303. quantum_admin/components/admin/components.q +59 -0
  304. quantum_admin/components/admin/connectors.q +283 -0
  305. quantum_admin/components/admin/dashboard.q +86 -0
  306. quantum_admin/components/admin/database.q +95 -0
  307. quantum_admin/components/admin/features.q +69 -0
  308. quantum_admin/components/admin/index.q +12 -0
  309. quantum_admin/components/admin/jobs.q +75 -0
  310. quantum_admin/components/admin/login.q +65 -0
  311. quantum_admin/components/admin/logout.q +11 -0
  312. quantum_admin/components/admin/settings.q +174 -0
  313. quantum_admin/components/admin/source.q +45 -0
  314. quantum_admin/components/admin/tests.q +73 -0
  315. quantum_admin/run.py +13 -0
  316. quantum_admin/services/__init__.py +16 -0
  317. quantum_admin/services/_base.py +84 -0
  318. quantum_admin/services/_component_test_generator.py +205 -0
  319. quantum_admin/services/_yaml_editor.py +82 -0
  320. quantum_admin/services/apps.py +330 -0
  321. quantum_admin/services/auth.py +61 -0
  322. quantum_admin/services/components.py +210 -0
  323. quantum_admin/services/connectors.py +164 -0
  324. quantum_admin/services/projects.py +189 -0
  325. quantum_admin/services/repository.py +223 -0
  326. quantum_admin/services/settings.py +150 -0
  327. quantum_admin/services/yaml_import.py +118 -0
  328. quantum_framework-0.18.0.dist-info/METADATA +281 -0
  329. quantum_framework-0.18.0.dist-info/RECORD +333 -0
  330. quantum_framework-0.18.0.dist-info/WHEEL +5 -0
  331. quantum_framework-0.18.0.dist-info/entry_points.txt +2 -0
  332. quantum_framework-0.18.0.dist-info/licenses/LICENSE +21 -0
  333. quantum_framework-0.18.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,226 @@
1
+ """
2
+ Database configuration and session management
3
+ """
4
+ import os
5
+ from datetime import datetime
6
+ from sqlalchemy import create_engine
7
+ from sqlalchemy.orm import sessionmaker
8
+ from .models import Base
9
+
10
+ # SQLite database file location - use absolute path relative to quantum_admin folder
11
+ _QUANTUM_ADMIN_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
12
+ _DB_PATH = os.path.join(_QUANTUM_ADMIN_DIR, "quantum_admin.db")
13
+
14
+ # QUANTUM_ADMIN_DATABASE_URL overrides the location. The path used to be fixed,
15
+ # so the admin test suite created and deleted rows in the same database the
16
+ # admin serves — every `pytest` run wrote into the developer's real data.
17
+ DATABASE_URL = os.environ.get("QUANTUM_ADMIN_DATABASE_URL") or f"sqlite:///{_DB_PATH}"
18
+
19
+ # Create engine with SQLite-specific settings
20
+ engine = create_engine(
21
+ DATABASE_URL,
22
+ connect_args={"check_same_thread": False} if DATABASE_URL.startswith("sqlite") else {},
23
+ echo=False # Set to True for SQL query logging during development
24
+ )
25
+
26
+ # Create session factory
27
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
28
+
29
+
30
+ def init_db():
31
+ """
32
+ Initialize database - create all tables
33
+ Call this on application startup
34
+ """
35
+ Base.metadata.create_all(bind=engine)
36
+ print("[OK] Database initialized successfully")
37
+
38
+
39
+ def seed_db():
40
+ """
41
+ Seed database with sample data if empty
42
+ """
43
+ from . import models
44
+ import uuid
45
+
46
+ db = SessionLocal()
47
+ try:
48
+ # Check if we already have data
49
+ existing_projects = db.query(models.Project).first()
50
+ if existing_projects:
51
+ print("[OK] Database already has data, skipping seed")
52
+ return
53
+
54
+ print("[INFO] Seeding database with sample data...")
55
+
56
+ # Create sample projects
57
+ projects = [
58
+ models.Project(
59
+ name="Blog Application",
60
+ description="A full-featured blog with posts, comments, and user authentication",
61
+ status="active"
62
+ ),
63
+ models.Project(
64
+ name="E-Commerce API",
65
+ description="REST API for an e-commerce platform with products, orders, and payments",
66
+ status="active"
67
+ ),
68
+ models.Project(
69
+ name="Dashboard App",
70
+ description="Real-time analytics dashboard with charts and data visualization",
71
+ status="inactive"
72
+ ),
73
+ ]
74
+ for p in projects:
75
+ db.add(p)
76
+ db.flush()
77
+
78
+ # Create sample connectors (id is String, required)
79
+ connectors = [
80
+ models.Connector(
81
+ id="postgres-prod",
82
+ name="PostgreSQL Production",
83
+ type="database",
84
+ provider="postgres",
85
+ host="db.example.com",
86
+ port=5432,
87
+ database="production",
88
+ status="connected"
89
+ ),
90
+ models.Connector(
91
+ id="redis-cache",
92
+ name="Redis Cache",
93
+ type="cache",
94
+ provider="redis",
95
+ host="redis.example.com",
96
+ port=6379,
97
+ status="connected"
98
+ ),
99
+ models.Connector(
100
+ id="s3-storage",
101
+ name="AWS S3 Storage",
102
+ type="storage",
103
+ provider="s3",
104
+ database="my-app-files",
105
+ status="disconnected"
106
+ ),
107
+ ]
108
+ for c in connectors:
109
+ db.add(c)
110
+
111
+ # Create sample environments for first project
112
+ environments = [
113
+ models.Environment(
114
+ name="dev",
115
+ display_name="Development",
116
+ project_id=1,
117
+ order=1,
118
+ branch="develop",
119
+ is_active=True
120
+ ),
121
+ models.Environment(
122
+ name="staging",
123
+ display_name="Staging",
124
+ project_id=1,
125
+ order=2,
126
+ branch="staging",
127
+ is_active=True
128
+ ),
129
+ models.Environment(
130
+ name="production",
131
+ display_name="Production",
132
+ project_id=1,
133
+ order=3,
134
+ branch="main",
135
+ requires_approval=True,
136
+ is_active=True
137
+ ),
138
+ ]
139
+ for e in environments:
140
+ db.add(e)
141
+
142
+ # Create sample application logs
143
+ from datetime import timedelta
144
+ sample_logs = [
145
+ models.ApplicationLog(
146
+ project_id=1,
147
+ timestamp=datetime.utcnow() - timedelta(minutes=5),
148
+ level="INFO",
149
+ source="app",
150
+ message="Application started successfully",
151
+ component_name="main"
152
+ ),
153
+ models.ApplicationLog(
154
+ project_id=1,
155
+ timestamp=datetime.utcnow() - timedelta(minutes=4),
156
+ level="INFO",
157
+ source="database",
158
+ message="Database connection established",
159
+ response_time_ms=45
160
+ ),
161
+ models.ApplicationLog(
162
+ project_id=1,
163
+ timestamp=datetime.utcnow() - timedelta(minutes=3),
164
+ level="INFO",
165
+ source="access",
166
+ message="GET /api/posts 200",
167
+ request_method="GET",
168
+ request_path="/api/posts",
169
+ response_status=200,
170
+ response_time_ms=120
171
+ ),
172
+ models.ApplicationLog(
173
+ project_id=1,
174
+ timestamp=datetime.utcnow() - timedelta(minutes=2),
175
+ level="WARNING",
176
+ source="api",
177
+ message="External API rate limit approaching",
178
+ component_name="oauth_service"
179
+ ),
180
+ models.ApplicationLog(
181
+ project_id=1,
182
+ timestamp=datetime.utcnow() - timedelta(minutes=1),
183
+ level="INFO",
184
+ source="security",
185
+ message="User login successful: admin@example.com",
186
+ component_name="auth"
187
+ ),
188
+ models.ApplicationLog(
189
+ project_id=1,
190
+ timestamp=datetime.utcnow(),
191
+ level="INFO",
192
+ source="deploy",
193
+ message="Deployment completed: v1.2.3",
194
+ component_name="deployer"
195
+ ),
196
+ ]
197
+ for log in sample_logs:
198
+ db.add(log)
199
+
200
+ db.commit()
201
+ print("[OK] Database seeded with sample data")
202
+
203
+ except Exception as e:
204
+ db.rollback()
205
+ print(f"[ERROR] Failed to seed database: {e}")
206
+ import traceback
207
+ traceback.print_exc()
208
+ finally:
209
+ db.close()
210
+
211
+
212
+ def get_db():
213
+ """
214
+ Dependency for FastAPI endpoints
215
+ Provides a database session and ensures cleanup
216
+
217
+ Usage:
218
+ @app.get("/items")
219
+ def get_items(db: Session = Depends(get_db)):
220
+ return db.query(Item).all()
221
+ """
222
+ db = SessionLocal()
223
+ try:
224
+ yield db
225
+ finally:
226
+ db.close()
@@ -0,0 +1,193 @@
1
+ """
2
+ Database Setup Service
3
+ Handles initial configuration of database containers
4
+ """
5
+ import logging
6
+ import time
7
+ import psycopg2
8
+ import pymysql
9
+ from pymongo import MongoClient
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class DatabaseSetupService:
15
+ """Service for setting up databases in containers"""
16
+
17
+ @staticmethod
18
+ def setup_database(datasource) -> tuple[bool, str]:
19
+ """
20
+ Setup database based on type
21
+
22
+ Returns:
23
+ tuple: (success: bool, message: str)
24
+ """
25
+ try:
26
+ db_type = datasource.type.lower()
27
+
28
+ if db_type == 'postgres':
29
+ return DatabaseSetupService._setup_postgres(datasource)
30
+ elif db_type in ['mysql', 'mariadb']:
31
+ return DatabaseSetupService._setup_mysql(datasource)
32
+ elif db_type == 'mongodb':
33
+ return DatabaseSetupService._setup_mongodb(datasource)
34
+ elif db_type == 'redis':
35
+ # Redis doesn't need setup
36
+ return True, "Redis is ready to use"
37
+ else:
38
+ return False, f"Unsupported database type: {db_type}"
39
+
40
+ except Exception as e:
41
+ logger.error(f"Database setup failed: {e}")
42
+ return False, str(e)
43
+
44
+ @staticmethod
45
+ def _setup_postgres(datasource) -> tuple[bool, str]:
46
+ """Setup PostgreSQL database"""
47
+ max_retries = 30
48
+ retry_delay = 2
49
+
50
+ for attempt in range(max_retries):
51
+ try:
52
+ # Connect to default postgres database
53
+ conn = psycopg2.connect(
54
+ host=datasource.host,
55
+ port=datasource.port,
56
+ database='postgres',
57
+ user=datasource.username,
58
+ password=datasource.password_encrypted,
59
+ connect_timeout=5
60
+ )
61
+ conn.autocommit = True
62
+ cursor = conn.cursor()
63
+
64
+ # Check if database exists
65
+ cursor.execute(
66
+ "SELECT 1 FROM pg_database WHERE datname = %s",
67
+ (datasource.database_name,)
68
+ )
69
+
70
+ if not cursor.fetchone():
71
+ # Create database
72
+ cursor.execute(
73
+ f'CREATE DATABASE "{datasource.database_name}" '
74
+ f'OWNER "{datasource.username}"'
75
+ )
76
+ logger.info(f"Created database: {datasource.database_name}")
77
+
78
+ cursor.close()
79
+ conn.close()
80
+
81
+ # Test connection to new database
82
+ test_conn = psycopg2.connect(
83
+ host=datasource.host,
84
+ port=datasource.port,
85
+ database=datasource.database_name,
86
+ user=datasource.username,
87
+ password=datasource.password_encrypted,
88
+ connect_timeout=5
89
+ )
90
+ test_conn.close()
91
+
92
+ return True, f"PostgreSQL database '{datasource.database_name}' is ready"
93
+
94
+ except psycopg2.OperationalError as e:
95
+ if attempt < max_retries - 1:
96
+ logger.info(f"Waiting for PostgreSQL to be ready... (attempt {attempt + 1}/{max_retries})")
97
+ time.sleep(retry_delay)
98
+ else:
99
+ return False, f"PostgreSQL failed to start: {str(e)}"
100
+ except Exception as e:
101
+ return False, f"PostgreSQL setup error: {str(e)}"
102
+
103
+ @staticmethod
104
+ def _setup_mysql(datasource) -> tuple[bool, str]:
105
+ """Setup MySQL/MariaDB database"""
106
+ max_retries = 30
107
+ retry_delay = 2
108
+
109
+ for attempt in range(max_retries):
110
+ try:
111
+ # Connect to MySQL server
112
+ conn = pymysql.connect(
113
+ host=datasource.host,
114
+ port=datasource.port,
115
+ user=datasource.username,
116
+ password=datasource.password_encrypted,
117
+ connect_timeout=5
118
+ )
119
+ cursor = conn.cursor()
120
+
121
+ # Create database if not exists
122
+ cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{datasource.database_name}`")
123
+
124
+ # Grant privileges
125
+ cursor.execute(
126
+ f"GRANT ALL PRIVILEGES ON `{datasource.database_name}`.* "
127
+ f"TO '{datasource.username}'@'%'"
128
+ )
129
+ cursor.execute("FLUSH PRIVILEGES")
130
+
131
+ cursor.close()
132
+ conn.close()
133
+
134
+ # Test connection to new database
135
+ test_conn = pymysql.connect(
136
+ host=datasource.host,
137
+ port=datasource.port,
138
+ database=datasource.database_name,
139
+ user=datasource.username,
140
+ password=datasource.password_encrypted,
141
+ connect_timeout=5
142
+ )
143
+ test_conn.close()
144
+
145
+ db_type = 'MariaDB' if datasource.type == 'mariadb' else 'MySQL'
146
+ return True, f"{db_type} database '{datasource.database_name}' is ready"
147
+
148
+ except pymysql.OperationalError as e:
149
+ if attempt < max_retries - 1:
150
+ logger.info(f"Waiting for MySQL/MariaDB to be ready... (attempt {attempt + 1}/{max_retries})")
151
+ time.sleep(retry_delay)
152
+ else:
153
+ return False, f"MySQL/MariaDB failed to start: {str(e)}"
154
+ except Exception as e:
155
+ return False, f"MySQL/MariaDB setup error: {str(e)}"
156
+
157
+ @staticmethod
158
+ def _setup_mongodb(datasource) -> tuple[bool, str]:
159
+ """Setup MongoDB database"""
160
+ max_retries = 30
161
+ retry_delay = 2
162
+
163
+ for attempt in range(max_retries):
164
+ try:
165
+ # Connect to MongoDB
166
+ client = MongoClient(
167
+ host=datasource.host,
168
+ port=datasource.port,
169
+ username=datasource.username,
170
+ password=datasource.password_encrypted,
171
+ serverSelectionTimeoutMS=5000
172
+ )
173
+
174
+ # Test connection
175
+ client.server_info()
176
+
177
+ # Create database (MongoDB creates it on first write)
178
+ db = client[datasource.database_name]
179
+
180
+ # Create a test collection to initialize the database
181
+ db.create_collection('_quantum_init')
182
+ db['_quantum_init'].insert_one({'initialized': True})
183
+
184
+ client.close()
185
+
186
+ return True, f"MongoDB database '{datasource.database_name}' is ready"
187
+
188
+ except Exception as e:
189
+ if attempt < max_retries - 1:
190
+ logger.info(f"Waiting for MongoDB to be ready... (attempt {attempt + 1}/{max_retries})")
191
+ time.sleep(retry_delay)
192
+ else:
193
+ return False, f"MongoDB failed to start: {str(e)}"