precis-cli 0.1.3__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 (450) hide show
  1. precis_cli-0.1.3/MANIFEST.in +3 -0
  2. precis_cli-0.1.3/PKG-INFO +180 -0
  3. precis_cli-0.1.3/README.md +118 -0
  4. precis_cli-0.1.3/app/__init__.py +16 -0
  5. precis_cli-0.1.3/app/api/__init__.py +32 -0
  6. precis_cli-0.1.3/app/api/dependencies.py +185 -0
  7. precis_cli-0.1.3/app/api/main.py +301 -0
  8. precis_cli-0.1.3/app/api/middleware/__init__.py +34 -0
  9. precis_cli-0.1.3/app/api/middleware/exception_handler.py +126 -0
  10. precis_cli-0.1.3/app/api/middleware/request_logging.py +97 -0
  11. precis_cli-0.1.3/app/api/middleware/token_auth.py +215 -0
  12. precis_cli-0.1.3/app/api/models/__init__.py +151 -0
  13. precis_cli-0.1.3/app/api/models/connection_rules.py +98 -0
  14. precis_cli-0.1.3/app/api/models/files.py +99 -0
  15. precis_cli-0.1.3/app/api/models/full_validation.py +554 -0
  16. precis_cli-0.1.3/app/api/models/project.py +117 -0
  17. precis_cli-0.1.3/app/api/models/projects.py +80 -0
  18. precis_cli-0.1.3/app/api/models/schema.py +121 -0
  19. precis_cli-0.1.3/app/api/models/v2_responses.py +46 -0
  20. precis_cli-0.1.3/app/api/models/validation.py +303 -0
  21. precis_cli-0.1.3/app/api/models/workspace.py +118 -0
  22. precis_cli-0.1.3/app/api/routers/__init__.py +56 -0
  23. precis_cli-0.1.3/app/api/routers/ai/__init__.py +36 -0
  24. precis_cli-0.1.3/app/api/routers/ai/chat.py +243 -0
  25. precis_cli-0.1.3/app/api/routers/ai/generate.py +156 -0
  26. precis_cli-0.1.3/app/api/routers/ai/hardware.py +199 -0
  27. precis_cli-0.1.3/app/api/routers/ai/jobs.py +544 -0
  28. precis_cli-0.1.3/app/api/routers/ai/migrate.py +471 -0
  29. precis_cli-0.1.3/app/api/routers/ai/models.py +352 -0
  30. precis_cli-0.1.3/app/api/routers/ai/ollama.py +108 -0
  31. precis_cli-0.1.3/app/api/routers/ai/providers.py +491 -0
  32. precis_cli-0.1.3/app/api/routers/ai/router.py +44 -0
  33. precis_cli-0.1.3/app/api/routers/ai/stream.py +281 -0
  34. precis_cli-0.1.3/app/api/routers/ai/utils.py +182 -0
  35. precis_cli-0.1.3/app/api/routers/core/__init__.py +34 -0
  36. precis_cli-0.1.3/app/api/routers/core/connection_rules.py +188 -0
  37. precis_cli-0.1.3/app/api/routers/core/data_sources.py +374 -0
  38. precis_cli-0.1.3/app/api/routers/core/regex.py +333 -0
  39. precis_cli-0.1.3/app/api/routers/core/reporting.py +263 -0
  40. precis_cli-0.1.3/app/api/routers/files/__init__.py +24 -0
  41. precis_cli-0.1.3/app/api/routers/files/ops.py +179 -0
  42. precis_cli-0.1.3/app/api/routers/files/transfer.py +101 -0
  43. precis_cli-0.1.3/app/api/routers/preview/__init__.py +35 -0
  44. precis_cli-0.1.3/app/api/routers/preview/content_mode.py +264 -0
  45. precis_cli-0.1.3/app/api/routers/preview/header_row.py +154 -0
  46. precis_cli-0.1.3/app/api/routers/preview/models.py +81 -0
  47. precis_cli-0.1.3/app/api/routers/preview/path_mode.py +440 -0
  48. precis_cli-0.1.3/app/api/routers/preview/router.py +30 -0
  49. precis_cli-0.1.3/app/api/routers/project/__init__.py +61 -0
  50. precis_cli-0.1.3/app/api/routers/project/base.py +111 -0
  51. precis_cli-0.1.3/app/api/routers/project/constraint.py +345 -0
  52. precis_cli-0.1.3/app/api/routers/project/full_config.py +411 -0
  53. precis_cli-0.1.3/app/api/routers/project/full_config_writer.py +327 -0
  54. precis_cli-0.1.3/app/api/routers/project/helpers.py +167 -0
  55. precis_cli-0.1.3/app/api/routers/project/inspection_fix.py +330 -0
  56. precis_cli-0.1.3/app/api/routers/project/manifest.py +605 -0
  57. precis_cli-0.1.3/app/api/routers/project/models.py +177 -0
  58. precis_cli-0.1.3/app/api/routers/project/pattern.py +268 -0
  59. precis_cli-0.1.3/app/api/routers/project/regex.py +358 -0
  60. precis_cli-0.1.3/app/api/routers/project/scanner.py +157 -0
  61. precis_cli-0.1.3/app/api/routers/project/schema.py +567 -0
  62. precis_cli-0.1.3/app/api/routers/project/schema_helpers.py +149 -0
  63. precis_cli-0.1.3/app/api/routers/project/settings.py +399 -0
  64. precis_cli-0.1.3/app/api/routers/project/template.py +325 -0
  65. precis_cli-0.1.3/app/api/routers/project/validation.py +227 -0
  66. precis_cli-0.1.3/app/api/routers/project/view.py +177 -0
  67. precis_cli-0.1.3/app/api/routers/project/workspaces.py +167 -0
  68. precis_cli-0.1.3/app/api/routers/projects/__init__.py +25 -0
  69. precis_cli-0.1.3/app/api/routers/projects/create.py +121 -0
  70. precis_cli-0.1.3/app/api/routers/projects/open.py +103 -0
  71. precis_cli-0.1.3/app/api/routers/projects/scan.py +100 -0
  72. precis_cli-0.1.3/app/api/routers/validation/__init__.py +39 -0
  73. precis_cli-0.1.3/app/api/routers/validation/common.py +263 -0
  74. precis_cli-0.1.3/app/api/routers/validation/content_mode.py +401 -0
  75. precis_cli-0.1.3/app/api/routers/validation/history.py +235 -0
  76. precis_cli-0.1.3/app/api/routers/validation/inline_mode.py +196 -0
  77. precis_cli-0.1.3/app/api/routers/validation/path_mode.py +314 -0
  78. precis_cli-0.1.3/app/api/routers/validation/router.py +51 -0
  79. precis_cli-0.1.3/app/api/services/full_validation_response_builder.py +412 -0
  80. precis_cli-0.1.3/app/api/services/io_error_messages.py +41 -0
  81. precis_cli-0.1.3/app/api/services/preview_service.py +248 -0
  82. precis_cli-0.1.3/app/cli/__init__.py +18 -0
  83. precis_cli-0.1.3/app/cli/__main__.py +30 -0
  84. precis_cli-0.1.3/app/cli/shared_services/__init__.py +42 -0
  85. precis_cli-0.1.3/app/cli/shared_services/config_ops.py +581 -0
  86. precis_cli-0.1.3/app/cli/shared_services/generation_ops.py +160 -0
  87. precis_cli-0.1.3/app/cli/shared_services/project_ops.py +288 -0
  88. precis_cli-0.1.3/app/cli/shell/__init__.py +48 -0
  89. precis_cli-0.1.3/app/cli/shell/commands/__init__.py +63 -0
  90. precis_cli-0.1.3/app/cli/shell/commands/ai/__init__.py +260 -0
  91. precis_cli-0.1.3/app/cli/shell/commands/ai/chat.py +331 -0
  92. precis_cli-0.1.3/app/cli/shell/commands/ai/delete.py +165 -0
  93. precis_cli-0.1.3/app/cli/shell/commands/ai/diff.py +70 -0
  94. precis_cli-0.1.3/app/cli/shell/commands/ai/display.py +428 -0
  95. precis_cli-0.1.3/app/cli/shell/commands/ai/executor.py +225 -0
  96. precis_cli-0.1.3/app/cli/shell/commands/ai/executor_utils.py +271 -0
  97. precis_cli-0.1.3/app/cli/shell/commands/ai/generate.py +285 -0
  98. precis_cli-0.1.3/app/cli/shell/commands/ai/interaction.py +262 -0
  99. precis_cli-0.1.3/app/cli/shell/commands/ai/migrate.py +281 -0
  100. precis_cli-0.1.3/app/cli/shell/commands/ai/resolver.py +224 -0
  101. precis_cli-0.1.3/app/cli/shell/commands/ai/status.py +101 -0
  102. precis_cli-0.1.3/app/cli/shell/commands/ai/switch.py +158 -0
  103. precis_cli-0.1.3/app/cli/shell/commands/ai/utils.py +52 -0
  104. precis_cli-0.1.3/app/cli/shell/commands/base.py +343 -0
  105. precis_cli-0.1.3/app/cli/shell/commands/config/__init__.py +131 -0
  106. precis_cli-0.1.3/app/cli/shell/commands/config/base.py +80 -0
  107. precis_cli-0.1.3/app/cli/shell/commands/config/check.py +246 -0
  108. precis_cli-0.1.3/app/cli/shell/commands/config/edit.py +148 -0
  109. precis_cli-0.1.3/app/cli/shell/commands/config/get.py +111 -0
  110. precis_cli-0.1.3/app/cli/shell/commands/config/init.py +123 -0
  111. precis_cli-0.1.3/app/cli/shell/commands/config/inspect.py +164 -0
  112. precis_cli-0.1.3/app/cli/shell/commands/config/list.py +104 -0
  113. precis_cli-0.1.3/app/cli/shell/commands/config/set.py +119 -0
  114. precis_cli-0.1.3/app/cli/shell/commands/config/show.py +150 -0
  115. precis_cli-0.1.3/app/cli/shell/commands/exit.py +67 -0
  116. precis_cli-0.1.3/app/cli/shell/commands/help.py +104 -0
  117. precis_cli-0.1.3/app/cli/shell/commands/infer_schema.py +156 -0
  118. precis_cli-0.1.3/app/cli/shell/commands/open.py +201 -0
  119. precis_cli-0.1.3/app/cli/shell/commands/project.py +215 -0
  120. precis_cli-0.1.3/app/cli/shell/commands/provider.py +619 -0
  121. precis_cli-0.1.3/app/cli/shell/commands/system.py +170 -0
  122. precis_cli-0.1.3/app/cli/shell/commands/validate.py +455 -0
  123. precis_cli-0.1.3/app/cli/shell/completer.py +231 -0
  124. precis_cli-0.1.3/app/cli/shell/config_storage.py +191 -0
  125. precis_cli-0.1.3/app/cli/shell/exceptions.py +90 -0
  126. precis_cli-0.1.3/app/cli/shell/formatter.py +371 -0
  127. precis_cli-0.1.3/app/cli/shell/interactive_menu.py +348 -0
  128. precis_cli-0.1.3/app/cli/shell/main.py +286 -0
  129. precis_cli-0.1.3/app/cli/shell/parser.py +266 -0
  130. precis_cli-0.1.3/app/cli/start.py +180 -0
  131. precis_cli-0.1.3/app/cli_main.py +52 -0
  132. precis_cli-0.1.3/app/mcp_server.py +311 -0
  133. precis_cli-0.1.3/app/shared/core/__init__.py +18 -0
  134. precis_cli-0.1.3/app/shared/core/app_version.py +59 -0
  135. precis_cli-0.1.3/app/shared/core/config/__init__.py +119 -0
  136. precis_cli-0.1.3/app/shared/core/config/server.py +193 -0
  137. precis_cli-0.1.3/app/shared/core/data_source/__init__.py +106 -0
  138. precis_cli-0.1.3/app/shared/core/data_source/loader.py +348 -0
  139. precis_cli-0.1.3/app/shared/core/data_source/loaders/__init__.py +213 -0
  140. precis_cli-0.1.3/app/shared/core/data_source/loaders/base.py +215 -0
  141. precis_cli-0.1.3/app/shared/core/data_source/loaders/converter.py +337 -0
  142. precis_cli-0.1.3/app/shared/core/data_source/loaders/csv_loader.py +252 -0
  143. precis_cli-0.1.3/app/shared/core/data_source/loaders/excel_loader.py +666 -0
  144. precis_cli-0.1.3/app/shared/core/data_source/loaders/extractor.py +268 -0
  145. precis_cli-0.1.3/app/shared/core/data_source/loaders/json_loader.py +354 -0
  146. precis_cli-0.1.3/app/shared/core/data_source/loaders/registry.py +88 -0
  147. precis_cli-0.1.3/app/shared/core/data_source/loaders/sql_loader.py +313 -0
  148. precis_cli-0.1.3/app/shared/core/data_source/loaders/strategies/__init__.py +100 -0
  149. precis_cli-0.1.3/app/shared/core/data_source/loaders/strategies/array_parser.py +277 -0
  150. precis_cli-0.1.3/app/shared/core/data_source/loaders/strategies/lines_parser.py +355 -0
  151. precis_cli-0.1.3/app/shared/core/data_source/loaders/strategies/object_parser.py +278 -0
  152. precis_cli-0.1.3/app/shared/core/data_source/schema_info.py +50 -0
  153. precis_cli-0.1.3/app/shared/core/data_source/specs/__init__.py +128 -0
  154. precis_cli-0.1.3/app/shared/core/data_source/specs/base.py +258 -0
  155. precis_cli-0.1.3/app/shared/core/data_source/specs/csv_source.py +137 -0
  156. precis_cli-0.1.3/app/shared/core/data_source/specs/excel_source.py +141 -0
  157. precis_cli-0.1.3/app/shared/core/data_source/specs/file_base.py +252 -0
  158. precis_cli-0.1.3/app/shared/core/data_source/specs/json_source.py +226 -0
  159. precis_cli-0.1.3/app/shared/core/data_source/specs/sql_source.py +161 -0
  160. precis_cli-0.1.3/app/shared/core/encoding.py +36 -0
  161. precis_cli-0.1.3/app/shared/core/io/__init__.py +24 -0
  162. precis_cli-0.1.3/app/shared/core/io/yaml.py +379 -0
  163. precis_cli-0.1.3/app/shared/core/manifest_schema/__init__.py +52 -0
  164. precis_cli-0.1.3/app/shared/core/manifest_schema/types.py +99 -0
  165. precis_cli-0.1.3/app/shared/core/manifest_schema/version.py +175 -0
  166. precis_cli-0.1.3/app/shared/core/patterns/__init__.py +24 -0
  167. precis_cli-0.1.3/app/shared/core/patterns/loader.py +134 -0
  168. precis_cli-0.1.3/app/shared/core/patterns/writer.py +244 -0
  169. precis_cli-0.1.3/app/shared/core/project/__init__.py +47 -0
  170. precis_cli-0.1.3/app/shared/core/project/constraint/builders/__init__.py +50 -0
  171. precis_cli-0.1.3/app/shared/core/project/constraint/builders/base.py +100 -0
  172. precis_cli-0.1.3/app/shared/core/project/constraint/builders/composite.py +77 -0
  173. precis_cli-0.1.3/app/shared/core/project/constraint/builders/conditional.py +67 -0
  174. precis_cli-0.1.3/app/shared/core/project/constraint/builders/foreign_key.py +53 -0
  175. precis_cli-0.1.3/app/shared/core/project/constraint/builders/registry.py +64 -0
  176. precis_cli-0.1.3/app/shared/core/project/constraint/builders/scripted.py +51 -0
  177. precis_cli-0.1.3/app/shared/core/project/constraint/builders/single_column.py +86 -0
  178. precis_cli-0.1.3/app/shared/core/project/constraint/builders/unique.py +53 -0
  179. precis_cli-0.1.3/app/shared/core/project/constraint/factory.py +170 -0
  180. precis_cli-0.1.3/app/shared/core/project/constraint/reader.py +214 -0
  181. precis_cli-0.1.3/app/shared/core/project/constraint/registry.py +233 -0
  182. precis_cli-0.1.3/app/shared/core/project/constraint/types/__init__.py +63 -0
  183. precis_cli-0.1.3/app/shared/core/project/constraint/types/constraint_file.py +261 -0
  184. precis_cli-0.1.3/app/shared/core/project/constraint/types/refs.py +460 -0
  185. precis_cli-0.1.3/app/shared/core/project/constraint/types.py +28 -0
  186. precis_cli-0.1.3/app/shared/core/project/constraint/writer.py +181 -0
  187. precis_cli-0.1.3/app/shared/core/project/loader/__init__.py +56 -0
  188. precis_cli-0.1.3/app/shared/core/project/loader/loader.py +30 -0
  189. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/config_inspector.py +137 -0
  190. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/embedded_constraints.py +224 -0
  191. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/file_loaders.py +58 -0
  192. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/inspection_ids.py +85 -0
  193. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/inspector_helpers.py +312 -0
  194. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/inspector_id_checks.py +274 -0
  195. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +690 -0
  196. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +286 -0
  197. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/loading_error_messages.py +298 -0
  198. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/main.py +432 -0
  199. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/path_validation.py +117 -0
  200. precis_cli-0.1.3/app/shared/core/project/loader/loader_parts/runtime.py +125 -0
  201. precis_cli-0.1.3/app/shared/core/project/loader/types.py +246 -0
  202. precis_cli-0.1.3/app/shared/core/project/manifest/coverage.py +391 -0
  203. precis_cli-0.1.3/app/shared/core/project/manifest/reader.py +260 -0
  204. precis_cli-0.1.3/app/shared/core/project/manifest/types.py +91 -0
  205. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/__init__.py +60 -0
  206. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/constants.py +40 -0
  207. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/data_source.py +68 -0
  208. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/info.py +59 -0
  209. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/manifest.py +294 -0
  210. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/refs.py +153 -0
  211. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/settings.py +92 -0
  212. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/settings_file_processing.py +64 -0
  213. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/settings_script_security.py +78 -0
  214. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/settings_validation.py +83 -0
  215. precis_cli-0.1.3/app/shared/core/project/manifest/types_parts/template.py +66 -0
  216. precis_cli-0.1.3/app/shared/core/project/manifest/writer.py +262 -0
  217. precis_cli-0.1.3/app/shared/core/project/manual_data/__init__.py +27 -0
  218. precis_cli-0.1.3/app/shared/core/project/manual_data/types.py +75 -0
  219. precis_cli-0.1.3/app/shared/core/project/regex/reader.py +197 -0
  220. precis_cli-0.1.3/app/shared/core/project/regex/types.py +405 -0
  221. precis_cli-0.1.3/app/shared/core/project/regex/writer.py +123 -0
  222. precis_cli-0.1.3/app/shared/core/project/schema/reader.py +170 -0
  223. precis_cli-0.1.3/app/shared/core/project/schema/types.py +47 -0
  224. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/__init__.py +36 -0
  225. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/column.py +174 -0
  226. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/column_utils.py +72 -0
  227. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/constraint.py +165 -0
  228. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/schema_id.py +66 -0
  229. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/source.py +255 -0
  230. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/source_options.py +347 -0
  231. precis_cli-0.1.3/app/shared/core/project/schema/types_parts/table.py +230 -0
  232. precis_cli-0.1.3/app/shared/core/project/schema/writer.py +139 -0
  233. precis_cli-0.1.3/app/shared/core/project/schema_ref_check.py +95 -0
  234. precis_cli-0.1.3/app/shared/core/project/template/__init__.py +27 -0
  235. precis_cli-0.1.3/app/shared/core/project/template/expander.py +263 -0
  236. precis_cli-0.1.3/app/shared/core/project/template/reader.py +120 -0
  237. precis_cli-0.1.3/app/shared/core/project/template/types.py +114 -0
  238. precis_cli-0.1.3/app/shared/core/project/transform/reader.py +76 -0
  239. precis_cli-0.1.3/app/shared/core/project/transform/types.py +116 -0
  240. precis_cli-0.1.3/app/shared/core/project/transform/writer.py +84 -0
  241. precis_cli-0.1.3/app/shared/core/pydantic_messages.py +59 -0
  242. precis_cli-0.1.3/app/shared/core/reporter/__init__.py +46 -0
  243. precis_cli-0.1.3/app/shared/core/reporter/reporter.py +220 -0
  244. precis_cli-0.1.3/app/shared/core/reporter/reporters/__init__.py +65 -0
  245. precis_cli-0.1.3/app/shared/core/reporter/reporters/base.py +188 -0
  246. precis_cli-0.1.3/app/shared/core/reporter/reporters/dingtalk_app_reporter.py +274 -0
  247. precis_cli-0.1.3/app/shared/core/reporter/reporters/email_reporter.py +271 -0
  248. precis_cli-0.1.3/app/shared/core/reporter/reporters/feishu_app_reporter.py +467 -0
  249. precis_cli-0.1.3/app/shared/core/reporter/reporters/local_file_reporter.py +208 -0
  250. precis_cli-0.1.3/app/shared/core/reporter/reporters/wecom_app_reporter.py +268 -0
  251. precis_cli-0.1.3/app/shared/core/utils/__init__.py +18 -0
  252. precis_cli-0.1.3/app/shared/core/utils/path_utils.py +60 -0
  253. precis_cli-0.1.3/app/shared/core/utils/regex_extract.py +113 -0
  254. precis_cli-0.1.3/app/shared/domain/__init__.py +114 -0
  255. precis_cli-0.1.3/app/shared/domain/constraints/__init__.py +76 -0
  256. precis_cli-0.1.3/app/shared/domain/constraints/allowed_values.py +211 -0
  257. precis_cli-0.1.3/app/shared/domain/constraints/base.py +141 -0
  258. precis_cli-0.1.3/app/shared/domain/constraints/charset.py +337 -0
  259. precis_cli-0.1.3/app/shared/domain/constraints/composite.py +174 -0
  260. precis_cli-0.1.3/app/shared/domain/constraints/condition_registry.py +130 -0
  261. precis_cli-0.1.3/app/shared/domain/constraints/conditional.py +629 -0
  262. precis_cli-0.1.3/app/shared/domain/constraints/date_logic.py +731 -0
  263. precis_cli-0.1.3/app/shared/domain/constraints/foreign_key.py +261 -0
  264. precis_cli-0.1.3/app/shared/domain/constraints/key_normalization.py +56 -0
  265. precis_cli-0.1.3/app/shared/domain/constraints/not_null.py +185 -0
  266. precis_cli-0.1.3/app/shared/domain/constraints/range.py +360 -0
  267. precis_cli-0.1.3/app/shared/domain/constraints/regex.py +218 -0
  268. precis_cli-0.1.3/app/shared/domain/constraints/scripted.py +276 -0
  269. precis_cli-0.1.3/app/shared/domain/constraints/unique.py +233 -0
  270. precis_cli-0.1.3/app/shared/domain/data_engine.py +384 -0
  271. precis_cli-0.1.3/app/shared/domain/data_types.py +113 -0
  272. precis_cli-0.1.3/app/shared/domain/data_types_parts/__init__.py +67 -0
  273. precis_cli-0.1.3/app/shared/domain/data_types_parts/base.py +204 -0
  274. precis_cli-0.1.3/app/shared/domain/data_types_parts/composite.py +250 -0
  275. precis_cli-0.1.3/app/shared/domain/data_types_parts/expression.py +202 -0
  276. precis_cli-0.1.3/app/shared/domain/data_types_parts/extracted.py +106 -0
  277. precis_cli-0.1.3/app/shared/domain/data_types_parts/json_types.py +234 -0
  278. precis_cli-0.1.3/app/shared/domain/data_types_parts/scalars.py +719 -0
  279. precis_cli-0.1.3/app/shared/domain/data_types_parts/sequence.py +129 -0
  280. precis_cli-0.1.3/app/shared/domain/dataset_schema.py +48 -0
  281. precis_cli-0.1.3/app/shared/domain/eval_sandbox.py +63 -0
  282. precis_cli-0.1.3/app/shared/domain/expression_system.py +366 -0
  283. precis_cli-0.1.3/app/shared/domain/regex_flags.py +53 -0
  284. precis_cli-0.1.3/app/shared/domain/schema/builder.py +223 -0
  285. precis_cli-0.1.3/app/shared/domain/schema/models.py +339 -0
  286. precis_cli-0.1.3/app/shared/domain/transforms/__init__.py +28 -0
  287. precis_cli-0.1.3/app/shared/domain/transforms/aggregate.py +141 -0
  288. precis_cli-0.1.3/app/shared/domain/transforms/base.py +171 -0
  289. precis_cli-0.1.3/app/shared/domain/transforms/cast_type.py +120 -0
  290. precis_cli-0.1.3/app/shared/domain/transforms/concat.py +103 -0
  291. precis_cli-0.1.3/app/shared/domain/transforms/conditional_assign.py +114 -0
  292. precis_cli-0.1.3/app/shared/domain/transforms/date_format.py +81 -0
  293. precis_cli-0.1.3/app/shared/domain/transforms/digits.py +77 -0
  294. precis_cli-0.1.3/app/shared/domain/transforms/drop_duplicates.py +94 -0
  295. precis_cli-0.1.3/app/shared/domain/transforms/fill_na.py +94 -0
  296. precis_cli-0.1.3/app/shared/domain/transforms/filter_rows.py +97 -0
  297. precis_cli-0.1.3/app/shared/domain/transforms/lookup.py +78 -0
  298. precis_cli-0.1.3/app/shared/domain/transforms/lower_case.py +70 -0
  299. precis_cli-0.1.3/app/shared/domain/transforms/map_value.py +90 -0
  300. precis_cli-0.1.3/app/shared/domain/transforms/math_expr.py +112 -0
  301. precis_cli-0.1.3/app/shared/domain/transforms/modulo.py +82 -0
  302. precis_cli-0.1.3/app/shared/domain/transforms/regex_extract.py +103 -0
  303. precis_cli-0.1.3/app/shared/domain/transforms/registry.py +95 -0
  304. precis_cli-0.1.3/app/shared/domain/transforms/replace.py +88 -0
  305. precis_cli-0.1.3/app/shared/domain/transforms/sort_rows.py +94 -0
  306. precis_cli-0.1.3/app/shared/domain/transforms/string_split.py +84 -0
  307. precis_cli-0.1.3/app/shared/domain/transforms/strip.py +73 -0
  308. precis_cli-0.1.3/app/shared/domain/transforms/substring.py +92 -0
  309. precis_cli-0.1.3/app/shared/domain/transforms/upper_case.py +70 -0
  310. precis_cli-0.1.3/app/shared/domain/transforms/weighted_sum.py +104 -0
  311. precis_cli-0.1.3/app/shared/domain/validation_constraints.py +69 -0
  312. precis_cli-0.1.3/app/shared/services/__init__.py +62 -0
  313. precis_cli-0.1.3/app/shared/services/ai/__init__.py +48 -0
  314. precis_cli-0.1.3/app/shared/services/ai/agent/__init__.py +40 -0
  315. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/__init__.py +47 -0
  316. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/apply_actions.py +592 -0
  317. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/ask_user.py +237 -0
  318. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/read_canvas.py +140 -0
  319. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/read_project.py +160 -0
  320. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/read_table.py +301 -0
  321. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/schemas.py +105 -0
  322. precis_cli-0.1.3/app/shared/services/ai/agent/chat_tools/validate_table.py +131 -0
  323. precis_cli-0.1.3/app/shared/services/ai/agent/executor.py +554 -0
  324. precis_cli-0.1.3/app/shared/services/ai/agent/memory.py +256 -0
  325. precis_cli-0.1.3/app/shared/services/ai/agent/planner.py +282 -0
  326. precis_cli-0.1.3/app/shared/services/ai/agent/tool_registry.py +296 -0
  327. precis_cli-0.1.3/app/shared/services/ai/agent/tools/__init__.py +32 -0
  328. precis_cli-0.1.3/app/shared/services/ai/agent/tools/config_generate.py +133 -0
  329. precis_cli-0.1.3/app/shared/services/ai/agent/tools/config_refine.py +109 -0
  330. precis_cli-0.1.3/app/shared/services/ai/agent/tools/config_validate.py +403 -0
  331. precis_cli-0.1.3/app/shared/services/ai/agent/tools/merge_results.py +136 -0
  332. precis_cli-0.1.3/app/shared/services/ai/agent/tools/plan_chunks.py +79 -0
  333. precis_cli-0.1.3/app/shared/services/ai/agent/tools/script_parse.py +359 -0
  334. precis_cli-0.1.3/app/shared/services/ai/agent/types.py +138 -0
  335. precis_cli-0.1.3/app/shared/services/ai/chat_agent_runner.py +596 -0
  336. precis_cli-0.1.3/app/shared/services/ai/chat_orchestrator.py +725 -0
  337. precis_cli-0.1.3/app/shared/services/ai/failure_messages.py +65 -0
  338. precis_cli-0.1.3/app/shared/services/ai/job_storage.py +274 -0
  339. precis_cli-0.1.3/app/shared/services/ai/migrate_service.py +550 -0
  340. precis_cli-0.1.3/app/shared/services/ai/streaming/__init__.py +65 -0
  341. precis_cli-0.1.3/app/shared/services/ai/streaming/event_journal.py +197 -0
  342. precis_cli-0.1.3/app/shared/services/ai/streaming/orchestrator.py +262 -0
  343. precis_cli-0.1.3/app/shared/services/ai/streaming/pending_interaction_store.py +227 -0
  344. precis_cli-0.1.3/app/shared/services/ai/streaming/sse_response.py +148 -0
  345. precis_cli-0.1.3/app/shared/services/ai/streaming/types.py +73 -0
  346. precis_cli-0.1.3/app/shared/services/ai/types.py +213 -0
  347. precis_cli-0.1.3/app/shared/services/ai/utils.py +322 -0
  348. precis_cli-0.1.3/app/shared/services/diff/config_diff.py +320 -0
  349. precis_cli-0.1.3/app/shared/services/hardware.py +237 -0
  350. precis_cli-0.1.3/app/shared/services/llm/__init__.py +62 -0
  351. precis_cli-0.1.3/app/shared/services/llm/actions/__init__.py +42 -0
  352. precis_cli-0.1.3/app/shared/services/llm/actions/_canvas_validator.py +147 -0
  353. precis_cli-0.1.3/app/shared/services/llm/actions/_constraint_validator.py +401 -0
  354. precis_cli-0.1.3/app/shared/services/llm/actions/_regex_validator.py +85 -0
  355. precis_cli-0.1.3/app/shared/services/llm/actions/_schema_validator.py +82 -0
  356. precis_cli-0.1.3/app/shared/services/llm/actions/_settings_validator.py +76 -0
  357. precis_cli-0.1.3/app/shared/services/llm/actions/_transform_validator.py +78 -0
  358. precis_cli-0.1.3/app/shared/services/llm/actions/action_handlers.py +400 -0
  359. precis_cli-0.1.3/app/shared/services/llm/actions/action_parser.py +63 -0
  360. precis_cli-0.1.3/app/shared/services/llm/actions/action_processor.py +468 -0
  361. precis_cli-0.1.3/app/shared/services/llm/actions/action_validator.py +311 -0
  362. precis_cli-0.1.3/app/shared/services/llm/actions/diff_compute.py +195 -0
  363. precis_cli-0.1.3/app/shared/services/llm/actions/regex_handlers.py +284 -0
  364. precis_cli-0.1.3/app/shared/services/llm/actions/registry.py +336 -0
  365. precis_cli-0.1.3/app/shared/services/llm/actions/schema_handlers.py +335 -0
  366. precis_cli-0.1.3/app/shared/services/llm/actions/settings_handlers.py +180 -0
  367. precis_cli-0.1.3/app/shared/services/llm/actions/specs.py +259 -0
  368. precis_cli-0.1.3/app/shared/services/llm/actions/transform_handlers.py +279 -0
  369. precis_cli-0.1.3/app/shared/services/llm/actions/validation_types.py +147 -0
  370. precis_cli-0.1.3/app/shared/services/llm/cache/__init__.py +18 -0
  371. precis_cli-0.1.3/app/shared/services/llm/cache/response_cache.py +80 -0
  372. precis_cli-0.1.3/app/shared/services/llm/chat/__init__.py +35 -0
  373. precis_cli-0.1.3/app/shared/services/llm/chat/chat_system_prompt.py +561 -0
  374. precis_cli-0.1.3/app/shared/services/llm/chat/response_parser.py +296 -0
  375. precis_cli-0.1.3/app/shared/services/llm/config/__init__.py +45 -0
  376. precis_cli-0.1.3/app/shared/services/llm/config/crypto.py +135 -0
  377. precis_cli-0.1.3/app/shared/services/llm/config/loader.py +258 -0
  378. precis_cli-0.1.3/app/shared/services/llm/config/models.py +202 -0
  379. precis_cli-0.1.3/app/shared/services/llm/config/presets.py +128 -0
  380. precis_cli-0.1.3/app/shared/services/llm/config_generator.py +163 -0
  381. precis_cli-0.1.3/app/shared/services/llm/constraints/__init__.py +41 -0
  382. precis_cli-0.1.3/app/shared/services/llm/constraints/constraint_builder.py +177 -0
  383. precis_cli-0.1.3/app/shared/services/llm/constraints/constraint_deletion.py +84 -0
  384. precis_cli-0.1.3/app/shared/services/llm/constraints/constraint_id.py +174 -0
  385. precis_cli-0.1.3/app/shared/services/llm/constraints/frontend_instructions.py +333 -0
  386. precis_cli-0.1.3/app/shared/services/llm/constraints/inline_batch.py +279 -0
  387. precis_cli-0.1.3/app/shared/services/llm/discovery/__init__.py +35 -0
  388. precis_cli-0.1.3/app/shared/services/llm/discovery/scanner.py +181 -0
  389. precis_cli-0.1.3/app/shared/services/llm/generation/__init__.py +42 -0
  390. precis_cli-0.1.3/app/shared/services/llm/generation/agent_wiring.py +156 -0
  391. precis_cli-0.1.3/app/shared/services/llm/generation/config_builder.py +386 -0
  392. precis_cli-0.1.3/app/shared/services/llm/generation/errors.py +36 -0
  393. precis_cli-0.1.3/app/shared/services/llm/generation/existing_config.py +99 -0
  394. precis_cli-0.1.3/app/shared/services/llm/generation/profiler.py +279 -0
  395. precis_cli-0.1.3/app/shared/services/llm/generation/prompt_builder.py +199 -0
  396. precis_cli-0.1.3/app/shared/services/llm/generation/response_parser.py +144 -0
  397. precis_cli-0.1.3/app/shared/services/llm/generation/service.py +622 -0
  398. precis_cli-0.1.3/app/shared/services/llm/models.py +104 -0
  399. precis_cli-0.1.3/app/shared/services/llm/providers/__init__.py +48 -0
  400. precis_cli-0.1.3/app/shared/services/llm/providers/base.py +310 -0
  401. precis_cli-0.1.3/app/shared/services/llm/providers/cached_provider.py +90 -0
  402. precis_cli-0.1.3/app/shared/services/llm/providers/ollama.py +498 -0
  403. precis_cli-0.1.3/app/shared/services/llm/providers/openai.py +334 -0
  404. precis_cli-0.1.3/app/shared/services/llm/providers/registry.py +108 -0
  405. precis_cli-0.1.3/app/shared/services/llm/schema_resolver.py +141 -0
  406. precis_cli-0.1.3/app/shared/services/llm/suggestion_utils.py +219 -0
  407. precis_cli-0.1.3/app/shared/services/llm/validate_executor.py +163 -0
  408. precis_cli-0.1.3/app/shared/services/llm/yaml_io.py +406 -0
  409. precis_cli-0.1.3/app/shared/services/preview/__init__.py +18 -0
  410. precis_cli-0.1.3/app/shared/services/preview/loader.py +145 -0
  411. precis_cli-0.1.3/app/shared/services/preview/path_validation.py +138 -0
  412. precis_cli-0.1.3/app/shared/services/project_loader.py +57 -0
  413. precis_cli-0.1.3/app/shared/services/schema_inference.py +260 -0
  414. precis_cli-0.1.3/app/shared/services/schema_runtime_builder.py +120 -0
  415. precis_cli-0.1.3/app/shared/services/validation/__init__.py +52 -0
  416. precis_cli-0.1.3/app/shared/services/validation/chunked_loader.py +509 -0
  417. precis_cli-0.1.3/app/shared/services/validation/dag/__init__.py +35 -0
  418. precis_cli-0.1.3/app/shared/services/validation/dag/builder.py +141 -0
  419. precis_cli-0.1.3/app/shared/services/validation/dag/executor.py +225 -0
  420. precis_cli-0.1.3/app/shared/services/validation/dag/sorter.py +77 -0
  421. precis_cli-0.1.3/app/shared/services/validation/data_loader.py +231 -0
  422. precis_cli-0.1.3/app/shared/services/validation/engine.py +446 -0
  423. precis_cli-0.1.3/app/shared/services/validation/executor.py +1030 -0
  424. precis_cli-0.1.3/app/shared/services/validation/extractors.py +266 -0
  425. precis_cli-0.1.3/app/shared/services/validation/history.py +209 -0
  426. precis_cli-0.1.3/app/shared/services/validation/json_payload.py +136 -0
  427. precis_cli-0.1.3/app/shared/services/validation/loader.py +152 -0
  428. precis_cli-0.1.3/app/shared/services/validation/memory_monitor.py +179 -0
  429. precis_cli-0.1.3/app/shared/services/validation/postprocess.py +208 -0
  430. precis_cli-0.1.3/app/shared/services/validation/progress.py +64 -0
  431. precis_cli-0.1.3/app/shared/services/validation/report_export.py +222 -0
  432. precis_cli-0.1.3/app/shared/services/validation/resolver.py +180 -0
  433. precis_cli-0.1.3/app/shared/services/validation/service.py +418 -0
  434. precis_cli-0.1.3/app/shared/services/validation/types.py +238 -0
  435. precis_cli-0.1.3/app/shared/services/validation/validators/__init__.py +36 -0
  436. precis_cli-0.1.3/app/shared/services/validation/validators/adapter.py +182 -0
  437. precis_cli-0.1.3/app/shared/services/validation/validators/base.py +332 -0
  438. precis_cli-0.1.3/app/shared/services/validation/validators/composite.py +233 -0
  439. precis_cli-0.1.3/app/shared/services/validation/validators/date_logic.py +276 -0
  440. precis_cli-0.1.3/app/start_server.py +133 -0
  441. precis_cli-0.1.3/precis_cli.egg-info/PKG-INFO +180 -0
  442. precis_cli-0.1.3/precis_cli.egg-info/SOURCES.txt +448 -0
  443. precis_cli-0.1.3/precis_cli.egg-info/dependency_links.txt +1 -0
  444. precis_cli-0.1.3/precis_cli.egg-info/entry_points.txt +4 -0
  445. precis_cli-0.1.3/precis_cli.egg-info/requires.txt +49 -0
  446. precis_cli-0.1.3/precis_cli.egg-info/top_level.txt +1 -0
  447. precis_cli-0.1.3/pyproject.toml +188 -0
  448. precis_cli-0.1.3/setup.cfg +4 -0
  449. precis_cli-0.1.3/tests/test_local_file_reporter.py +126 -0
  450. precis_cli-0.1.3/tests/test_schema_builder.py +246 -0
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include pyproject.toml
3
+ recursive-include app *.yaml
@@ -0,0 +1,180 @@
1
+ Metadata-Version: 2.4
2
+ Name: precis-cli
3
+ Version: 0.1.3
4
+ Summary: Precis - 可配置数据校验工具 CLI(校验 CSV/Excel/JSON 数据质量)
5
+ Author: Precis Team
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/AirSaiga/Precis
8
+ Project-URL: Repository, https://github.com/AirSaiga/Precis
9
+ Project-URL: Bug Tracker, https://github.com/AirSaiga/Precis/issues
10
+ Project-URL: Discussions, https://github.com/AirSaiga/Precis/discussions
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Classifier: Topic :: Software Development :: Testing
19
+ Requires-Python: <3.14,>=3.12
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: pydantic>=2.12.0
22
+ Requires-Dist: pandas<3.0,>=2.2.0
23
+ Requires-Dist: openpyxl>=3.1.5
24
+ Requires-Dist: xlrd>=2.0.1
25
+ Requires-Dist: SQLAlchemy>=2.0.48
26
+ Requires-Dist: pyyaml>=6.0.3
27
+ Requires-Dist: ruamel.yaml>=0.19.0
28
+ Requires-Dist: rich>=13.0.0
29
+ Requires-Dist: readchar>=4.2.0
30
+ Requires-Dist: cryptography>=44.0.0
31
+ Requires-Dist: simpleeval>=1.0.0
32
+ Requires-Dist: filelock>=3.12.0
33
+ Provides-Extra: api
34
+ Requires-Dist: fastapi!=0.136.3,>=0.135.0; extra == "api"
35
+ Requires-Dist: uvicorn>=0.42.0; extra == "api"
36
+ Requires-Dist: email-validator>=2.3.0; extra == "api"
37
+ Requires-Dist: uritemplate>=4.2.0; extra == "api"
38
+ Requires-Dist: python-multipart>=0.0.26; extra == "api"
39
+ Requires-Dist: cryptography>=44.0.0; extra == "api"
40
+ Provides-Extra: ai
41
+ Requires-Dist: openai>=1.6.0; extra == "ai"
42
+ Requires-Dist: aiohttp>=3.9.0; extra == "ai"
43
+ Requires-Dist: psutil>=5.9.6; extra == "ai"
44
+ Provides-Extra: mcp
45
+ Requires-Dist: mcp<2,>=1.30.0; extra == "mcp"
46
+ Provides-Extra: completion
47
+ Requires-Dist: pyreadline3>=0.1.8; sys_platform == "win32" and extra == "completion"
48
+ Provides-Extra: full
49
+ Requires-Dist: precis-cli[ai,api,completion,mcp]; extra == "full"
50
+ Provides-Extra: dev
51
+ Requires-Dist: precis-cli[ai,api,mcp]; extra == "dev"
52
+ Requires-Dist: debugpy>=1.8.0; extra == "dev"
53
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
54
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
55
+ Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
56
+ Requires-Dist: pytest>=9.0.3; extra == "dev"
57
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
58
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
59
+ Requires-Dist: httpx>=0.27.0; extra == "dev"
60
+ Requires-Dist: build>=1.0.0; extra == "dev"
61
+ Requires-Dist: twine>=5.0.0; extra == "dev"
62
+
63
+ # Precis 后端 / Precis Backend
64
+
65
+ > **Alpha** — 核心功能已成型,接口可能调整。
66
+
67
+ FastAPI + CLI + 核心校验引擎,采用三层分离架构。
68
+
69
+ 完整项目说明请见 [根目录 README.md](../README.md)。
70
+
71
+ ---
72
+
73
+ ## 架构
74
+
75
+ ```
76
+ backend/app/
77
+ ├── api/ # API 层
78
+ │ ├── main.py # FastAPI 应用入口(路由注册、中间件、CORS)
79
+ │ ├── dependencies.py # 依赖注入
80
+ │ ├── middleware/ # 中间件
81
+ │ ├── models/ # 请求/响应 Pydantic 模型
82
+ │ ├── routers/ # 路由定义
83
+ │ │ ├── core/ # 核心路由(项目、工作区)
84
+ │ │ ├── project/ # V2 项目 CRUD(Schema、Constraint、Regex、Transform)
85
+ │ │ ├── validation/ # 校验执行与历史
86
+ │ │ ├── preview/ # 数据预览
87
+ │ │ └── ai/ # AI 配置生成
88
+ │ └── services/ # API 层服务
89
+ ├── cli/ # 交互式命令行(shell/ REPL、start 启动器、__main__)
90
+ ├── shared/ # 三层分离架构
91
+ │ ├── core/ # 框架级基础设施
92
+ │ │ # 文件 I/O、配置解析(YAML)、数据加载
93
+ │ ├── domain/ # 纯业务领域逻辑(无 I/O 依赖)
94
+ │ │ ├── constraints/ # 10 种约束类型定义(not_null.py、unique.py 等,每种一个文件)
95
+ │ │ ├── transforms/ # 22 种转换类型定义(string_split.py、math_expr.py 等,每种一个文件)
96
+ │ │ ├── data_types.py # 数据类型定义(string/integer/float/decimal/boolean/date)
97
+ │ │ ├── dataset_schema.py # Schema 模型
98
+ │ │ ├── expression_system.py # 表达式求值系统
99
+ │ │ └── schema/ # Schema 相关领域逻辑
100
+ │ └── services/ # 应用服务(编排 core 和 domain)
101
+ │ ├── validation/ # 校验引擎(两阶段流水线)
102
+ │ │ ├── executor.py # ValidationExecutor 主编排器
103
+ │ │ ├── engine.py # 校验执行引擎
104
+ │ │ ├── data_loader.py # 数据加载
105
+ │ │ ├── loader.py # 配置加载
106
+ │ │ ├── resolver.py # 数据源解析
107
+ │ │ ├── extractors.py # 派生列提取(regex)
108
+ │ │ ├── history.py # 校验历史持久化
109
+ │ │ ├── dag/ # 转换 DAG 执行
110
+ │ │ ├── validators/ # 各类型校验器(每种约束一个文件)
111
+ │ │ └── types.py # 校验类型定义
112
+ │ ├── ai/ # AI 服务
113
+ │ ├── llm/ # LLM 集成(OpenAI / Ollama)
114
+ │ ├── preview/ # 数据预览服务
115
+ │ ├── diff/ # 配置差异比较
116
+ │ └── hardware.py # 硬件检测
117
+ └── start_server.py # 服务器启动入口
118
+ ```
119
+
120
+ ### 关键约定
121
+
122
+ - `domain/` 不得导入 `core/` 或 `services/`,保持纯净
123
+ - API 路由在 `api/routers/`,请求/响应模型在 `api/models/`
124
+ - 路由注册入口:`api/main.py`
125
+ - 所有请求通过 `X-Project-Config-Path` header 标识当前项目
126
+ - 校验类接口约定"永远返回 200、结果看 body";配置文件损坏(如清单 YAML 语法错误/空文件)返回 422 并附说明
127
+ - 打包模式下 `Origin: null` 跨域请求须携带 `X-Precis-Auth` 头(值来自 Electron 注入的 `PRECIS_API_TOKEN`,见 `api/middleware/token_auth.py`);未配置 token 时中间件直通,`PRECIS_ALLOW_NULL_ORIGIN=1` 为旧的全局放行兼容开关
128
+
129
+ ---
130
+
131
+ ## 校验引擎(两阶段流水线)
132
+
133
+ ```
134
+ 阶段 1: 数据加载与预处理
135
+ ├── DataSourceResolver → 解析文件路径
136
+ ├── DataLoader → 加载 Excel/CSV/JSON
137
+ ├── process_dataframe → 类型转换、格式检查
138
+ ├── extractors → 派生列提取(regex)
139
+ └── Transform DAG → 拓扑排序执行 transform 链
140
+
141
+ 阶段 2: 约束校验
142
+ └── 逐约束调用 validate(),聚合错误
143
+ (validators/ 下每种类型一个:not_null.py, unique.py, foreign_key.py ...)
144
+ ```
145
+
146
+ ---
147
+
148
+ ## 开发命令
149
+
150
+ ```bash
151
+ # 安装
152
+ python -m venv .venv
153
+ pip install -e ".[dev]"
154
+
155
+ # 运行
156
+ python -m uvicorn app.api.main:app --reload --port 18000
157
+
158
+ # 代码检查
159
+ python -m ruff check . # lint(不自动修复)
160
+ python -m ruff check --fix . # lint 自动修复
161
+ python -m ruff format . # 格式化
162
+ python -m mypy . # 类型检查
163
+
164
+ # 测试
165
+ python -m pytest # 运行全部测试
166
+
167
+ # CLI
168
+ python -B -m app.cli
169
+ ```
170
+
171
+ ---
172
+
173
+ ## 配置文件格式(V2 YAML)
174
+
175
+ | 文件类型 | 命名 | 说明 |
176
+ |---------|------|------|
177
+ | 项目清单 | `project.precis.yaml` | 索引所有 Schema/Constraint/Regex/Transform 资源 |
178
+ | Schema | `*.schema.yaml` | 表结构定义(列、数据类型、内嵌约束) |
179
+ | Constraint | `*.constraint.yaml` | 独立约束(refs + params 分离设计) |
180
+ | Regex | `*.regex.yaml` | 正则节点(引用模式或直接模式) |
@@ -0,0 +1,118 @@
1
+ # Precis 后端 / Precis Backend
2
+
3
+ > **Alpha** — 核心功能已成型,接口可能调整。
4
+
5
+ FastAPI + CLI + 核心校验引擎,采用三层分离架构。
6
+
7
+ 完整项目说明请见 [根目录 README.md](../README.md)。
8
+
9
+ ---
10
+
11
+ ## 架构
12
+
13
+ ```
14
+ backend/app/
15
+ ├── api/ # API 层
16
+ │ ├── main.py # FastAPI 应用入口(路由注册、中间件、CORS)
17
+ │ ├── dependencies.py # 依赖注入
18
+ │ ├── middleware/ # 中间件
19
+ │ ├── models/ # 请求/响应 Pydantic 模型
20
+ │ ├── routers/ # 路由定义
21
+ │ │ ├── core/ # 核心路由(项目、工作区)
22
+ │ │ ├── project/ # V2 项目 CRUD(Schema、Constraint、Regex、Transform)
23
+ │ │ ├── validation/ # 校验执行与历史
24
+ │ │ ├── preview/ # 数据预览
25
+ │ │ └── ai/ # AI 配置生成
26
+ │ └── services/ # API 层服务
27
+ ├── cli/ # 交互式命令行(shell/ REPL、start 启动器、__main__)
28
+ ├── shared/ # 三层分离架构
29
+ │ ├── core/ # 框架级基础设施
30
+ │ │ # 文件 I/O、配置解析(YAML)、数据加载
31
+ │ ├── domain/ # 纯业务领域逻辑(无 I/O 依赖)
32
+ │ │ ├── constraints/ # 10 种约束类型定义(not_null.py、unique.py 等,每种一个文件)
33
+ │ │ ├── transforms/ # 22 种转换类型定义(string_split.py、math_expr.py 等,每种一个文件)
34
+ │ │ ├── data_types.py # 数据类型定义(string/integer/float/decimal/boolean/date)
35
+ │ │ ├── dataset_schema.py # Schema 模型
36
+ │ │ ├── expression_system.py # 表达式求值系统
37
+ │ │ └── schema/ # Schema 相关领域逻辑
38
+ │ └── services/ # 应用服务(编排 core 和 domain)
39
+ │ ├── validation/ # 校验引擎(两阶段流水线)
40
+ │ │ ├── executor.py # ValidationExecutor 主编排器
41
+ │ │ ├── engine.py # 校验执行引擎
42
+ │ │ ├── data_loader.py # 数据加载
43
+ │ │ ├── loader.py # 配置加载
44
+ │ │ ├── resolver.py # 数据源解析
45
+ │ │ ├── extractors.py # 派生列提取(regex)
46
+ │ │ ├── history.py # 校验历史持久化
47
+ │ │ ├── dag/ # 转换 DAG 执行
48
+ │ │ ├── validators/ # 各类型校验器(每种约束一个文件)
49
+ │ │ └── types.py # 校验类型定义
50
+ │ ├── ai/ # AI 服务
51
+ │ ├── llm/ # LLM 集成(OpenAI / Ollama)
52
+ │ ├── preview/ # 数据预览服务
53
+ │ ├── diff/ # 配置差异比较
54
+ │ └── hardware.py # 硬件检测
55
+ └── start_server.py # 服务器启动入口
56
+ ```
57
+
58
+ ### 关键约定
59
+
60
+ - `domain/` 不得导入 `core/` 或 `services/`,保持纯净
61
+ - API 路由在 `api/routers/`,请求/响应模型在 `api/models/`
62
+ - 路由注册入口:`api/main.py`
63
+ - 所有请求通过 `X-Project-Config-Path` header 标识当前项目
64
+ - 校验类接口约定"永远返回 200、结果看 body";配置文件损坏(如清单 YAML 语法错误/空文件)返回 422 并附说明
65
+ - 打包模式下 `Origin: null` 跨域请求须携带 `X-Precis-Auth` 头(值来自 Electron 注入的 `PRECIS_API_TOKEN`,见 `api/middleware/token_auth.py`);未配置 token 时中间件直通,`PRECIS_ALLOW_NULL_ORIGIN=1` 为旧的全局放行兼容开关
66
+
67
+ ---
68
+
69
+ ## 校验引擎(两阶段流水线)
70
+
71
+ ```
72
+ 阶段 1: 数据加载与预处理
73
+ ├── DataSourceResolver → 解析文件路径
74
+ ├── DataLoader → 加载 Excel/CSV/JSON
75
+ ├── process_dataframe → 类型转换、格式检查
76
+ ├── extractors → 派生列提取(regex)
77
+ └── Transform DAG → 拓扑排序执行 transform 链
78
+
79
+ 阶段 2: 约束校验
80
+ └── 逐约束调用 validate(),聚合错误
81
+ (validators/ 下每种类型一个:not_null.py, unique.py, foreign_key.py ...)
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 开发命令
87
+
88
+ ```bash
89
+ # 安装
90
+ python -m venv .venv
91
+ pip install -e ".[dev]"
92
+
93
+ # 运行
94
+ python -m uvicorn app.api.main:app --reload --port 18000
95
+
96
+ # 代码检查
97
+ python -m ruff check . # lint(不自动修复)
98
+ python -m ruff check --fix . # lint 自动修复
99
+ python -m ruff format . # 格式化
100
+ python -m mypy . # 类型检查
101
+
102
+ # 测试
103
+ python -m pytest # 运行全部测试
104
+
105
+ # CLI
106
+ python -B -m app.cli
107
+ ```
108
+
109
+ ---
110
+
111
+ ## 配置文件格式(V2 YAML)
112
+
113
+ | 文件类型 | 命名 | 说明 |
114
+ |---------|------|------|
115
+ | 项目清单 | `project.precis.yaml` | 索引所有 Schema/Constraint/Regex/Transform 资源 |
116
+ | Schema | `*.schema.yaml` | 表结构定义(列、数据类型、内嵌约束) |
117
+ | Constraint | `*.constraint.yaml` | 独立约束(refs + params 分离设计) |
118
+ | Regex | `*.regex.yaml` | 正则节点(引用模式或直接模式) |
@@ -0,0 +1,16 @@
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
+ """@fileoverview Precis 后端应用包入口"""
@@ -0,0 +1,32 @@
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 API 模块包入口
18
+
19
+ 功能概述:
20
+ - 标记 backend/app/api 目录为 Python 包
21
+ - 作为 API 层的统一入口,供外部导入使用
22
+
23
+ 架构设计:
24
+ - 该包包含 FastAPI 应用、依赖注入、中间件、数据模型和路由等子模块
25
+ - 通过 __init__.py 暴露公共接口,简化外部导入路径
26
+
27
+ 输入示例:
28
+ from app.api import main
29
+
30
+ 输出示例:
31
+ 无直接输出,仅作为包标记
32
+ """
@@ -0,0 +1,185 @@
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 API 依赖注入模块
18
+
19
+ 功能概述:
20
+ - 提供 FastAPI 依赖注入函数
21
+ - 从 HTTP Header 获取并验证项目配置路径
22
+ - 提供 ProjectStore 数据容器在请求生命周期内传递项目路径
23
+
24
+ 架构设计:
25
+ - 使用 FastAPI 的 Depends 机制实现依赖注入
26
+ - 通过 X-Project-Config-Path Header 接收项目路径,支持多项目
27
+ - 路径验证包括绝对路径检查和目录存在性检查
28
+ - ProjectStore 可轻松 mock,便于单元测试
29
+
30
+ 输入示例:
31
+ Header: X-Project-Config-Path: D:/project (项目根,须含 project.precis.yaml)
32
+
33
+ 输出示例:
34
+ ProjectStore(project_path="D:/project")
35
+ """
36
+
37
+ # backend/app/api/dependencies.py
38
+ import os
39
+
40
+ from fastapi import Depends, Header, HTTPException
41
+
42
+
43
+ class ProjectStore:
44
+ """
45
+ 项目存储类。
46
+
47
+ 这是一个简单的数据容器类,用于在 FastAPI 依赖注入链中传递项目路径信息。
48
+ 通过将项目路径封装为对象,可以在类型提示中明确表达依赖关系。
49
+
50
+ 设计目的:
51
+ - 提供类型安全的项目路径传递方式
52
+ - 方便在路由处理器中获取项目根目录
53
+ - 支持依赖注入的单元测试(可轻松 mock)
54
+
55
+ 属性:
56
+ project_path: 项目配置目录的绝对路径
57
+ """
58
+
59
+ def __init__(self, project_path: str):
60
+ """
61
+ 初始化项目存储对象。
62
+
63
+ :param project_path: 项目配置目录的绝对路径
64
+ """
65
+ self.project_path = project_path
66
+
67
+
68
+ async def get_project_config_path(
69
+ x_project_config_path: str = Header(..., description="项目根目录的绝对路径(须含 project.precis.yaml)"),
70
+ ) -> str:
71
+ """
72
+ 获取并验证项目配置路径的依赖函数。
73
+
74
+ 该函数是 FastAPI 的依赖项,用于从 HTTP Header 中提取项目配置路径,
75
+ 并进行合法性验证:
76
+ 1. 检查路径是否为绝对路径
77
+ 2. 检查路径对应的目录是否存在
78
+ 3. 必须含 project.precis.yaml(合法 Precis 项目根标识)
79
+
80
+ B-sec3 安全加固: 原校验仅"绝对+是目录",任意目录都能当项目根,导致后续
81
+ manifest/数据源/AI 配置写入可能落到任意目录。现对齐 AI 路由的
82
+ validate_project_path,要求 manifest 存在。项目首次创建走独立的
83
+ /projects/create 端点(不经此依赖),故不影响创建流程。
84
+
85
+ 处理流程:
86
+ 1. 从 X-Project-Config-Path Header 获取路径
87
+ 2. 委托 _validate_project_root 做完整校验(绝对路径/拒绝 `..`/目录存在/manifest 存在)
88
+ 3. 返回验证后的绝对路径
89
+
90
+ :param x_project_config_path: HTTP Header 中的项目配置路径
91
+ :return: 验证通过的项目配置绝对路径
92
+ :raises HTTPException: 路径验证失败时返回 400 或 404 错误
93
+
94
+ Header 示例(项目根目录语义,不是 .precis/ 子目录):
95
+ X-Project-Config-Path: /path/to/project
96
+ """
97
+ return _validate_project_root(x_project_config_path)
98
+
99
+
100
+ def _validate_project_root(raw_path: str | None) -> str:
101
+ """校验路径是否为合法 Precis 项目根(单一事实源)。
102
+
103
+ B-sec3: 统一 get_project_config_path 与 ai/utils.validate_project_path 的校验逻辑,
104
+ 消除双套不一致(原 ai 路径要求 manifest,通用依赖不要求,弱者为默认)。
105
+
106
+ 要求:
107
+ - 非空
108
+ - 必须是绝对路径(Windows 下 abspath 会把相对路径转绝对,故须在规范化前先判)
109
+ - 不含 ".."(normpath 后仍不含)
110
+ - 必须是存在的目录
111
+ - 必须含 project.precis.yaml(合法项目根标识)
112
+
113
+ 参数:
114
+ raw_path: 原始路径字符串(通常来自 Header)
115
+
116
+ 返回:
117
+ 规范化后的绝对路径
118
+
119
+ 抛出:
120
+ HTTPException(400): 校验失败
121
+ """
122
+ if not raw_path:
123
+ raise HTTPException(status_code=400, detail="X-Project-Config-Path header 不能为空。")
124
+ # 步骤1:先校验原始输入是否为绝对路径
125
+ # 在 Windows 下,os.path.abspath 会把相对路径(如 "../project")解析成绝对路径,
126
+ # 导致后续 isabs 检查无法拒绝相对路径。因此必须在规范化之前先做判断。
127
+ if not os.path.isabs(raw_path):
128
+ raise HTTPException(status_code=400, detail="X-Project-Config-Path header 必须是一个绝对路径。")
129
+
130
+ # 路径标准化并解析为绝对路径,防御 Path Traversal
131
+ normalized_path = os.path.abspath(os.path.normpath(raw_path))
132
+ # 拒绝路径穿越(normpath 后仍出现 .. 说明超出根)
133
+ if ".." in normalized_path.split(os.sep):
134
+ raise HTTPException(status_code=400, detail="X-Project-Config-Path 不允许包含 .. 目录穿越。")
135
+
136
+ # 步骤2:验证路径对应的目录是否存在
137
+ if not os.path.isdir(normalized_path):
138
+ raise HTTPException(status_code=404, detail=f"提供的项目配置路径不存在: {normalized_path}")
139
+
140
+ # 步骤3:验证是合法 Precis 项目根(含 manifest)
141
+ manifest = os.path.join(normalized_path, "project.precis.yaml")
142
+ if not os.path.isfile(manifest):
143
+ # §2.1: manifest 缺失属"资源不存在"语义,统一 404(原 400 与 GET /manifest
144
+ # 端点对同一情形不同状态码,且前端 404 自愈链永不触发)。detail 携带结构化
145
+ # 错误码,前端按 detail.code 识别(不再匹配中文措辞前缀)。
146
+ raise HTTPException(
147
+ status_code=404,
148
+ detail={
149
+ "code": "PROJECT_NOT_FOUND",
150
+ "message": (
151
+ "项目路径下未找到 project.precis.yaml(非合法 Precis 项目根)。"
152
+ "若要初始化新项目,请使用 POST /api/latest/projects/create。"
153
+ ),
154
+ "path": normalized_path,
155
+ },
156
+ )
157
+
158
+ return normalized_path
159
+
160
+
161
+ async def get_project_store(project_path: str = Depends(get_project_config_path)) -> ProjectStore:
162
+ """
163
+ 创建项目存储对象的依赖函数。
164
+
165
+ 该函数是 FastAPI 的依赖项,负责:
166
+ 1. 调用 get_project_config_path 获取验证后的项目路径
167
+ 2. 创建 ProjectStore 实例并返回
168
+
169
+ 这种分层设计的好处:
170
+ - 职责分离:路径验证和对象创建分别处理
171
+ - 可复用性:get_project_config_path 可以被其他依赖函数复用
172
+ - 可测试性:每个函数都可以独立进行单元测试
173
+
174
+ :param project_path: 已验证的项目配置路径(由 get_project_config_path 注入)
175
+ :return: 包含项目路径的 ProjectStore 实例
176
+
177
+ 使用示例:
178
+ @app.get("/projects/{project_id}/schemas")
179
+ async def get_schemas(project: ProjectStore = Depends(get_project_store)):
180
+ # 可以直接使用 project.project_path 访问项目路径
181
+ schemas = load_schemas(project.project_path)
182
+ return schemas
183
+ """
184
+ # 创建并返回项目存储对象,将路径封装为对象形式
185
+ return ProjectStore(project_path=project_path)