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.
- app/__init__.py +16 -0
- app/api/__init__.py +32 -0
- app/api/dependencies.py +185 -0
- app/api/main.py +301 -0
- app/api/middleware/__init__.py +34 -0
- app/api/middleware/exception_handler.py +126 -0
- app/api/middleware/request_logging.py +97 -0
- app/api/middleware/token_auth.py +215 -0
- app/api/models/__init__.py +151 -0
- app/api/models/connection_rules.py +98 -0
- app/api/models/files.py +99 -0
- app/api/models/full_validation.py +554 -0
- app/api/models/project.py +117 -0
- app/api/models/projects.py +80 -0
- app/api/models/schema.py +121 -0
- app/api/models/v2_responses.py +46 -0
- app/api/models/validation.py +303 -0
- app/api/models/workspace.py +118 -0
- app/api/routers/__init__.py +56 -0
- app/api/routers/ai/__init__.py +36 -0
- app/api/routers/ai/chat.py +243 -0
- app/api/routers/ai/generate.py +156 -0
- app/api/routers/ai/hardware.py +199 -0
- app/api/routers/ai/jobs.py +544 -0
- app/api/routers/ai/migrate.py +471 -0
- app/api/routers/ai/models.py +352 -0
- app/api/routers/ai/ollama.py +108 -0
- app/api/routers/ai/providers.py +491 -0
- app/api/routers/ai/router.py +44 -0
- app/api/routers/ai/stream.py +281 -0
- app/api/routers/ai/utils.py +182 -0
- app/api/routers/core/__init__.py +34 -0
- app/api/routers/core/connection_rules.py +188 -0
- app/api/routers/core/data_sources.py +374 -0
- app/api/routers/core/regex.py +333 -0
- app/api/routers/core/reporting.py +263 -0
- app/api/routers/files/__init__.py +24 -0
- app/api/routers/files/ops.py +179 -0
- app/api/routers/files/transfer.py +101 -0
- app/api/routers/preview/__init__.py +35 -0
- app/api/routers/preview/content_mode.py +264 -0
- app/api/routers/preview/header_row.py +154 -0
- app/api/routers/preview/models.py +81 -0
- app/api/routers/preview/path_mode.py +440 -0
- app/api/routers/preview/router.py +30 -0
- app/api/routers/project/__init__.py +61 -0
- app/api/routers/project/base.py +111 -0
- app/api/routers/project/constraint.py +345 -0
- app/api/routers/project/full_config.py +411 -0
- app/api/routers/project/full_config_writer.py +327 -0
- app/api/routers/project/helpers.py +167 -0
- app/api/routers/project/inspection_fix.py +330 -0
- app/api/routers/project/manifest.py +605 -0
- app/api/routers/project/models.py +177 -0
- app/api/routers/project/pattern.py +268 -0
- app/api/routers/project/regex.py +358 -0
- app/api/routers/project/scanner.py +157 -0
- app/api/routers/project/schema.py +567 -0
- app/api/routers/project/schema_helpers.py +149 -0
- app/api/routers/project/settings.py +399 -0
- app/api/routers/project/template.py +325 -0
- app/api/routers/project/validation.py +227 -0
- app/api/routers/project/view.py +177 -0
- app/api/routers/project/workspaces.py +167 -0
- app/api/routers/projects/__init__.py +25 -0
- app/api/routers/projects/create.py +121 -0
- app/api/routers/projects/open.py +103 -0
- app/api/routers/projects/scan.py +100 -0
- app/api/routers/validation/__init__.py +39 -0
- app/api/routers/validation/common.py +263 -0
- app/api/routers/validation/content_mode.py +401 -0
- app/api/routers/validation/history.py +235 -0
- app/api/routers/validation/inline_mode.py +196 -0
- app/api/routers/validation/path_mode.py +314 -0
- app/api/routers/validation/router.py +51 -0
- app/api/services/full_validation_response_builder.py +412 -0
- app/api/services/io_error_messages.py +41 -0
- app/api/services/preview_service.py +248 -0
- app/cli/__init__.py +18 -0
- app/cli/__main__.py +30 -0
- app/cli/shared_services/__init__.py +42 -0
- app/cli/shared_services/config_ops.py +581 -0
- app/cli/shared_services/generation_ops.py +160 -0
- app/cli/shared_services/project_ops.py +288 -0
- app/cli/shell/__init__.py +48 -0
- app/cli/shell/commands/__init__.py +63 -0
- app/cli/shell/commands/ai/__init__.py +260 -0
- app/cli/shell/commands/ai/chat.py +331 -0
- app/cli/shell/commands/ai/delete.py +165 -0
- app/cli/shell/commands/ai/diff.py +70 -0
- app/cli/shell/commands/ai/display.py +428 -0
- app/cli/shell/commands/ai/executor.py +225 -0
- app/cli/shell/commands/ai/executor_utils.py +271 -0
- app/cli/shell/commands/ai/generate.py +285 -0
- app/cli/shell/commands/ai/interaction.py +262 -0
- app/cli/shell/commands/ai/migrate.py +281 -0
- app/cli/shell/commands/ai/resolver.py +224 -0
- app/cli/shell/commands/ai/status.py +101 -0
- app/cli/shell/commands/ai/switch.py +158 -0
- app/cli/shell/commands/ai/utils.py +52 -0
- app/cli/shell/commands/base.py +343 -0
- app/cli/shell/commands/config/__init__.py +131 -0
- app/cli/shell/commands/config/base.py +80 -0
- app/cli/shell/commands/config/check.py +246 -0
- app/cli/shell/commands/config/edit.py +148 -0
- app/cli/shell/commands/config/get.py +111 -0
- app/cli/shell/commands/config/init.py +123 -0
- app/cli/shell/commands/config/inspect.py +164 -0
- app/cli/shell/commands/config/list.py +104 -0
- app/cli/shell/commands/config/set.py +119 -0
- app/cli/shell/commands/config/show.py +150 -0
- app/cli/shell/commands/exit.py +67 -0
- app/cli/shell/commands/help.py +104 -0
- app/cli/shell/commands/infer_schema.py +156 -0
- app/cli/shell/commands/open.py +201 -0
- app/cli/shell/commands/project.py +215 -0
- app/cli/shell/commands/provider.py +619 -0
- app/cli/shell/commands/system.py +170 -0
- app/cli/shell/commands/validate.py +455 -0
- app/cli/shell/completer.py +231 -0
- app/cli/shell/config_storage.py +191 -0
- app/cli/shell/exceptions.py +90 -0
- app/cli/shell/formatter.py +371 -0
- app/cli/shell/interactive_menu.py +348 -0
- app/cli/shell/main.py +286 -0
- app/cli/shell/parser.py +266 -0
- app/cli/start.py +180 -0
- app/cli_main.py +52 -0
- app/mcp_server.py +311 -0
- app/shared/core/__init__.py +18 -0
- app/shared/core/app_version.py +59 -0
- app/shared/core/config/__init__.py +119 -0
- app/shared/core/config/server.py +193 -0
- app/shared/core/data_source/__init__.py +106 -0
- app/shared/core/data_source/loader.py +348 -0
- app/shared/core/data_source/loaders/__init__.py +213 -0
- app/shared/core/data_source/loaders/base.py +215 -0
- app/shared/core/data_source/loaders/converter.py +337 -0
- app/shared/core/data_source/loaders/csv_loader.py +252 -0
- app/shared/core/data_source/loaders/excel_loader.py +666 -0
- app/shared/core/data_source/loaders/extractor.py +268 -0
- app/shared/core/data_source/loaders/json_loader.py +354 -0
- app/shared/core/data_source/loaders/registry.py +88 -0
- app/shared/core/data_source/loaders/sql_loader.py +313 -0
- app/shared/core/data_source/loaders/strategies/__init__.py +100 -0
- app/shared/core/data_source/loaders/strategies/array_parser.py +277 -0
- app/shared/core/data_source/loaders/strategies/lines_parser.py +355 -0
- app/shared/core/data_source/loaders/strategies/object_parser.py +278 -0
- app/shared/core/data_source/schema_info.py +50 -0
- app/shared/core/data_source/specs/__init__.py +128 -0
- app/shared/core/data_source/specs/base.py +258 -0
- app/shared/core/data_source/specs/csv_source.py +137 -0
- app/shared/core/data_source/specs/excel_source.py +141 -0
- app/shared/core/data_source/specs/file_base.py +252 -0
- app/shared/core/data_source/specs/json_source.py +226 -0
- app/shared/core/data_source/specs/sql_source.py +161 -0
- app/shared/core/encoding.py +36 -0
- app/shared/core/io/__init__.py +24 -0
- app/shared/core/io/yaml.py +379 -0
- app/shared/core/manifest_schema/__init__.py +52 -0
- app/shared/core/manifest_schema/types.py +99 -0
- app/shared/core/manifest_schema/version.py +175 -0
- app/shared/core/patterns/__init__.py +24 -0
- app/shared/core/patterns/loader.py +134 -0
- app/shared/core/patterns/writer.py +244 -0
- app/shared/core/project/__init__.py +47 -0
- app/shared/core/project/constraint/builders/__init__.py +50 -0
- app/shared/core/project/constraint/builders/base.py +100 -0
- app/shared/core/project/constraint/builders/composite.py +77 -0
- app/shared/core/project/constraint/builders/conditional.py +67 -0
- app/shared/core/project/constraint/builders/foreign_key.py +53 -0
- app/shared/core/project/constraint/builders/registry.py +64 -0
- app/shared/core/project/constraint/builders/scripted.py +51 -0
- app/shared/core/project/constraint/builders/single_column.py +86 -0
- app/shared/core/project/constraint/builders/unique.py +53 -0
- app/shared/core/project/constraint/factory.py +170 -0
- app/shared/core/project/constraint/reader.py +214 -0
- app/shared/core/project/constraint/registry.py +233 -0
- app/shared/core/project/constraint/types/__init__.py +63 -0
- app/shared/core/project/constraint/types/constraint_file.py +261 -0
- app/shared/core/project/constraint/types/refs.py +460 -0
- app/shared/core/project/constraint/types.py +28 -0
- app/shared/core/project/constraint/writer.py +181 -0
- app/shared/core/project/loader/__init__.py +56 -0
- app/shared/core/project/loader/loader.py +30 -0
- app/shared/core/project/loader/loader_parts/config_inspector.py +137 -0
- app/shared/core/project/loader/loader_parts/embedded_constraints.py +224 -0
- app/shared/core/project/loader/loader_parts/file_loaders.py +58 -0
- app/shared/core/project/loader/loader_parts/inspection_ids.py +85 -0
- app/shared/core/project/loader/loader_parts/inspector_helpers.py +312 -0
- app/shared/core/project/loader/loader_parts/inspector_id_checks.py +274 -0
- app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +690 -0
- app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +286 -0
- app/shared/core/project/loader/loader_parts/loading_error_messages.py +298 -0
- app/shared/core/project/loader/loader_parts/main.py +432 -0
- app/shared/core/project/loader/loader_parts/path_validation.py +117 -0
- app/shared/core/project/loader/loader_parts/runtime.py +125 -0
- app/shared/core/project/loader/types.py +246 -0
- app/shared/core/project/manifest/coverage.py +391 -0
- app/shared/core/project/manifest/reader.py +260 -0
- app/shared/core/project/manifest/types.py +91 -0
- app/shared/core/project/manifest/types_parts/__init__.py +60 -0
- app/shared/core/project/manifest/types_parts/constants.py +40 -0
- app/shared/core/project/manifest/types_parts/data_source.py +68 -0
- app/shared/core/project/manifest/types_parts/info.py +59 -0
- app/shared/core/project/manifest/types_parts/manifest.py +294 -0
- app/shared/core/project/manifest/types_parts/refs.py +153 -0
- app/shared/core/project/manifest/types_parts/settings.py +92 -0
- app/shared/core/project/manifest/types_parts/settings_file_processing.py +64 -0
- app/shared/core/project/manifest/types_parts/settings_script_security.py +78 -0
- app/shared/core/project/manifest/types_parts/settings_validation.py +83 -0
- app/shared/core/project/manifest/types_parts/template.py +66 -0
- app/shared/core/project/manifest/writer.py +262 -0
- app/shared/core/project/manual_data/__init__.py +27 -0
- app/shared/core/project/manual_data/types.py +75 -0
- app/shared/core/project/regex/reader.py +197 -0
- app/shared/core/project/regex/types.py +405 -0
- app/shared/core/project/regex/writer.py +123 -0
- app/shared/core/project/schema/reader.py +170 -0
- app/shared/core/project/schema/types.py +47 -0
- app/shared/core/project/schema/types_parts/__init__.py +36 -0
- app/shared/core/project/schema/types_parts/column.py +174 -0
- app/shared/core/project/schema/types_parts/column_utils.py +72 -0
- app/shared/core/project/schema/types_parts/constraint.py +165 -0
- app/shared/core/project/schema/types_parts/schema_id.py +66 -0
- app/shared/core/project/schema/types_parts/source.py +255 -0
- app/shared/core/project/schema/types_parts/source_options.py +347 -0
- app/shared/core/project/schema/types_parts/table.py +230 -0
- app/shared/core/project/schema/writer.py +139 -0
- app/shared/core/project/schema_ref_check.py +95 -0
- app/shared/core/project/template/__init__.py +27 -0
- app/shared/core/project/template/expander.py +263 -0
- app/shared/core/project/template/reader.py +120 -0
- app/shared/core/project/template/types.py +114 -0
- app/shared/core/project/transform/reader.py +76 -0
- app/shared/core/project/transform/types.py +116 -0
- app/shared/core/project/transform/writer.py +84 -0
- app/shared/core/pydantic_messages.py +59 -0
- app/shared/core/reporter/__init__.py +46 -0
- app/shared/core/reporter/reporter.py +220 -0
- app/shared/core/reporter/reporters/__init__.py +65 -0
- app/shared/core/reporter/reporters/base.py +188 -0
- app/shared/core/reporter/reporters/dingtalk_app_reporter.py +274 -0
- app/shared/core/reporter/reporters/email_reporter.py +271 -0
- app/shared/core/reporter/reporters/feishu_app_reporter.py +467 -0
- app/shared/core/reporter/reporters/local_file_reporter.py +208 -0
- app/shared/core/reporter/reporters/wecom_app_reporter.py +268 -0
- app/shared/core/utils/__init__.py +18 -0
- app/shared/core/utils/path_utils.py +60 -0
- app/shared/core/utils/regex_extract.py +113 -0
- app/shared/domain/__init__.py +114 -0
- app/shared/domain/constraints/__init__.py +76 -0
- app/shared/domain/constraints/allowed_values.py +211 -0
- app/shared/domain/constraints/base.py +141 -0
- app/shared/domain/constraints/charset.py +337 -0
- app/shared/domain/constraints/composite.py +174 -0
- app/shared/domain/constraints/condition_registry.py +130 -0
- app/shared/domain/constraints/conditional.py +629 -0
- app/shared/domain/constraints/date_logic.py +731 -0
- app/shared/domain/constraints/foreign_key.py +261 -0
- app/shared/domain/constraints/key_normalization.py +56 -0
- app/shared/domain/constraints/not_null.py +185 -0
- app/shared/domain/constraints/range.py +360 -0
- app/shared/domain/constraints/regex.py +218 -0
- app/shared/domain/constraints/scripted.py +276 -0
- app/shared/domain/constraints/unique.py +233 -0
- app/shared/domain/data_engine.py +384 -0
- app/shared/domain/data_types.py +113 -0
- app/shared/domain/data_types_parts/__init__.py +67 -0
- app/shared/domain/data_types_parts/base.py +204 -0
- app/shared/domain/data_types_parts/composite.py +250 -0
- app/shared/domain/data_types_parts/expression.py +202 -0
- app/shared/domain/data_types_parts/extracted.py +106 -0
- app/shared/domain/data_types_parts/json_types.py +234 -0
- app/shared/domain/data_types_parts/scalars.py +719 -0
- app/shared/domain/data_types_parts/sequence.py +129 -0
- app/shared/domain/dataset_schema.py +48 -0
- app/shared/domain/eval_sandbox.py +63 -0
- app/shared/domain/expression_system.py +366 -0
- app/shared/domain/regex_flags.py +53 -0
- app/shared/domain/schema/builder.py +223 -0
- app/shared/domain/schema/models.py +339 -0
- app/shared/domain/transforms/__init__.py +28 -0
- app/shared/domain/transforms/aggregate.py +141 -0
- app/shared/domain/transforms/base.py +171 -0
- app/shared/domain/transforms/cast_type.py +120 -0
- app/shared/domain/transforms/concat.py +103 -0
- app/shared/domain/transforms/conditional_assign.py +114 -0
- app/shared/domain/transforms/date_format.py +81 -0
- app/shared/domain/transforms/digits.py +77 -0
- app/shared/domain/transforms/drop_duplicates.py +94 -0
- app/shared/domain/transforms/fill_na.py +94 -0
- app/shared/domain/transforms/filter_rows.py +97 -0
- app/shared/domain/transforms/lookup.py +78 -0
- app/shared/domain/transforms/lower_case.py +70 -0
- app/shared/domain/transforms/map_value.py +90 -0
- app/shared/domain/transforms/math_expr.py +112 -0
- app/shared/domain/transforms/modulo.py +82 -0
- app/shared/domain/transforms/regex_extract.py +103 -0
- app/shared/domain/transforms/registry.py +95 -0
- app/shared/domain/transforms/replace.py +88 -0
- app/shared/domain/transforms/sort_rows.py +94 -0
- app/shared/domain/transforms/string_split.py +84 -0
- app/shared/domain/transforms/strip.py +73 -0
- app/shared/domain/transforms/substring.py +92 -0
- app/shared/domain/transforms/upper_case.py +70 -0
- app/shared/domain/transforms/weighted_sum.py +104 -0
- app/shared/domain/validation_constraints.py +69 -0
- app/shared/services/__init__.py +62 -0
- app/shared/services/ai/__init__.py +48 -0
- app/shared/services/ai/agent/__init__.py +40 -0
- app/shared/services/ai/agent/chat_tools/__init__.py +47 -0
- app/shared/services/ai/agent/chat_tools/apply_actions.py +592 -0
- app/shared/services/ai/agent/chat_tools/ask_user.py +237 -0
- app/shared/services/ai/agent/chat_tools/read_canvas.py +140 -0
- app/shared/services/ai/agent/chat_tools/read_project.py +160 -0
- app/shared/services/ai/agent/chat_tools/read_table.py +301 -0
- app/shared/services/ai/agent/chat_tools/schemas.py +105 -0
- app/shared/services/ai/agent/chat_tools/validate_table.py +131 -0
- app/shared/services/ai/agent/executor.py +554 -0
- app/shared/services/ai/agent/memory.py +256 -0
- app/shared/services/ai/agent/planner.py +282 -0
- app/shared/services/ai/agent/tool_registry.py +296 -0
- app/shared/services/ai/agent/tools/__init__.py +32 -0
- app/shared/services/ai/agent/tools/config_generate.py +133 -0
- app/shared/services/ai/agent/tools/config_refine.py +109 -0
- app/shared/services/ai/agent/tools/config_validate.py +403 -0
- app/shared/services/ai/agent/tools/merge_results.py +136 -0
- app/shared/services/ai/agent/tools/plan_chunks.py +79 -0
- app/shared/services/ai/agent/tools/script_parse.py +359 -0
- app/shared/services/ai/agent/types.py +138 -0
- app/shared/services/ai/chat_agent_runner.py +596 -0
- app/shared/services/ai/chat_orchestrator.py +725 -0
- app/shared/services/ai/failure_messages.py +65 -0
- app/shared/services/ai/job_storage.py +274 -0
- app/shared/services/ai/migrate_service.py +550 -0
- app/shared/services/ai/streaming/__init__.py +65 -0
- app/shared/services/ai/streaming/event_journal.py +197 -0
- app/shared/services/ai/streaming/orchestrator.py +262 -0
- app/shared/services/ai/streaming/pending_interaction_store.py +227 -0
- app/shared/services/ai/streaming/sse_response.py +148 -0
- app/shared/services/ai/streaming/types.py +73 -0
- app/shared/services/ai/types.py +213 -0
- app/shared/services/ai/utils.py +322 -0
- app/shared/services/diff/config_diff.py +320 -0
- app/shared/services/hardware.py +237 -0
- app/shared/services/llm/__init__.py +62 -0
- app/shared/services/llm/actions/__init__.py +42 -0
- app/shared/services/llm/actions/_canvas_validator.py +147 -0
- app/shared/services/llm/actions/_constraint_validator.py +401 -0
- app/shared/services/llm/actions/_regex_validator.py +85 -0
- app/shared/services/llm/actions/_schema_validator.py +82 -0
- app/shared/services/llm/actions/_settings_validator.py +76 -0
- app/shared/services/llm/actions/_transform_validator.py +78 -0
- app/shared/services/llm/actions/action_handlers.py +400 -0
- app/shared/services/llm/actions/action_parser.py +63 -0
- app/shared/services/llm/actions/action_processor.py +468 -0
- app/shared/services/llm/actions/action_validator.py +311 -0
- app/shared/services/llm/actions/diff_compute.py +195 -0
- app/shared/services/llm/actions/regex_handlers.py +284 -0
- app/shared/services/llm/actions/registry.py +336 -0
- app/shared/services/llm/actions/schema_handlers.py +335 -0
- app/shared/services/llm/actions/settings_handlers.py +180 -0
- app/shared/services/llm/actions/specs.py +259 -0
- app/shared/services/llm/actions/transform_handlers.py +279 -0
- app/shared/services/llm/actions/validation_types.py +147 -0
- app/shared/services/llm/cache/__init__.py +18 -0
- app/shared/services/llm/cache/response_cache.py +80 -0
- app/shared/services/llm/chat/__init__.py +35 -0
- app/shared/services/llm/chat/chat_system_prompt.py +561 -0
- app/shared/services/llm/chat/response_parser.py +296 -0
- app/shared/services/llm/config/__init__.py +45 -0
- app/shared/services/llm/config/crypto.py +135 -0
- app/shared/services/llm/config/loader.py +258 -0
- app/shared/services/llm/config/models.py +202 -0
- app/shared/services/llm/config/presets.py +128 -0
- app/shared/services/llm/config_generator.py +163 -0
- app/shared/services/llm/constraints/__init__.py +41 -0
- app/shared/services/llm/constraints/constraint_builder.py +177 -0
- app/shared/services/llm/constraints/constraint_deletion.py +84 -0
- app/shared/services/llm/constraints/constraint_id.py +174 -0
- app/shared/services/llm/constraints/frontend_instructions.py +333 -0
- app/shared/services/llm/constraints/inline_batch.py +279 -0
- app/shared/services/llm/discovery/__init__.py +35 -0
- app/shared/services/llm/discovery/scanner.py +181 -0
- app/shared/services/llm/generation/__init__.py +42 -0
- app/shared/services/llm/generation/agent_wiring.py +156 -0
- app/shared/services/llm/generation/config_builder.py +386 -0
- app/shared/services/llm/generation/errors.py +36 -0
- app/shared/services/llm/generation/existing_config.py +99 -0
- app/shared/services/llm/generation/profiler.py +279 -0
- app/shared/services/llm/generation/prompt_builder.py +199 -0
- app/shared/services/llm/generation/response_parser.py +144 -0
- app/shared/services/llm/generation/service.py +622 -0
- app/shared/services/llm/models.py +104 -0
- app/shared/services/llm/providers/__init__.py +48 -0
- app/shared/services/llm/providers/base.py +310 -0
- app/shared/services/llm/providers/cached_provider.py +90 -0
- app/shared/services/llm/providers/ollama.py +498 -0
- app/shared/services/llm/providers/openai.py +334 -0
- app/shared/services/llm/providers/registry.py +108 -0
- app/shared/services/llm/schema_resolver.py +141 -0
- app/shared/services/llm/suggestion_utils.py +219 -0
- app/shared/services/llm/validate_executor.py +163 -0
- app/shared/services/llm/yaml_io.py +406 -0
- app/shared/services/preview/__init__.py +18 -0
- app/shared/services/preview/loader.py +145 -0
- app/shared/services/preview/path_validation.py +138 -0
- app/shared/services/project_loader.py +57 -0
- app/shared/services/schema_inference.py +260 -0
- app/shared/services/schema_runtime_builder.py +120 -0
- app/shared/services/validation/__init__.py +52 -0
- app/shared/services/validation/chunked_loader.py +509 -0
- app/shared/services/validation/dag/__init__.py +35 -0
- app/shared/services/validation/dag/builder.py +141 -0
- app/shared/services/validation/dag/executor.py +225 -0
- app/shared/services/validation/dag/sorter.py +77 -0
- app/shared/services/validation/data_loader.py +231 -0
- app/shared/services/validation/engine.py +446 -0
- app/shared/services/validation/executor.py +1030 -0
- app/shared/services/validation/extractors.py +266 -0
- app/shared/services/validation/history.py +209 -0
- app/shared/services/validation/json_payload.py +136 -0
- app/shared/services/validation/loader.py +152 -0
- app/shared/services/validation/memory_monitor.py +179 -0
- app/shared/services/validation/postprocess.py +208 -0
- app/shared/services/validation/progress.py +64 -0
- app/shared/services/validation/report_export.py +222 -0
- app/shared/services/validation/resolver.py +180 -0
- app/shared/services/validation/service.py +418 -0
- app/shared/services/validation/types.py +238 -0
- app/shared/services/validation/validators/__init__.py +36 -0
- app/shared/services/validation/validators/adapter.py +182 -0
- app/shared/services/validation/validators/base.py +332 -0
- app/shared/services/validation/validators/composite.py +233 -0
- app/shared/services/validation/validators/date_logic.py +276 -0
- app/start_server.py +133 -0
- precis_cli-0.1.3.dist-info/METADATA +180 -0
- precis_cli-0.1.3.dist-info/RECORD +442 -0
- precis_cli-0.1.3.dist-info/WHEEL +5 -0
- precis_cli-0.1.3.dist-info/entry_points.txt +4 -0
- precis_cli-0.1.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,117 @@
|
|
|
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
|
+
# backend/app/api/models/project.py
|
|
17
|
+
"""
|
|
18
|
+
@fileoverview 项目相关请求/响应模型
|
|
19
|
+
|
|
20
|
+
功能概述:
|
|
21
|
+
- 定义项目配置相关的 Pydantic 数据模型
|
|
22
|
+
- 包含项目详情、路径配置、项目配置文件结构、通用响应等模型
|
|
23
|
+
|
|
24
|
+
输入示例:
|
|
25
|
+
ProjectConfigModel(
|
|
26
|
+
project_id="my-project",
|
|
27
|
+
project_name="My Data Project",
|
|
28
|
+
paths=PathsModel(schemas="schemas/", constraints="constraints/")
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
输出示例:
|
|
32
|
+
ProjectDetail(
|
|
33
|
+
project_id="my-project",
|
|
34
|
+
project_name="My Data Project",
|
|
35
|
+
schemas_count=5,
|
|
36
|
+
constraints_count=10
|
|
37
|
+
)
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from pydantic import BaseModel, Field
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ProjectDetail(BaseModel):
|
|
44
|
+
"""
|
|
45
|
+
用于描述当前活动项目的详细信息模型
|
|
46
|
+
|
|
47
|
+
该模型在项目概览或项目列表接口中使用,
|
|
48
|
+
展示项目的核心统计信息和基本标识。
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
project_id: 项目唯一标识符
|
|
52
|
+
project_name: 项目显示名称
|
|
53
|
+
schemas_count: 项目中定义的 Schema 数量
|
|
54
|
+
constraints_count: 项目中定义的约束规则数量
|
|
55
|
+
last_validated: 最后一次验证的时间戳(ISO 格式),预留字段
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
project_id: str # 项目唯一标识符,用于区分不同项目
|
|
59
|
+
project_name: str # 项目显示名称,面向用户的可读名称
|
|
60
|
+
schemas_count: int # 项目中已定义的 Schema(表结构)数量
|
|
61
|
+
constraints_count: int # 项目中已定义的约束规则数量
|
|
62
|
+
last_validated: str | None = None # 最后一次执行校验的时间戳,ISO 8601 格式,可选
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class PathsModel(BaseModel):
|
|
66
|
+
"""
|
|
67
|
+
定义项目中各类配置文件的路径配置模型
|
|
68
|
+
|
|
69
|
+
用于配置 Schema、Constraints、Patterns 等配置文件
|
|
70
|
+
相对于项目根目录的存放路径。
|
|
71
|
+
|
|
72
|
+
Attributes:
|
|
73
|
+
schemas: Schema 配置文件存放目录路径
|
|
74
|
+
constraints: Constraints 约束规则文件存放目录路径
|
|
75
|
+
patterns: Patterns 模式匹配规则文件存放目录路径(可选)
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
schemas: str = Field(..., title="表结构 (Schemas) 路径") # Schema 配置文件相对于项目根目录的存放路径,必填
|
|
79
|
+
constraints: str = Field(
|
|
80
|
+
..., title="约束规则 (Constraints) 路径"
|
|
81
|
+
) # Constraints 约束规则文件相对于项目根目录的存放路径,必填
|
|
82
|
+
patterns: str | None = Field(
|
|
83
|
+
None, title="模式 (Patterns) 路径"
|
|
84
|
+
) # Patterns 模式匹配规则文件相对于项目根目录的存放路径,可选
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ProjectConfigModel(BaseModel):
|
|
88
|
+
"""
|
|
89
|
+
定义 project.yaml 完整结构的数据模型
|
|
90
|
+
|
|
91
|
+
该模型对应项目根目录下的 project.yaml 配置文件,
|
|
92
|
+
包含项目的全局配置信息。
|
|
93
|
+
|
|
94
|
+
Attributes:
|
|
95
|
+
project_id: 项目唯一标识符
|
|
96
|
+
project_name: 项目显示名称
|
|
97
|
+
paths: 各类配置文件的路径设置(嵌套 PathsModel)
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
project_id: str = Field(..., title="项目ID") # 项目唯一标识符,全局唯一,用于内部引用和目录命名
|
|
101
|
+
project_name: str = Field(..., title="项目名称") # 项目显示名称,面向用户的可读名称
|
|
102
|
+
paths: PathsModel # 嵌套路径配置模型,定义各类配置文件的存放位置
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class StandardResponse(BaseModel):
|
|
106
|
+
"""
|
|
107
|
+
定义通用消息响应模型
|
|
108
|
+
|
|
109
|
+
用于简单的文本响应场景,如确认消息、状态更新等。
|
|
110
|
+
|
|
111
|
+
Attributes:
|
|
112
|
+
success: 操作是否成功,默认为 True
|
|
113
|
+
message: 响应消息内容
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
success: bool = True # 操作是否成功,默认返回 True
|
|
117
|
+
message: str # 响应消息内容,通常用于操作成功确认或状态说明
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
"""项目管理 API 模型:项目扫描、打开、创建、关闭与当前项目查询的请求/响应定义。"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from pydantic import BaseModel
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProjectInfo(BaseModel):
|
|
24
|
+
"""扫描返回的单个项目信息。"""
|
|
25
|
+
|
|
26
|
+
name: str
|
|
27
|
+
path: str
|
|
28
|
+
schema_count: int
|
|
29
|
+
constraint_count: int
|
|
30
|
+
last_modified: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ScanResponse(BaseModel):
|
|
34
|
+
"""项目扫描端点的响应。"""
|
|
35
|
+
|
|
36
|
+
work_dir: str
|
|
37
|
+
projects: list[ProjectInfo]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class OpenProjectRequest(BaseModel):
|
|
41
|
+
"""打开项目的请求体。"""
|
|
42
|
+
|
|
43
|
+
path: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class OpenProjectResponse(BaseModel):
|
|
47
|
+
"""打开项目的响应。"""
|
|
48
|
+
|
|
49
|
+
success: bool
|
|
50
|
+
name: str
|
|
51
|
+
path: str
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CreateProjectRequest(BaseModel):
|
|
55
|
+
"""创建新项目脚手架的请求体。"""
|
|
56
|
+
|
|
57
|
+
path: str
|
|
58
|
+
name: str
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CreateProjectResponse(BaseModel):
|
|
62
|
+
"""创建项目的响应。"""
|
|
63
|
+
|
|
64
|
+
success: bool
|
|
65
|
+
name: str
|
|
66
|
+
path: str
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class CurrentProjectResponse(BaseModel):
|
|
70
|
+
"""当前项目查询的响应。"""
|
|
71
|
+
|
|
72
|
+
has_current: bool
|
|
73
|
+
path: str | None = None
|
|
74
|
+
name: str | None = None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CloseProjectResponse(BaseModel):
|
|
78
|
+
"""关闭项目的响应。"""
|
|
79
|
+
|
|
80
|
+
success: bool
|
app/api/models/schema.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
# backend/app/api/models/schema.py
|
|
17
|
+
"""
|
|
18
|
+
@fileoverview Schema 相关请求/响应模型
|
|
19
|
+
|
|
20
|
+
功能概述:
|
|
21
|
+
- 定义 Schema 文件操作相关的 Pydantic 数据模型
|
|
22
|
+
- 包含 Schema 保存请求/响应、表头行变更请求/响应等模型
|
|
23
|
+
|
|
24
|
+
输入示例:
|
|
25
|
+
SchemaSaveRequest(
|
|
26
|
+
action="save_schema",
|
|
27
|
+
schema_name="users",
|
|
28
|
+
yaml_content="version: 2\nid: users\n...",
|
|
29
|
+
saved_at="2024-01-01T00:00:00Z"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
输出示例:
|
|
33
|
+
SchemaSaveResponse(
|
|
34
|
+
success=True,
|
|
35
|
+
message="Schema saved successfully",
|
|
36
|
+
schema_name="users",
|
|
37
|
+
saved_at="2024-01-01T00:00:00Z"
|
|
38
|
+
)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from pydantic import BaseModel, Field
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SchemaSaveRequest(BaseModel):
|
|
45
|
+
"""
|
|
46
|
+
Schema 保存请求模型
|
|
47
|
+
|
|
48
|
+
前端保存 Schema 配置文件时发送的请求体。
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
action: 操作类型,固定为 'save_schema'
|
|
52
|
+
schema_name: Schema 名称(不含 .yaml 后缀)
|
|
53
|
+
yaml_content: YAML 格式的 Schema 内容
|
|
54
|
+
saved_at: 保存时间(ISO 格式时间戳)
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
action: str = Field(..., description="操作类型,固定为'save_schema'")
|
|
58
|
+
schema_name: str = Field(..., description="Schema名称")
|
|
59
|
+
yaml_content: str = Field(..., description="YAML格式的Schema内容")
|
|
60
|
+
saved_at: str = Field(..., description="保存时间")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class SchemaSaveResponse(BaseModel):
|
|
64
|
+
"""
|
|
65
|
+
Schema 保存响应模型
|
|
66
|
+
|
|
67
|
+
Schema 保存操作的结果响应。
|
|
68
|
+
|
|
69
|
+
Attributes:
|
|
70
|
+
success: 保存是否成功
|
|
71
|
+
message: 保存结果消息
|
|
72
|
+
schema_name: Schema 名称
|
|
73
|
+
saved_at: 保存时间
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
success: bool = Field(..., description="保存是否成功")
|
|
77
|
+
message: str = Field(..., description="保存结果消息")
|
|
78
|
+
schema_name: str = Field(..., description="Schema名称")
|
|
79
|
+
saved_at: str = Field(..., description="保存时间")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class HeaderRowChangedRequest(BaseModel):
|
|
83
|
+
"""
|
|
84
|
+
表头行变更请求模型
|
|
85
|
+
|
|
86
|
+
用户在 UI 中修改数据表的表头行位置时发送的请求。
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
action: 操作类型,固定为 'header_row_changed'
|
|
90
|
+
node_id: 源预览节点 ID
|
|
91
|
+
header_row: 新的表头行索引(0 表示第一行)
|
|
92
|
+
old_header_row: 旧的表头行索引
|
|
93
|
+
row_data: 表头行数据(可选)
|
|
94
|
+
schema_name: 关联的 Schema 名称(可选)
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
action: str = Field(..., description="操作类型,固定为'header_row_changed'")
|
|
98
|
+
node_id: str = Field(..., description="源预览节点ID")
|
|
99
|
+
header_row: int | None = Field(None, description="新的表头行索引")
|
|
100
|
+
old_header_row: int | None = Field(None, description="旧的表头行索引")
|
|
101
|
+
row_data: dict | None = Field(None, description="表头行数据")
|
|
102
|
+
schema_name: str | None = Field(None, description="关联的Schema名称")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class HeaderRowChangedResponse(BaseModel):
|
|
106
|
+
"""
|
|
107
|
+
表头行变更响应模型
|
|
108
|
+
|
|
109
|
+
表头行变更操作的结果响应。
|
|
110
|
+
|
|
111
|
+
Attributes:
|
|
112
|
+
success: 更新是否成功
|
|
113
|
+
message: 更新结果消息
|
|
114
|
+
schema_name: 关联的 Schema 名称(可选)
|
|
115
|
+
updated_at: 更新时间(可选)
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
success: bool = Field(..., description="更新是否成功")
|
|
119
|
+
message: str = Field(..., description="更新结果消息")
|
|
120
|
+
schema_name: str | None = Field(default=None, description="关联的Schema名称")
|
|
121
|
+
updated_at: str | None = Field(default=None, description="更新时间")
|
|
@@ -0,0 +1,46 @@
|
|
|
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 V2 配置响应模型
|
|
18
|
+
|
|
19
|
+
功能概述:
|
|
20
|
+
- 定义 V2 项目配置 API 响应相关的 Pydantic 数据模型
|
|
21
|
+
- 将内部配置模型与 API 响应契约解耦,保持 API 兼容性
|
|
22
|
+
|
|
23
|
+
输入示例:
|
|
24
|
+
内部 ProjectManifestV2 模型实例
|
|
25
|
+
|
|
26
|
+
输出示例:
|
|
27
|
+
ManifestResponse(
|
|
28
|
+
version=2,
|
|
29
|
+
project=ProjectInfo(id="proj", name="Project"),
|
|
30
|
+
schemas=[...],
|
|
31
|
+
constraints=[...]
|
|
32
|
+
)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from app.shared.core.project.manifest.types import ProjectManifestV2
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ManifestResponse(ProjectManifestV2):
|
|
39
|
+
"""
|
|
40
|
+
/manifest GET 的 API 响应模型。
|
|
41
|
+
|
|
42
|
+
当前继承自 ProjectManifestV2 以保持兼容性,
|
|
43
|
+
后续可按需添加/移除字段,或在此做数据转换。
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
pass
|
|
@@ -0,0 +1,303 @@
|
|
|
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
|
+
# backend/app/api/models/validation.py
|
|
17
|
+
"""
|
|
18
|
+
@fileoverview 校验请求/响应模型
|
|
19
|
+
|
|
20
|
+
功能概述:
|
|
21
|
+
- 定义数据校验相关的 Pydantic 数据模型
|
|
22
|
+
- 包含正则校验请求/响应、统一校验请求/响应、校验类型枚举等
|
|
23
|
+
|
|
24
|
+
输入示例:
|
|
25
|
+
RegexValidationRequest(
|
|
26
|
+
regex_pattern="^1[3-9]\\d{9}$",
|
|
27
|
+
match_mode="full",
|
|
28
|
+
target_column_name="phone",
|
|
29
|
+
source_file_path="data/users.xlsx"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
输出示例:
|
|
33
|
+
ValidationResponse(
|
|
34
|
+
success=True,
|
|
35
|
+
validation_type="regex",
|
|
36
|
+
data=ValidationResult(
|
|
37
|
+
is_valid=False,
|
|
38
|
+
error_count=3,
|
|
39
|
+
total_rows=100,
|
|
40
|
+
error_rows=[...]
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from typing import Any, Literal
|
|
46
|
+
|
|
47
|
+
from pydantic import BaseModel, Field
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class RegexValidationRequest(BaseModel):
|
|
51
|
+
"""
|
|
52
|
+
正则表达式校验请求模型
|
|
53
|
+
|
|
54
|
+
用于对数据列进行正则表达式模式匹配校验。
|
|
55
|
+
|
|
56
|
+
Attributes:
|
|
57
|
+
regex_pattern: 正则表达式模式
|
|
58
|
+
regex_flags: 正则表达式标志(如 g, i, m)
|
|
59
|
+
match_mode: 匹配模式(full/partial/extract)
|
|
60
|
+
case_sensitive: 是否大小写敏感
|
|
61
|
+
target_column_name: 目标列名
|
|
62
|
+
source_file_path: 数据源文件路径
|
|
63
|
+
sheet_name: Excel 工作表名称(可选)
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
regex_pattern: str = Field(..., description="正则表达式模式") # 用于匹配的正则表达式字符串,必填
|
|
67
|
+
regex_flags: str | None = Field(None, description="正则表达式标志") # 正则标志(如 g, i, m),可选
|
|
68
|
+
match_mode: str = Field(
|
|
69
|
+
default="full", description="匹配模式: full/partial/extract"
|
|
70
|
+
) # 匹配模式:full(全匹配)、partial(部分匹配)、extract(提取)
|
|
71
|
+
case_sensitive: bool = Field(
|
|
72
|
+
default=True, description="是否大小写敏感"
|
|
73
|
+
) # True 表示区分大小写,False 表示忽略大小写
|
|
74
|
+
target_column_name: str = Field(..., description="目标列名") # 需要进行正则校验的数据列名称,必填
|
|
75
|
+
source_file_path: str = Field(
|
|
76
|
+
..., description="数据源文件路径"
|
|
77
|
+
) # 数据源文件(Excel/CSV/JSON)的绝对或相对路径,必填
|
|
78
|
+
sheet_name: str | None = Field(None, description="Excel工作表名称") # 当数据源为 Excel 时指定工作表名称,可选
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class RegexValidationErrorRow(BaseModel):
|
|
82
|
+
"""
|
|
83
|
+
正则校验错误行模型
|
|
84
|
+
|
|
85
|
+
记录正则校验失败的具体行信息。
|
|
86
|
+
|
|
87
|
+
Attributes:
|
|
88
|
+
row_index: 行索引(从 0 开始)
|
|
89
|
+
cell_value: 单元格原始值
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
row_index: int = Field(..., description="行索引") # 数据行在源文件中的索引位置,从 0 开始计数
|
|
93
|
+
cell_value: str = Field(..., description="单元格值") # 该校验失败的单元格原始值
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class RegexValidationResult(BaseModel):
|
|
97
|
+
"""
|
|
98
|
+
正则表达式校验结果模型
|
|
99
|
+
|
|
100
|
+
包含正则校验的详细结果信息。
|
|
101
|
+
|
|
102
|
+
Attributes:
|
|
103
|
+
is_valid: 校验是否通过
|
|
104
|
+
error_count: 错误行数量
|
|
105
|
+
total_rows: 总行数
|
|
106
|
+
match_count: 匹配行数量
|
|
107
|
+
error_rows: 错误行列表
|
|
108
|
+
validation_time: 校验耗时时间戳
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
is_valid: bool = Field(..., description="校验是否通过") # True 表示全部通过,False 表示存在错误行
|
|
112
|
+
error_count: int = Field(..., description="错误数量") # 校验失败的行数
|
|
113
|
+
total_rows: int = Field(..., description="总行数") # 参与校验的数据总行数(不含表头)
|
|
114
|
+
match_count: int = Field(..., description="匹配数量") # 正则匹配成功的行数
|
|
115
|
+
error_rows: list[RegexValidationErrorRow] = Field(default=[], description="错误行列表") # 校验失败的详细行信息列表
|
|
116
|
+
validation_time: str = Field(..., description="校验时间") # 校验执行完成的时间戳,ISO 8601 格式
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class RegexValidationResponse(BaseModel):
|
|
120
|
+
"""
|
|
121
|
+
正则表达式校验响应模型
|
|
122
|
+
|
|
123
|
+
正则校验接口的标准响应格式。
|
|
124
|
+
|
|
125
|
+
Attributes:
|
|
126
|
+
success: 请求是否成功
|
|
127
|
+
data: 校验结果详情
|
|
128
|
+
error: 错误信息(如果有)
|
|
129
|
+
schema_name: 关联的 Schema 名称(可选)
|
|
130
|
+
updated_at: 更新时间(可选)
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
success: bool = Field(..., description="请求是否成功") # True 表示请求处理成功,False 表示接口层面出错
|
|
134
|
+
data: RegexValidationResult | None = Field(None, description="校验结果") # 校验成功时返回的详细结果,失败时为 None
|
|
135
|
+
error: str | None = Field(None, description="错误信息") # 请求处理失败时的错误描述,成功时为 None
|
|
136
|
+
schema_name: str | None = Field(
|
|
137
|
+
default=None, description="Schema名称"
|
|
138
|
+
) # 关联的 Schema 名称,用于前端展示上下文,可选
|
|
139
|
+
updated_at: str | None = Field(default=None, description="更新时间") # 响应生成的时间戳,ISO 8601 格式,可选
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# 统一使用 services 层的 ValidationType 作为唯一真相源
|
|
143
|
+
# API 层不再维护独立的校验类型定义,避免与服务层不一致
|
|
144
|
+
from app.shared.services.validation.types import ValidationType # noqa: F401
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ValidationRequest(BaseModel):
|
|
148
|
+
"""
|
|
149
|
+
统一校验请求模型
|
|
150
|
+
|
|
151
|
+
用于通用数据校验接口的请求体。
|
|
152
|
+
支持多种校验类型,通过 validation_type 字段指定。
|
|
153
|
+
|
|
154
|
+
Attributes:
|
|
155
|
+
validation_type: 校验类型(regex/unique/not_null/allowed_values/conditional/scripted)
|
|
156
|
+
target_column_name: 目标列名
|
|
157
|
+
source_file_path: 数据源文件路径
|
|
158
|
+
sheet_name: Excel 工作表名称(可选)
|
|
159
|
+
header_row: 表头行索引,0 表示第一行(可选)
|
|
160
|
+
validation_config: 校验特定配置(字典)
|
|
161
|
+
allow_unsafe_eval: 是否允许执行脚本化校验(eval 模式)
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
validation_type: str = Field(
|
|
165
|
+
..., description="校验类型: regex/unique/not_null/allowed_values/conditional/scripted"
|
|
166
|
+
) # 指定要执行的校验类型,必填
|
|
167
|
+
target_column_name: str = Field(..., description="目标列名") # 需要校验的数据列名称,必填
|
|
168
|
+
source_file_path: str = Field(
|
|
169
|
+
..., description="数据源文件路径"
|
|
170
|
+
) # 数据源文件(Excel/CSV/JSON)的绝对或相对路径,必填
|
|
171
|
+
sheet_name: str | None = Field(None, description="Excel工作表名称") # 当数据源为 Excel 时指定工作表名称,可选
|
|
172
|
+
header_row: int | None = Field(
|
|
173
|
+
None, description="表头行索引,0表示第一行"
|
|
174
|
+
) # 指定表头所在行索引,0 表示第一行,可选
|
|
175
|
+
validation_config: dict | None = Field(
|
|
176
|
+
default={}, description="校验特定配置"
|
|
177
|
+
) # 各类校验的特定配置参数(如 allowed_values 的值列表),默认为空字典
|
|
178
|
+
allow_unsafe_eval: bool = Field(
|
|
179
|
+
False, description="是否允许执行脚本化校验(eval模式)"
|
|
180
|
+
) # True 允许执行脚本化校验(存在安全风险),默认关闭
|
|
181
|
+
column_data_type: str | None = Field(
|
|
182
|
+
None, description="目标列在 Schema 中声明的数据类型(如 string/integer/decimal)"
|
|
183
|
+
) # 用于单节点校验时按 Schema 类型转换目标列,保持与全量校验行为一致
|
|
184
|
+
json_path: str | None = Field(
|
|
185
|
+
None, description="JSON 数据源的 JSONPath 表达式(可选)"
|
|
186
|
+
) # 用于从嵌套 JSON 中提取目标记录数组
|
|
187
|
+
json_format: Literal["array", "lines", "object"] | None = Field(
|
|
188
|
+
None, description="JSON 数据源格式:array | lines | object(可选,auto 已废弃)"
|
|
189
|
+
) # 用于指定 JSON 文件的解析方式
|
|
190
|
+
record_path: str | None = Field(
|
|
191
|
+
None, description="JSON 数据源的 record_path,用于展开嵌套数组(可选)"
|
|
192
|
+
) # 用于将嵌套 JSON 数组扁平化为 DataFrame 行
|
|
193
|
+
|
|
194
|
+
def to_source_config(self) -> dict[str, Any] | None:
|
|
195
|
+
"""构建 JSON 数据源配置字典,仅在有 JSON 相关字段时返回。"""
|
|
196
|
+
cfg: dict[str, Any] = {}
|
|
197
|
+
if self.json_path is not None:
|
|
198
|
+
cfg["json_path"] = self.json_path
|
|
199
|
+
if self.json_format is not None:
|
|
200
|
+
cfg["json_format"] = self.json_format
|
|
201
|
+
if self.record_path is not None:
|
|
202
|
+
cfg["record_path"] = self.record_path
|
|
203
|
+
return cfg if cfg else None
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class InlineValidationRequest(BaseModel):
|
|
207
|
+
"""
|
|
208
|
+
行内数据校验请求模型
|
|
209
|
+
|
|
210
|
+
用于纯数据节点(TransformOutput / ManualData)的行内校验接口。
|
|
211
|
+
直接接收行数据,无需文件路径。
|
|
212
|
+
|
|
213
|
+
Attributes:
|
|
214
|
+
validation_type: 校验类型(not_null/unique/allowed_values/range/charset/scripted/foreign_key 等)
|
|
215
|
+
target_column_name: 目标列名
|
|
216
|
+
rows: 行数据二维数组,默认第一行为表头(与 TransformOutput/ManualData 的 rows 结构一致)
|
|
217
|
+
column_names: 列名列表,当提供时 rows 全部视为数据行(覆盖默认的第一行表头行为)
|
|
218
|
+
validation_config: 校验特定配置(字典)
|
|
219
|
+
allow_unsafe_eval: 是否允许执行脚本化校验(eval 模式)
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
validation_type: str = Field(
|
|
223
|
+
..., description="校验类型"
|
|
224
|
+
) # 指定要执行的校验类型(如 not_null/unique/range 等),必填
|
|
225
|
+
target_column_name: str = Field(..., description="目标列名") # 需要校验的数据列名称,必填
|
|
226
|
+
rows: list[list[Any]] = Field(
|
|
227
|
+
..., description="行数据,默认第一行为表头"
|
|
228
|
+
) # 二维数组形式的行数据,默认第一行为表头,后续行为数据
|
|
229
|
+
column_names: list[str] = Field(
|
|
230
|
+
default=[], description="列名列表(提供时 rows 全部视为数据行)"
|
|
231
|
+
) # 显式指定列名时,rows 全部视为数据行(不再将第一行作为表头)
|
|
232
|
+
validation_config: dict | None = Field(
|
|
233
|
+
default={}, description="校验特定配置"
|
|
234
|
+
) # 各类校验的特定配置参数,默认为空字典
|
|
235
|
+
allow_unsafe_eval: bool = Field(
|
|
236
|
+
False, description="是否允许执行脚本化校验(eval模式)"
|
|
237
|
+
) # True 允许执行脚本化校验(存在安全风险),默认关闭
|
|
238
|
+
column_data_type: str | None = Field(
|
|
239
|
+
None, description="目标列在 Schema 中声明的数据类型(如 string/integer/decimal)"
|
|
240
|
+
) # 用于单节点校验时按 Schema 类型转换目标列,保持与全量校验行为一致
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class ValidationErrorRow(BaseModel):
|
|
244
|
+
"""
|
|
245
|
+
校验错误行模型
|
|
246
|
+
|
|
247
|
+
记录数据校验失败的具体行信息。
|
|
248
|
+
|
|
249
|
+
Attributes:
|
|
250
|
+
row_index: 行索引(从 0 开始)
|
|
251
|
+
cell_value: 单元格原始值
|
|
252
|
+
error_message: 错误描述信息(可选)
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
row_index: int = Field(..., description="行索引") # 数据行在源文件或行内数据中的索引位置,从 0 开始计数
|
|
256
|
+
cell_value: str = Field(..., description="单元格值") # 该校验失败的单元格原始值
|
|
257
|
+
error_message: str | None = Field(
|
|
258
|
+
None, description="错误信息"
|
|
259
|
+
) # 校验失败的具体错误描述,如"值不在允许列表中",可选
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class ValidationResult(BaseModel):
|
|
263
|
+
"""
|
|
264
|
+
校验结果模型
|
|
265
|
+
|
|
266
|
+
包含通用校验的详细结果信息。
|
|
267
|
+
|
|
268
|
+
Attributes:
|
|
269
|
+
is_valid: 校验是否通过
|
|
270
|
+
error_count: 错误行数量
|
|
271
|
+
total_rows: 总行数
|
|
272
|
+
match_count: 匹配行数量(可选)
|
|
273
|
+
error_rows: 错误行列表
|
|
274
|
+
validation_time: 校验耗时
|
|
275
|
+
"""
|
|
276
|
+
|
|
277
|
+
is_valid: bool = Field(..., description="校验是否通过") # True 表示全部通过,False 表示存在错误行
|
|
278
|
+
error_count: int = Field(..., description="错误数量") # 校验失败的行数
|
|
279
|
+
total_rows: int = Field(..., description="总行数") # 参与校验的数据总行数(不含表头)
|
|
280
|
+
match_count: int | None = Field(None, description="匹配数量") # 匹配成功的行数(部分校验类型适用,如 regex),可选
|
|
281
|
+
error_rows: list[ValidationErrorRow] = Field(default=[], description="错误行列表") # 校验失败的详细行信息列表
|
|
282
|
+
validation_time: str = Field(..., description="校验耗时") # 校验执行耗时,通常以毫秒或秒为单位的字符串
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class ValidationResponse(BaseModel):
|
|
286
|
+
"""
|
|
287
|
+
统一校验响应模型
|
|
288
|
+
|
|
289
|
+
校验接口的标准响应格式。
|
|
290
|
+
|
|
291
|
+
Attributes:
|
|
292
|
+
success: 请求是否成功
|
|
293
|
+
validation_type: 执行的校验类型
|
|
294
|
+
data: 校验结果详情
|
|
295
|
+
error: 错误信息(如果有)
|
|
296
|
+
"""
|
|
297
|
+
|
|
298
|
+
success: bool = Field(..., description="请求是否成功") # True 表示请求处理成功,False 表示接口层面出错
|
|
299
|
+
validation_type: str = Field(
|
|
300
|
+
..., description="执行的校验类型"
|
|
301
|
+
) # 实际执行的校验类型标识,与请求中的 validation_type 对应
|
|
302
|
+
data: ValidationResult | None = Field(None, description="校验结果") # 校验成功时返回的详细结果,失败时为 None
|
|
303
|
+
error: str | None = Field(None, description="错误信息") # 请求处理失败时的错误描述,成功时为 None
|