precis-cli 0.1.3__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 (442) hide show
  1. app/__init__.py +16 -0
  2. app/api/__init__.py +32 -0
  3. app/api/dependencies.py +185 -0
  4. app/api/main.py +301 -0
  5. app/api/middleware/__init__.py +34 -0
  6. app/api/middleware/exception_handler.py +126 -0
  7. app/api/middleware/request_logging.py +97 -0
  8. app/api/middleware/token_auth.py +215 -0
  9. app/api/models/__init__.py +151 -0
  10. app/api/models/connection_rules.py +98 -0
  11. app/api/models/files.py +99 -0
  12. app/api/models/full_validation.py +554 -0
  13. app/api/models/project.py +117 -0
  14. app/api/models/projects.py +80 -0
  15. app/api/models/schema.py +121 -0
  16. app/api/models/v2_responses.py +46 -0
  17. app/api/models/validation.py +303 -0
  18. app/api/models/workspace.py +118 -0
  19. app/api/routers/__init__.py +56 -0
  20. app/api/routers/ai/__init__.py +36 -0
  21. app/api/routers/ai/chat.py +243 -0
  22. app/api/routers/ai/generate.py +156 -0
  23. app/api/routers/ai/hardware.py +199 -0
  24. app/api/routers/ai/jobs.py +544 -0
  25. app/api/routers/ai/migrate.py +471 -0
  26. app/api/routers/ai/models.py +352 -0
  27. app/api/routers/ai/ollama.py +108 -0
  28. app/api/routers/ai/providers.py +491 -0
  29. app/api/routers/ai/router.py +44 -0
  30. app/api/routers/ai/stream.py +281 -0
  31. app/api/routers/ai/utils.py +182 -0
  32. app/api/routers/core/__init__.py +34 -0
  33. app/api/routers/core/connection_rules.py +188 -0
  34. app/api/routers/core/data_sources.py +374 -0
  35. app/api/routers/core/regex.py +333 -0
  36. app/api/routers/core/reporting.py +263 -0
  37. app/api/routers/files/__init__.py +24 -0
  38. app/api/routers/files/ops.py +179 -0
  39. app/api/routers/files/transfer.py +101 -0
  40. app/api/routers/preview/__init__.py +35 -0
  41. app/api/routers/preview/content_mode.py +264 -0
  42. app/api/routers/preview/header_row.py +154 -0
  43. app/api/routers/preview/models.py +81 -0
  44. app/api/routers/preview/path_mode.py +440 -0
  45. app/api/routers/preview/router.py +30 -0
  46. app/api/routers/project/__init__.py +61 -0
  47. app/api/routers/project/base.py +111 -0
  48. app/api/routers/project/constraint.py +345 -0
  49. app/api/routers/project/full_config.py +411 -0
  50. app/api/routers/project/full_config_writer.py +327 -0
  51. app/api/routers/project/helpers.py +167 -0
  52. app/api/routers/project/inspection_fix.py +330 -0
  53. app/api/routers/project/manifest.py +605 -0
  54. app/api/routers/project/models.py +177 -0
  55. app/api/routers/project/pattern.py +268 -0
  56. app/api/routers/project/regex.py +358 -0
  57. app/api/routers/project/scanner.py +157 -0
  58. app/api/routers/project/schema.py +567 -0
  59. app/api/routers/project/schema_helpers.py +149 -0
  60. app/api/routers/project/settings.py +399 -0
  61. app/api/routers/project/template.py +325 -0
  62. app/api/routers/project/validation.py +227 -0
  63. app/api/routers/project/view.py +177 -0
  64. app/api/routers/project/workspaces.py +167 -0
  65. app/api/routers/projects/__init__.py +25 -0
  66. app/api/routers/projects/create.py +121 -0
  67. app/api/routers/projects/open.py +103 -0
  68. app/api/routers/projects/scan.py +100 -0
  69. app/api/routers/validation/__init__.py +39 -0
  70. app/api/routers/validation/common.py +263 -0
  71. app/api/routers/validation/content_mode.py +401 -0
  72. app/api/routers/validation/history.py +235 -0
  73. app/api/routers/validation/inline_mode.py +196 -0
  74. app/api/routers/validation/path_mode.py +314 -0
  75. app/api/routers/validation/router.py +51 -0
  76. app/api/services/full_validation_response_builder.py +412 -0
  77. app/api/services/io_error_messages.py +41 -0
  78. app/api/services/preview_service.py +248 -0
  79. app/cli/__init__.py +18 -0
  80. app/cli/__main__.py +30 -0
  81. app/cli/shared_services/__init__.py +42 -0
  82. app/cli/shared_services/config_ops.py +581 -0
  83. app/cli/shared_services/generation_ops.py +160 -0
  84. app/cli/shared_services/project_ops.py +288 -0
  85. app/cli/shell/__init__.py +48 -0
  86. app/cli/shell/commands/__init__.py +63 -0
  87. app/cli/shell/commands/ai/__init__.py +260 -0
  88. app/cli/shell/commands/ai/chat.py +331 -0
  89. app/cli/shell/commands/ai/delete.py +165 -0
  90. app/cli/shell/commands/ai/diff.py +70 -0
  91. app/cli/shell/commands/ai/display.py +428 -0
  92. app/cli/shell/commands/ai/executor.py +225 -0
  93. app/cli/shell/commands/ai/executor_utils.py +271 -0
  94. app/cli/shell/commands/ai/generate.py +285 -0
  95. app/cli/shell/commands/ai/interaction.py +262 -0
  96. app/cli/shell/commands/ai/migrate.py +281 -0
  97. app/cli/shell/commands/ai/resolver.py +224 -0
  98. app/cli/shell/commands/ai/status.py +101 -0
  99. app/cli/shell/commands/ai/switch.py +158 -0
  100. app/cli/shell/commands/ai/utils.py +52 -0
  101. app/cli/shell/commands/base.py +343 -0
  102. app/cli/shell/commands/config/__init__.py +131 -0
  103. app/cli/shell/commands/config/base.py +80 -0
  104. app/cli/shell/commands/config/check.py +246 -0
  105. app/cli/shell/commands/config/edit.py +148 -0
  106. app/cli/shell/commands/config/get.py +111 -0
  107. app/cli/shell/commands/config/init.py +123 -0
  108. app/cli/shell/commands/config/inspect.py +164 -0
  109. app/cli/shell/commands/config/list.py +104 -0
  110. app/cli/shell/commands/config/set.py +119 -0
  111. app/cli/shell/commands/config/show.py +150 -0
  112. app/cli/shell/commands/exit.py +67 -0
  113. app/cli/shell/commands/help.py +104 -0
  114. app/cli/shell/commands/infer_schema.py +156 -0
  115. app/cli/shell/commands/open.py +201 -0
  116. app/cli/shell/commands/project.py +215 -0
  117. app/cli/shell/commands/provider.py +619 -0
  118. app/cli/shell/commands/system.py +170 -0
  119. app/cli/shell/commands/validate.py +455 -0
  120. app/cli/shell/completer.py +231 -0
  121. app/cli/shell/config_storage.py +191 -0
  122. app/cli/shell/exceptions.py +90 -0
  123. app/cli/shell/formatter.py +371 -0
  124. app/cli/shell/interactive_menu.py +348 -0
  125. app/cli/shell/main.py +286 -0
  126. app/cli/shell/parser.py +266 -0
  127. app/cli/start.py +180 -0
  128. app/cli_main.py +52 -0
  129. app/mcp_server.py +311 -0
  130. app/shared/core/__init__.py +18 -0
  131. app/shared/core/app_version.py +59 -0
  132. app/shared/core/config/__init__.py +119 -0
  133. app/shared/core/config/server.py +193 -0
  134. app/shared/core/data_source/__init__.py +106 -0
  135. app/shared/core/data_source/loader.py +348 -0
  136. app/shared/core/data_source/loaders/__init__.py +213 -0
  137. app/shared/core/data_source/loaders/base.py +215 -0
  138. app/shared/core/data_source/loaders/converter.py +337 -0
  139. app/shared/core/data_source/loaders/csv_loader.py +252 -0
  140. app/shared/core/data_source/loaders/excel_loader.py +666 -0
  141. app/shared/core/data_source/loaders/extractor.py +268 -0
  142. app/shared/core/data_source/loaders/json_loader.py +354 -0
  143. app/shared/core/data_source/loaders/registry.py +88 -0
  144. app/shared/core/data_source/loaders/sql_loader.py +313 -0
  145. app/shared/core/data_source/loaders/strategies/__init__.py +100 -0
  146. app/shared/core/data_source/loaders/strategies/array_parser.py +277 -0
  147. app/shared/core/data_source/loaders/strategies/lines_parser.py +355 -0
  148. app/shared/core/data_source/loaders/strategies/object_parser.py +278 -0
  149. app/shared/core/data_source/schema_info.py +50 -0
  150. app/shared/core/data_source/specs/__init__.py +128 -0
  151. app/shared/core/data_source/specs/base.py +258 -0
  152. app/shared/core/data_source/specs/csv_source.py +137 -0
  153. app/shared/core/data_source/specs/excel_source.py +141 -0
  154. app/shared/core/data_source/specs/file_base.py +252 -0
  155. app/shared/core/data_source/specs/json_source.py +226 -0
  156. app/shared/core/data_source/specs/sql_source.py +161 -0
  157. app/shared/core/encoding.py +36 -0
  158. app/shared/core/io/__init__.py +24 -0
  159. app/shared/core/io/yaml.py +379 -0
  160. app/shared/core/manifest_schema/__init__.py +52 -0
  161. app/shared/core/manifest_schema/types.py +99 -0
  162. app/shared/core/manifest_schema/version.py +175 -0
  163. app/shared/core/patterns/__init__.py +24 -0
  164. app/shared/core/patterns/loader.py +134 -0
  165. app/shared/core/patterns/writer.py +244 -0
  166. app/shared/core/project/__init__.py +47 -0
  167. app/shared/core/project/constraint/builders/__init__.py +50 -0
  168. app/shared/core/project/constraint/builders/base.py +100 -0
  169. app/shared/core/project/constraint/builders/composite.py +77 -0
  170. app/shared/core/project/constraint/builders/conditional.py +67 -0
  171. app/shared/core/project/constraint/builders/foreign_key.py +53 -0
  172. app/shared/core/project/constraint/builders/registry.py +64 -0
  173. app/shared/core/project/constraint/builders/scripted.py +51 -0
  174. app/shared/core/project/constraint/builders/single_column.py +86 -0
  175. app/shared/core/project/constraint/builders/unique.py +53 -0
  176. app/shared/core/project/constraint/factory.py +170 -0
  177. app/shared/core/project/constraint/reader.py +214 -0
  178. app/shared/core/project/constraint/registry.py +233 -0
  179. app/shared/core/project/constraint/types/__init__.py +63 -0
  180. app/shared/core/project/constraint/types/constraint_file.py +261 -0
  181. app/shared/core/project/constraint/types/refs.py +460 -0
  182. app/shared/core/project/constraint/types.py +28 -0
  183. app/shared/core/project/constraint/writer.py +181 -0
  184. app/shared/core/project/loader/__init__.py +56 -0
  185. app/shared/core/project/loader/loader.py +30 -0
  186. app/shared/core/project/loader/loader_parts/config_inspector.py +137 -0
  187. app/shared/core/project/loader/loader_parts/embedded_constraints.py +224 -0
  188. app/shared/core/project/loader/loader_parts/file_loaders.py +58 -0
  189. app/shared/core/project/loader/loader_parts/inspection_ids.py +85 -0
  190. app/shared/core/project/loader/loader_parts/inspector_helpers.py +312 -0
  191. app/shared/core/project/loader/loader_parts/inspector_id_checks.py +274 -0
  192. app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +690 -0
  193. app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +286 -0
  194. app/shared/core/project/loader/loader_parts/loading_error_messages.py +298 -0
  195. app/shared/core/project/loader/loader_parts/main.py +432 -0
  196. app/shared/core/project/loader/loader_parts/path_validation.py +117 -0
  197. app/shared/core/project/loader/loader_parts/runtime.py +125 -0
  198. app/shared/core/project/loader/types.py +246 -0
  199. app/shared/core/project/manifest/coverage.py +391 -0
  200. app/shared/core/project/manifest/reader.py +260 -0
  201. app/shared/core/project/manifest/types.py +91 -0
  202. app/shared/core/project/manifest/types_parts/__init__.py +60 -0
  203. app/shared/core/project/manifest/types_parts/constants.py +40 -0
  204. app/shared/core/project/manifest/types_parts/data_source.py +68 -0
  205. app/shared/core/project/manifest/types_parts/info.py +59 -0
  206. app/shared/core/project/manifest/types_parts/manifest.py +294 -0
  207. app/shared/core/project/manifest/types_parts/refs.py +153 -0
  208. app/shared/core/project/manifest/types_parts/settings.py +92 -0
  209. app/shared/core/project/manifest/types_parts/settings_file_processing.py +64 -0
  210. app/shared/core/project/manifest/types_parts/settings_script_security.py +78 -0
  211. app/shared/core/project/manifest/types_parts/settings_validation.py +83 -0
  212. app/shared/core/project/manifest/types_parts/template.py +66 -0
  213. app/shared/core/project/manifest/writer.py +262 -0
  214. app/shared/core/project/manual_data/__init__.py +27 -0
  215. app/shared/core/project/manual_data/types.py +75 -0
  216. app/shared/core/project/regex/reader.py +197 -0
  217. app/shared/core/project/regex/types.py +405 -0
  218. app/shared/core/project/regex/writer.py +123 -0
  219. app/shared/core/project/schema/reader.py +170 -0
  220. app/shared/core/project/schema/types.py +47 -0
  221. app/shared/core/project/schema/types_parts/__init__.py +36 -0
  222. app/shared/core/project/schema/types_parts/column.py +174 -0
  223. app/shared/core/project/schema/types_parts/column_utils.py +72 -0
  224. app/shared/core/project/schema/types_parts/constraint.py +165 -0
  225. app/shared/core/project/schema/types_parts/schema_id.py +66 -0
  226. app/shared/core/project/schema/types_parts/source.py +255 -0
  227. app/shared/core/project/schema/types_parts/source_options.py +347 -0
  228. app/shared/core/project/schema/types_parts/table.py +230 -0
  229. app/shared/core/project/schema/writer.py +139 -0
  230. app/shared/core/project/schema_ref_check.py +95 -0
  231. app/shared/core/project/template/__init__.py +27 -0
  232. app/shared/core/project/template/expander.py +263 -0
  233. app/shared/core/project/template/reader.py +120 -0
  234. app/shared/core/project/template/types.py +114 -0
  235. app/shared/core/project/transform/reader.py +76 -0
  236. app/shared/core/project/transform/types.py +116 -0
  237. app/shared/core/project/transform/writer.py +84 -0
  238. app/shared/core/pydantic_messages.py +59 -0
  239. app/shared/core/reporter/__init__.py +46 -0
  240. app/shared/core/reporter/reporter.py +220 -0
  241. app/shared/core/reporter/reporters/__init__.py +65 -0
  242. app/shared/core/reporter/reporters/base.py +188 -0
  243. app/shared/core/reporter/reporters/dingtalk_app_reporter.py +274 -0
  244. app/shared/core/reporter/reporters/email_reporter.py +271 -0
  245. app/shared/core/reporter/reporters/feishu_app_reporter.py +467 -0
  246. app/shared/core/reporter/reporters/local_file_reporter.py +208 -0
  247. app/shared/core/reporter/reporters/wecom_app_reporter.py +268 -0
  248. app/shared/core/utils/__init__.py +18 -0
  249. app/shared/core/utils/path_utils.py +60 -0
  250. app/shared/core/utils/regex_extract.py +113 -0
  251. app/shared/domain/__init__.py +114 -0
  252. app/shared/domain/constraints/__init__.py +76 -0
  253. app/shared/domain/constraints/allowed_values.py +211 -0
  254. app/shared/domain/constraints/base.py +141 -0
  255. app/shared/domain/constraints/charset.py +337 -0
  256. app/shared/domain/constraints/composite.py +174 -0
  257. app/shared/domain/constraints/condition_registry.py +130 -0
  258. app/shared/domain/constraints/conditional.py +629 -0
  259. app/shared/domain/constraints/date_logic.py +731 -0
  260. app/shared/domain/constraints/foreign_key.py +261 -0
  261. app/shared/domain/constraints/key_normalization.py +56 -0
  262. app/shared/domain/constraints/not_null.py +185 -0
  263. app/shared/domain/constraints/range.py +360 -0
  264. app/shared/domain/constraints/regex.py +218 -0
  265. app/shared/domain/constraints/scripted.py +276 -0
  266. app/shared/domain/constraints/unique.py +233 -0
  267. app/shared/domain/data_engine.py +384 -0
  268. app/shared/domain/data_types.py +113 -0
  269. app/shared/domain/data_types_parts/__init__.py +67 -0
  270. app/shared/domain/data_types_parts/base.py +204 -0
  271. app/shared/domain/data_types_parts/composite.py +250 -0
  272. app/shared/domain/data_types_parts/expression.py +202 -0
  273. app/shared/domain/data_types_parts/extracted.py +106 -0
  274. app/shared/domain/data_types_parts/json_types.py +234 -0
  275. app/shared/domain/data_types_parts/scalars.py +719 -0
  276. app/shared/domain/data_types_parts/sequence.py +129 -0
  277. app/shared/domain/dataset_schema.py +48 -0
  278. app/shared/domain/eval_sandbox.py +63 -0
  279. app/shared/domain/expression_system.py +366 -0
  280. app/shared/domain/regex_flags.py +53 -0
  281. app/shared/domain/schema/builder.py +223 -0
  282. app/shared/domain/schema/models.py +339 -0
  283. app/shared/domain/transforms/__init__.py +28 -0
  284. app/shared/domain/transforms/aggregate.py +141 -0
  285. app/shared/domain/transforms/base.py +171 -0
  286. app/shared/domain/transforms/cast_type.py +120 -0
  287. app/shared/domain/transforms/concat.py +103 -0
  288. app/shared/domain/transforms/conditional_assign.py +114 -0
  289. app/shared/domain/transforms/date_format.py +81 -0
  290. app/shared/domain/transforms/digits.py +77 -0
  291. app/shared/domain/transforms/drop_duplicates.py +94 -0
  292. app/shared/domain/transforms/fill_na.py +94 -0
  293. app/shared/domain/transforms/filter_rows.py +97 -0
  294. app/shared/domain/transforms/lookup.py +78 -0
  295. app/shared/domain/transforms/lower_case.py +70 -0
  296. app/shared/domain/transforms/map_value.py +90 -0
  297. app/shared/domain/transforms/math_expr.py +112 -0
  298. app/shared/domain/transforms/modulo.py +82 -0
  299. app/shared/domain/transforms/regex_extract.py +103 -0
  300. app/shared/domain/transforms/registry.py +95 -0
  301. app/shared/domain/transforms/replace.py +88 -0
  302. app/shared/domain/transforms/sort_rows.py +94 -0
  303. app/shared/domain/transforms/string_split.py +84 -0
  304. app/shared/domain/transforms/strip.py +73 -0
  305. app/shared/domain/transforms/substring.py +92 -0
  306. app/shared/domain/transforms/upper_case.py +70 -0
  307. app/shared/domain/transforms/weighted_sum.py +104 -0
  308. app/shared/domain/validation_constraints.py +69 -0
  309. app/shared/services/__init__.py +62 -0
  310. app/shared/services/ai/__init__.py +48 -0
  311. app/shared/services/ai/agent/__init__.py +40 -0
  312. app/shared/services/ai/agent/chat_tools/__init__.py +47 -0
  313. app/shared/services/ai/agent/chat_tools/apply_actions.py +592 -0
  314. app/shared/services/ai/agent/chat_tools/ask_user.py +237 -0
  315. app/shared/services/ai/agent/chat_tools/read_canvas.py +140 -0
  316. app/shared/services/ai/agent/chat_tools/read_project.py +160 -0
  317. app/shared/services/ai/agent/chat_tools/read_table.py +301 -0
  318. app/shared/services/ai/agent/chat_tools/schemas.py +105 -0
  319. app/shared/services/ai/agent/chat_tools/validate_table.py +131 -0
  320. app/shared/services/ai/agent/executor.py +554 -0
  321. app/shared/services/ai/agent/memory.py +256 -0
  322. app/shared/services/ai/agent/planner.py +282 -0
  323. app/shared/services/ai/agent/tool_registry.py +296 -0
  324. app/shared/services/ai/agent/tools/__init__.py +32 -0
  325. app/shared/services/ai/agent/tools/config_generate.py +133 -0
  326. app/shared/services/ai/agent/tools/config_refine.py +109 -0
  327. app/shared/services/ai/agent/tools/config_validate.py +403 -0
  328. app/shared/services/ai/agent/tools/merge_results.py +136 -0
  329. app/shared/services/ai/agent/tools/plan_chunks.py +79 -0
  330. app/shared/services/ai/agent/tools/script_parse.py +359 -0
  331. app/shared/services/ai/agent/types.py +138 -0
  332. app/shared/services/ai/chat_agent_runner.py +596 -0
  333. app/shared/services/ai/chat_orchestrator.py +725 -0
  334. app/shared/services/ai/failure_messages.py +65 -0
  335. app/shared/services/ai/job_storage.py +274 -0
  336. app/shared/services/ai/migrate_service.py +550 -0
  337. app/shared/services/ai/streaming/__init__.py +65 -0
  338. app/shared/services/ai/streaming/event_journal.py +197 -0
  339. app/shared/services/ai/streaming/orchestrator.py +262 -0
  340. app/shared/services/ai/streaming/pending_interaction_store.py +227 -0
  341. app/shared/services/ai/streaming/sse_response.py +148 -0
  342. app/shared/services/ai/streaming/types.py +73 -0
  343. app/shared/services/ai/types.py +213 -0
  344. app/shared/services/ai/utils.py +322 -0
  345. app/shared/services/diff/config_diff.py +320 -0
  346. app/shared/services/hardware.py +237 -0
  347. app/shared/services/llm/__init__.py +62 -0
  348. app/shared/services/llm/actions/__init__.py +42 -0
  349. app/shared/services/llm/actions/_canvas_validator.py +147 -0
  350. app/shared/services/llm/actions/_constraint_validator.py +401 -0
  351. app/shared/services/llm/actions/_regex_validator.py +85 -0
  352. app/shared/services/llm/actions/_schema_validator.py +82 -0
  353. app/shared/services/llm/actions/_settings_validator.py +76 -0
  354. app/shared/services/llm/actions/_transform_validator.py +78 -0
  355. app/shared/services/llm/actions/action_handlers.py +400 -0
  356. app/shared/services/llm/actions/action_parser.py +63 -0
  357. app/shared/services/llm/actions/action_processor.py +468 -0
  358. app/shared/services/llm/actions/action_validator.py +311 -0
  359. app/shared/services/llm/actions/diff_compute.py +195 -0
  360. app/shared/services/llm/actions/regex_handlers.py +284 -0
  361. app/shared/services/llm/actions/registry.py +336 -0
  362. app/shared/services/llm/actions/schema_handlers.py +335 -0
  363. app/shared/services/llm/actions/settings_handlers.py +180 -0
  364. app/shared/services/llm/actions/specs.py +259 -0
  365. app/shared/services/llm/actions/transform_handlers.py +279 -0
  366. app/shared/services/llm/actions/validation_types.py +147 -0
  367. app/shared/services/llm/cache/__init__.py +18 -0
  368. app/shared/services/llm/cache/response_cache.py +80 -0
  369. app/shared/services/llm/chat/__init__.py +35 -0
  370. app/shared/services/llm/chat/chat_system_prompt.py +561 -0
  371. app/shared/services/llm/chat/response_parser.py +296 -0
  372. app/shared/services/llm/config/__init__.py +45 -0
  373. app/shared/services/llm/config/crypto.py +135 -0
  374. app/shared/services/llm/config/loader.py +258 -0
  375. app/shared/services/llm/config/models.py +202 -0
  376. app/shared/services/llm/config/presets.py +128 -0
  377. app/shared/services/llm/config_generator.py +163 -0
  378. app/shared/services/llm/constraints/__init__.py +41 -0
  379. app/shared/services/llm/constraints/constraint_builder.py +177 -0
  380. app/shared/services/llm/constraints/constraint_deletion.py +84 -0
  381. app/shared/services/llm/constraints/constraint_id.py +174 -0
  382. app/shared/services/llm/constraints/frontend_instructions.py +333 -0
  383. app/shared/services/llm/constraints/inline_batch.py +279 -0
  384. app/shared/services/llm/discovery/__init__.py +35 -0
  385. app/shared/services/llm/discovery/scanner.py +181 -0
  386. app/shared/services/llm/generation/__init__.py +42 -0
  387. app/shared/services/llm/generation/agent_wiring.py +156 -0
  388. app/shared/services/llm/generation/config_builder.py +386 -0
  389. app/shared/services/llm/generation/errors.py +36 -0
  390. app/shared/services/llm/generation/existing_config.py +99 -0
  391. app/shared/services/llm/generation/profiler.py +279 -0
  392. app/shared/services/llm/generation/prompt_builder.py +199 -0
  393. app/shared/services/llm/generation/response_parser.py +144 -0
  394. app/shared/services/llm/generation/service.py +622 -0
  395. app/shared/services/llm/models.py +104 -0
  396. app/shared/services/llm/providers/__init__.py +48 -0
  397. app/shared/services/llm/providers/base.py +310 -0
  398. app/shared/services/llm/providers/cached_provider.py +90 -0
  399. app/shared/services/llm/providers/ollama.py +498 -0
  400. app/shared/services/llm/providers/openai.py +334 -0
  401. app/shared/services/llm/providers/registry.py +108 -0
  402. app/shared/services/llm/schema_resolver.py +141 -0
  403. app/shared/services/llm/suggestion_utils.py +219 -0
  404. app/shared/services/llm/validate_executor.py +163 -0
  405. app/shared/services/llm/yaml_io.py +406 -0
  406. app/shared/services/preview/__init__.py +18 -0
  407. app/shared/services/preview/loader.py +145 -0
  408. app/shared/services/preview/path_validation.py +138 -0
  409. app/shared/services/project_loader.py +57 -0
  410. app/shared/services/schema_inference.py +260 -0
  411. app/shared/services/schema_runtime_builder.py +120 -0
  412. app/shared/services/validation/__init__.py +52 -0
  413. app/shared/services/validation/chunked_loader.py +509 -0
  414. app/shared/services/validation/dag/__init__.py +35 -0
  415. app/shared/services/validation/dag/builder.py +141 -0
  416. app/shared/services/validation/dag/executor.py +225 -0
  417. app/shared/services/validation/dag/sorter.py +77 -0
  418. app/shared/services/validation/data_loader.py +231 -0
  419. app/shared/services/validation/engine.py +446 -0
  420. app/shared/services/validation/executor.py +1030 -0
  421. app/shared/services/validation/extractors.py +266 -0
  422. app/shared/services/validation/history.py +209 -0
  423. app/shared/services/validation/json_payload.py +136 -0
  424. app/shared/services/validation/loader.py +152 -0
  425. app/shared/services/validation/memory_monitor.py +179 -0
  426. app/shared/services/validation/postprocess.py +208 -0
  427. app/shared/services/validation/progress.py +64 -0
  428. app/shared/services/validation/report_export.py +222 -0
  429. app/shared/services/validation/resolver.py +180 -0
  430. app/shared/services/validation/service.py +418 -0
  431. app/shared/services/validation/types.py +238 -0
  432. app/shared/services/validation/validators/__init__.py +36 -0
  433. app/shared/services/validation/validators/adapter.py +182 -0
  434. app/shared/services/validation/validators/base.py +332 -0
  435. app/shared/services/validation/validators/composite.py +233 -0
  436. app/shared/services/validation/validators/date_logic.py +276 -0
  437. app/start_server.py +133 -0
  438. precis_cli-0.1.3.dist-info/METADATA +180 -0
  439. precis_cli-0.1.3.dist-info/RECORD +442 -0
  440. precis_cli-0.1.3.dist-info/WHEEL +5 -0
  441. precis_cli-0.1.3.dist-info/entry_points.txt +4 -0
  442. precis_cli-0.1.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,384 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 数据处理引擎模块
18
+
19
+ 功能概述:
20
+ - 提供 DataFrame 解析和验证的核心逻辑
21
+ - 执行逐单元格的类型检查和格式验证
22
+ - 支持结构化列展开(JSON 展开)
23
+ - 收集并报告验证错误
24
+
25
+ 架构设计:
26
+ - process_dataframe 是核心函数,逐行逐列验证数据
27
+ - 使用 DataType 的 validate 方法进行类型验证
28
+ - 使用 DataType 的 parse 方法进行类型转换
29
+ - 支持结构化列展开(ExpressionType 类型)
30
+
31
+ 输入示例:
32
+ from app.shared.domain.dataset_schema import TableSchema
33
+ from app.shared.domain.data_engine import process_dataframe
34
+
35
+ schema = TableSchema(name="users", columns=[...])
36
+ parsed_df, errors = process_dataframe(raw_df, schema)
37
+
38
+ 输出示例:
39
+ parsed_df: 解析后的 DataFrame(类型已转换)
40
+ errors_df: 错误列表,每项包含 row_index、column、message
41
+ """
42
+
43
+ # 1. 第三方库导入
44
+ import pandas as pd
45
+
46
+ # 2. 项目内部导入
47
+ from app.shared.domain.data_types import ExpressionType
48
+ from app.shared.domain.data_types_parts.json_types import JsonObjectType
49
+ from app.shared.domain.dataset_schema import ColumnSchema, TableSchema
50
+
51
+
52
+ def _reconstruct_expand_columns(df: pd.DataFrame, table_schema: TableSchema) -> pd.DataFrame:
53
+ """
54
+ 将 pd.json_normalize 展平产生的点分列名重构回原始 dict 列。
55
+
56
+ pd.json_normalize 会将 {"specs": {"brand": "X", "model": "Y"}} 展平为
57
+ specs.brand 和 specs.model 两列。本函数对 schema 中 expand=True 且有 children
58
+ 的列,将这些点分列重新聚合为 dict 列(如 specs 列的每个单元格是一个 dict)。
59
+
60
+ 这样后续 _expand_structured_columns 就能正确处理这些列。
61
+ """
62
+ df = df.copy()
63
+ for col_name, col_schema in table_schema.columns.items():
64
+ if not col_schema.expand or not col_schema.children:
65
+ continue
66
+ if col_name in df.columns:
67
+ continue
68
+
69
+ prefix = f"{col_name}."
70
+ matching_cols = [c for c in df.columns if c.startswith(prefix)]
71
+ if not matching_cols:
72
+ continue
73
+
74
+ # 预筛选存在的子列(保留 children 顺序)
75
+ child_names = []
76
+ child_keys = []
77
+ for child in col_schema.children or []:
78
+ col_key = f"{col_name}.{child.name}"
79
+ if col_key in df.columns:
80
+ child_names.append(child.name)
81
+ child_keys.append(col_key)
82
+
83
+ # 向量化重构:逐行组装 dict cell,NaN 值省略,整行空则为 None
84
+ # (原 iterrows 实现的等价语义,itertuples 性能优于 iterrows)
85
+ sub_df = df[child_keys]
86
+ reconstructed: list[dict | None] = []
87
+ for row_vals in sub_df.itertuples(index=False, name=None):
88
+ cell = {}
89
+ for idx, child_name in enumerate(child_names):
90
+ val = row_vals[idx]
91
+ if pd.notna(val):
92
+ cell[child_name] = val
93
+ reconstructed.append(cell if cell else None)
94
+
95
+ df[col_name] = reconstructed
96
+ df = df.drop(columns=matching_cols)
97
+
98
+ return df
99
+
100
+
101
+ def _map_json_path_columns(df: pd.DataFrame, table_schema: TableSchema) -> pd.DataFrame:
102
+ """
103
+ 使用 json_path 将 DataFrame 中的点分列名映射为 schema 定义的列名。
104
+
105
+ pd.json_normalize 会将 {"location": {"zone": "A"}} 展平为 location.zone 列,
106
+ 但 schema 定义的列名可能是 location_zone,通过 json_path("$.location.zone") 关联。
107
+ 本函数根据 json_path 将 DataFrame 列名重命名为 schema 列名。
108
+ """
109
+ rename_map = {}
110
+ for col_name, col_schema in table_schema.columns.items():
111
+ if col_name in df.columns:
112
+ continue
113
+ if not col_schema.json_path:
114
+ continue
115
+ json_path = col_schema.json_path
116
+ if not json_path.startswith("$."):
117
+ continue
118
+ dot_path = json_path[2:]
119
+ if dot_path in df.columns:
120
+ rename_map[dot_path] = col_name
121
+
122
+ if rename_map:
123
+ df = df.rename(columns=rename_map)
124
+
125
+ return df
126
+
127
+
128
+ def _fillna_dict(col: pd.Series) -> pd.Series:
129
+ """将 JSON 列中的空值(NaN/None)替换为空 dict,供 json_normalize 展开为全空行。
130
+
131
+ 说明: 不能用 fillna({})——Series.fillna 把 dict 参数按"索引标签→值"映射解释,
132
+ 空 dict 什么都填不上,空值原样残留后进入 json_normalize 会产生垃圾行为。
133
+ """
134
+ return col.where(col.notna(), {})
135
+
136
+
137
+ def _expand_structured_columns(df: pd.DataFrame, table_schema: TableSchema) -> pd.DataFrame:
138
+ """
139
+ 展开结构化列(JSON 列)。
140
+
141
+ ============================================================================
142
+ 业务场景 (什么情况下会调用这个函数)
143
+ ============================================================================
144
+ - 场景1: 展开 JSON 列
145
+ 当列的数据类型是 ExpressionType 且 expand=True 时,
146
+ 将 JSON 对象展开为多个独立的列。
147
+
148
+ ============================================================================
149
+ 数据流 (输入如何变成输出)
150
+ ============================================================================
151
+ 输入参数:
152
+ - df: pd.DataFrame 待处理的 DataFrame
153
+ - table_schema: TableSchema 表结构定义
154
+
155
+ 处理步骤:
156
+ 1. 遍历所有列
157
+ 2. 检查是否有 ExpressionType 且 expand=True 的列
158
+ 3. 使用 pd.json_normalize 展开 JSON
159
+ 4. 合并到原 DataFrame
160
+
161
+ 最终输出: pd.DataFrame - 展开后的 DataFrame
162
+ """
163
+ # 复制 DataFrame 避免修改原始数据,保证函数的纯性
164
+ df_to_process = df.copy()
165
+
166
+ # 遍历 schema 中定义的所有列,查找需要展开的结构化列
167
+ for col_name, col_schema in table_schema.columns.items():
168
+ # 条件判断:列必须存在于 DataFrame 中,且 schema 标记为需要展开
169
+ if col_name not in df_to_process.columns or not col_schema.expand:
170
+ continue
171
+
172
+ # 仅 ExpressionType 和 JsonObjectType(有 children)支持展开
173
+ is_expression = isinstance(col_schema.data_type, ExpressionType)
174
+ is_json_object_with_children = isinstance(col_schema.data_type, JsonObjectType) and col_schema.children
175
+ if not (is_expression or is_json_object_with_children):
176
+ continue
177
+
178
+ if is_json_object_with_children:
179
+ if not col_schema.children:
180
+ continue
181
+ child_names = [child.name for child in col_schema.children]
182
+ normalized_data = pd.json_normalize(_fillna_dict(df_to_process[col_name]).tolist())
183
+ normalized_data = normalized_data.reindex(columns=child_names)
184
+ normalized_data = normalized_data.add_prefix(f"{col_name}_")
185
+ else:
186
+ normalized_data = pd.json_normalize(_fillna_dict(df_to_process[col_name]).tolist()).add_prefix(
187
+ f"{col_name}_"
188
+ )
189
+
190
+ # 删除原始的 JSON 列,避免列名冲突
191
+ df_to_process = df_to_process.drop(columns=[col_name])
192
+
193
+ # 将展开后的新列横向合并到原 DataFrame
194
+ df_to_process = pd.concat([df_to_process, normalized_data], axis=1)
195
+
196
+ import logging
197
+
198
+ logger = logging.getLogger(__name__)
199
+ logger.info(f"列 '{col_name}' 已被自动展开为新的列。")
200
+
201
+ return df_to_process
202
+
203
+
204
+ def _process_columns_recursive(
205
+ df: pd.DataFrame,
206
+ schema_columns: dict[str, ColumnSchema],
207
+ parent_path: str,
208
+ parsed_data: dict[str, list],
209
+ errors: list[dict],
210
+ num_rows: int,
211
+ ) -> None:
212
+ """递归处理 schema 列。
213
+
214
+ JsonObject 列(有 children)跳过自身列检查,递归处理叶子子列。
215
+ 叶子列以「父.子」全限定名参与校验(对应 json_normalize 点分列)。
216
+ 平面列(无父)全限定名即自身名,行为不变。
217
+
218
+ :param df: 待处理的 DataFrame
219
+ :param schema_columns: 当前层级的列字典 {name: ColumnSchema}
220
+ :param parent_path: 父级全限定路径(空串表示顶层)
221
+ :param parsed_data: 累积解析列数据的字典
222
+ :param errors: 累积错误的列表
223
+ :param num_rows: 原始行数(用于缺失列填充)
224
+ """
225
+ prefix = f"{parent_path}." if parent_path else ""
226
+ for col_name, col_schema in schema_columns.items():
227
+ # 跳过派生列(Extracted 类型),它们不存在于原始数据中
228
+ if hasattr(col_schema.data_type, "name") and col_schema.data_type.name == "Extracted":
229
+ continue
230
+
231
+ qualified = f"{prefix}{col_name}"
232
+
233
+ # JsonObject 列(有 children):递归处理子列,跳过自身列检查
234
+ # children 是 list[ColumnSchema],转为 {name: col} dict 以复用递归
235
+ #
236
+ # 例外:expand=True 时不递归。该路径下 process_dataframe 已先调用
237
+ # _reconstruct_expand_columns 把点分子列(specs.brand)折叠回单列 dict 列
238
+ # (specs),交由后续 _expand_structured_columns 重新展开。若此处仍递归,
239
+ # 子列的全限定名已不在 df.columns 中,会误报 MissingColumn。改为按父列
240
+ # 全限定名做存在性检查(折叠后的 dict 列存在),与历史行为一致。
241
+ if isinstance(col_schema.data_type, JsonObjectType) and col_schema.children and not col_schema.expand:
242
+ child_dict = {c.name: c for c in col_schema.children}
243
+ _process_columns_recursive(df, child_dict, qualified, parsed_data, errors, num_rows)
244
+ continue
245
+
246
+ # 叶子列(含平面列和嵌套叶子):按全限定名检查存在性
247
+ if qualified not in df.columns:
248
+ errors.append(
249
+ {
250
+ "row_index": None,
251
+ "column": qualified,
252
+ "value": None,
253
+ "error_type": "MissingColumn",
254
+ "error_message": f"数据表中缺少必需的列 '{qualified}'",
255
+ }
256
+ )
257
+ parsed_data[qualified] = [None] * num_rows
258
+ continue
259
+
260
+ # 类型校验(用全限定名取列)
261
+ nullable = getattr(col_schema, "nullable", True)
262
+ parsed_series, col_errors = col_schema.data_type.process_column(df[qualified], qualified, nullable=nullable)
263
+ parsed_data[qualified] = parsed_series
264
+ errors.extend(col_errors)
265
+
266
+
267
+ def process_dataframe(df: pd.DataFrame, schema: TableSchema) -> tuple[pd.DataFrame, list[dict]]:
268
+ """
269
+ 处理 DataFrame,执行类型验证和解析。
270
+
271
+ ============================================================================
272
+ 业务场景 (什么情况下会调用这个函数)
273
+ ============================================================================
274
+ - 场景1: 数据校验
275
+ 对导入的 Excel/CSV 数据进行类型验证,确保数据符合 schema 定义。
276
+
277
+ - 场景2: 数据清洗
278
+ 将字符串类型的数据解析为正确的类型(如 "123" -> 123)。
279
+
280
+ ============================================================================
281
+ 数据流 (输入如何变成输出)
282
+ ============================================================================
283
+ 输入参数:
284
+ - df: pd.DataFrame 原始 DataFrame
285
+ 示例值: pd.DataFrame({"user_id": ["1", "2"], "name": ["Alice", "Bob"]})
286
+ - schema: TableSchema 表结构定义
287
+ 示例值: TableSchema(name="users", columns=[ColumnSchema(...), ...])
288
+
289
+ 处理步骤:
290
+ ┌─────────────────────────────────────────────────────────────┐
291
+ │ Step 1: 遍历每一列 │
292
+ ├─────────────────────────────────────────────────────────────┤
293
+ │ 输入: df, schema │
294
+ │ 操作: for col_name, col_schema in schema.columns.items()│
295
+ │ 输出: 遍历每个定义的列 │
296
+ └─────────────────────────────────────────────────────────────┘
297
+
298
+ ┌─────────────────────────────────────────────────────────────┐
299
+ │ Step 2: 检查列是否存在 │
300
+ ├─────────────────────────────────────────────────────────────┤
301
+ │ 输入: 列名 │
302
+ │ 操作: if col_name not in df.columns │
303
+ │ 输出: 错误记录(MissingColumn) │
304
+ └─────────────────────────────────────────────────────────────┘
305
+
306
+ ┌─────────────────────────────────────────────────────────────┐
307
+ │ Step 3: 遍历每一行的值 │
308
+ ├─────────────────────────────────────────────────────────────┤
309
+ │ 输入: 列的所有值 │
310
+ │ 操作: for index, value in df[col_name].items() │
311
+ │ 输出: 逐个验证 │
312
+ └─────────────────────────────────────────────────────────────┘
313
+
314
+ ┌─────────────────────────────────────────────────────────────┐
315
+ │ Step 4: 类型验证 │
316
+ ├─────────────────────────────────────────────────────────────┤
317
+ │ 输入: cell value │
318
+ │ 操作: col_schema.data_type.validate(value) │
319
+ │ 输出: (is_valid, error_message) │
320
+ └─────────────────────────────────────────────────────────────┘
321
+
322
+ ┌─────────────────────────────────────────────────────────────┐
323
+ │ Step 5: 类型解析 │
324
+ ├─────────────────────────────────────────────────────────────┤
325
+ │ 输入: 验证通过的值 │
326
+ │ 操作: col_schema.data_type.parse(value) │
327
+ │ 输出: 解析后的值 │
328
+ └─────────────────────────────────────────────────────────────┘
329
+
330
+ ┌─────────────────────────────────────────────────────────────┐
331
+ │ Step 6: 展开结构化列 │
332
+ ├─────────────────────────────────────────────────────────────┤
333
+ │ 输入: 解析后的 DataFrame │
334
+ │ 操作: _expand_structured_columns │
335
+ │ 输出: 展开后的 DataFrame │
336
+ └─────────────────────────────────────────────────────────────┘
337
+
338
+ 最终输出: Tuple[pd.DataFrame, list[dict]]
339
+ - 第一个元素: 解析后的 DataFrame
340
+ - 第二个元素: 错误字典列表,每项包含 row_index、column、value、error_type、error_message
341
+
342
+ ============================================================================
343
+ 错误格式
344
+ ============================================================================
345
+ 错误列表中的每个字典包含以下字段:
346
+ - row_index: 行索引(整数或 None,None 表示整列级错误)
347
+ - column: 列名(字符串)
348
+ - value: 错误值(任意类型)
349
+ - error_type: 错误类型(字符串)
350
+ - error_message: 错误消息(字符串)
351
+
352
+ ============================================================================
353
+ 边界情况处理
354
+ ============================================================================
355
+ - 缺少列: 记录 MissingColumn 错误,该列填充 None
356
+ - 空 DataFrame: 返回空的解析 DataFrame 和空的错误 DataFrame
357
+ - 验证失败: 记录错误,该单元格填充 None
358
+ """
359
+ # 展开 expand 列:将 pd.json_normalize 展平产生的点分列名(如 specs.brand)
360
+ # 重构回原始 dict 列,以便后续 _expand_structured_columns 能正确处理
361
+ df = _reconstruct_expand_columns(df, schema)
362
+
363
+ # 使用 json_path 将 DataFrame 中的点分列名映射为 schema 定义的列名
364
+ df = _map_json_path_columns(df, schema)
365
+
366
+ # 存储解析后的列数据,键为列名,值为解析后的列表
367
+ parsed_data: dict[str, list] = {}
368
+
369
+ # 存储所有验证和解析过程中发现的错误
370
+ errors: list[dict] = []
371
+
372
+ # 记录原始 DataFrame 的行数,用于缺失列时填充空值
373
+ num_rows = len(df)
374
+
375
+ # 递归处理列:JsonObject 列跳过自身检查、递归叶子子列(全限定名校验)
376
+ _process_columns_recursive(df, schema.columns, "", parsed_data, errors, num_rows)
377
+
378
+ # 将解析后的列数据组装为 DataFrame,保留原始索引以维持行号对应关系
379
+ parsed_df = pd.DataFrame(parsed_data, index=df.index)
380
+
381
+ # 展开需要展开的结构化列(JSON 列)
382
+ parsed_df = _expand_structured_columns(parsed_df, schema)
383
+
384
+ return parsed_df, errors
@@ -0,0 +1,113 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 数据类型统一导出模块
18
+
19
+ 功能概述:
20
+ - 聚合导出所有领域数据类型(标量、复合、序列、表达式、提取类型等)
21
+ - 为校验引擎和 Schema 解析提供统一的数据类型入口
22
+ - 作为 app.shared.domain.data_types 包的门面(Facade),隐藏 data_types_parts 内部结构
23
+
24
+ 架构设计:
25
+ - 类型注册表驱动: 各类型继承自 DataType 基类,通过统一的 process_column / validate / parse 接口工作
26
+ - 扁平化导出: 将分散在 data_types_parts 子目录中的类型集中暴露,降低调用方的认知负担
27
+ - 开闭原则: 新增数据类型时只需在对应子模块中实现,并在本模块重导出,不影响现有代码
28
+
29
+ 类型分类说明:
30
+ - 标量类型 (scalars): StringType、IntegerType、DecimalType、FloatType、BooleanType、DateType
31
+ 用于表示单一值的基本数据类型,是最常用的类型。
32
+ - 复合类型 (composite): CompositeConditionType、SpecificCompositeConditionType
33
+ 用于表示由多个条件组合而成的复杂校验规则。
34
+ - 表达式类型 (expression): ExpressionType、SpecificExpressionType
35
+ 用于表示需要动态求值的表达式列,支持 JSON 展开。
36
+ - 提取类型 (extracted): ExtractedType
37
+ 用于表示从其他列派生计算得到的虚拟列,不存在于原始数据中。
38
+ - 序列类型 (sequence): SequenceType
39
+ 用于表示数组或列表类型的数据。
40
+
41
+ 输入示例:
42
+ >>> from app.shared.domain.data_types import StringType, IntegerType, ExpressionType
43
+ >>> string_type = StringType()
44
+ >>> int_type = IntegerType()
45
+
46
+ 输出示例:
47
+ >>> data_type = StringType() # 或 IntegerType(), DateType() 等
48
+ >>> parsed, errors = data_type.process_column(series, "column_name", nullable=True)
49
+
50
+ 注意事项:
51
+ - 所有具体类型必须继承自 DataType 基类,并实现 process_column 方法。
52
+ - 若需新增数据类型,应在 data_types_parts 的对应子模块中实现,
53
+ 然后在本模块导入并重导出,同时更新 __all__ 列表。
54
+ """
55
+
56
+ from __future__ import annotations
57
+
58
+ # 1. 项目内部导入 —— 从 data_types_parts 各子模块聚合类型
59
+ # 基类:所有数据类型的抽象基类,定义统一的 process_column / validate / parse 接口
60
+ from app.shared.domain.data_types_parts.base import DataType
61
+
62
+ # 复合类型:支持多条件组合校验的复合条件类型
63
+ from app.shared.domain.data_types_parts.composite import CompositeConditionType, SpecificCompositeConditionType
64
+
65
+ # 表达式类型:支持 JSONPath 等动态表达式求值的列类型,可配置展开为多个子列
66
+ from app.shared.domain.data_types_parts.expression import ExpressionType, SpecificExpressionType
67
+
68
+ # 提取类型:派生列类型,表示由正则提取或其他计算逻辑生成的虚拟列
69
+ from app.shared.domain.data_types_parts.extracted import ExtractedType
70
+
71
+ # JSON 类型:JSON 对象、数组和空值类型
72
+ from app.shared.domain.data_types_parts.json_types import JsonArrayType, JsonNullType, JsonObjectType
73
+
74
+ # 标量类型:基本数据类型,覆盖数值、字符串、布尔、日期等常见类型
75
+ from app.shared.domain.data_types_parts.scalars import (
76
+ BooleanType, # 布尔类型:True / False
77
+ DateType, # 日期类型:datetime.date 或 datetime.datetime
78
+ DecimalType, # 高精度小数类型:Decimal,适用于财务计算
79
+ FloatType, # 浮点类型:float,适用于科学计算
80
+ IntegerType, # 整数类型:int
81
+ StringType, # 字符串类型:str,最通用的数据类型
82
+ )
83
+
84
+ # 序列类型:数组/列表类型,表示同一类型的多个值集合
85
+ from app.shared.domain.data_types_parts.sequence import SequenceType
86
+
87
+ # 控制 `from module import *` 时导出的公开名称
88
+ # 按类型类别分组排列,便于开发者快速定位所需类型
89
+ __all__ = [
90
+ # 基类
91
+ "DataType",
92
+ # 标量类型
93
+ "BooleanType",
94
+ "DateType",
95
+ "DecimalType",
96
+ "FloatType",
97
+ "IntegerType",
98
+ "StringType",
99
+ # 复合类型
100
+ "CompositeConditionType",
101
+ "SpecificCompositeConditionType",
102
+ # 表达式类型
103
+ "ExpressionType",
104
+ "SpecificExpressionType",
105
+ # 提取类型
106
+ "ExtractedType",
107
+ # JSON 类型
108
+ "JsonArrayType",
109
+ "JsonNullType",
110
+ "JsonObjectType",
111
+ # 序列类型
112
+ "SequenceType",
113
+ ]
@@ -0,0 +1,67 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 数据类型子模块聚合导出
18
+
19
+ 功能概述:
20
+ - 集中导出所有数据类型子模块的符号
21
+ - 简化上层模块对 data_types_parts 的导入路径
22
+
23
+ 架构设计:
24
+ - 扁平化聚合: 将 base、scalars、composite、expression 等子模块统一暴露
25
+ - 显式接口控制: 通过 __all__ 限定公开符号
26
+
27
+ 输入示例:
28
+ from app.shared.domain.data_types_parts import StringType, DataType, ExpressionType
29
+
30
+ 输出示例:
31
+ dtype = DataType.create("string") # 返回 StringType 实例
32
+ """
33
+
34
+ # 1. 项目内部导入
35
+ from app.shared.domain.data_types_parts.base import DataType
36
+ from app.shared.domain.data_types_parts.composite import CompositeConditionType, SpecificCompositeConditionType
37
+ from app.shared.domain.data_types_parts.expression import ExpressionType, SpecificExpressionType
38
+ from app.shared.domain.data_types_parts.extracted import ExtractedType
39
+ from app.shared.domain.data_types_parts.json_types import JsonArrayType, JsonNullType, JsonObjectType
40
+ from app.shared.domain.data_types_parts.scalars import (
41
+ BooleanType,
42
+ DateType,
43
+ DecimalType,
44
+ FloatType,
45
+ IntegerType,
46
+ StringType,
47
+ )
48
+ from app.shared.domain.data_types_parts.sequence import SequenceType
49
+
50
+ __all__ = [
51
+ "BooleanType",
52
+ "CompositeConditionType",
53
+ "DataType",
54
+ "DateType",
55
+ "DecimalType",
56
+ "ExpressionType",
57
+ "ExtractedType",
58
+ "FloatType",
59
+ "IntegerType",
60
+ "JsonArrayType",
61
+ "JsonNullType",
62
+ "JsonObjectType",
63
+ "SequenceType",
64
+ "SpecificCompositeConditionType",
65
+ "SpecificExpressionType",
66
+ "StringType",
67
+ ]