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,213 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2026 Precis Team
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
"""
|
|
17
|
+
@fileoverview 数据源加载器模块
|
|
18
|
+
|
|
19
|
+
功能概述:
|
|
20
|
+
- 提供统一的数据源加载入口 load_source_data
|
|
21
|
+
- 根据数据源类型自动匹配对应的加载器类
|
|
22
|
+
- 支持 JSON、CSV、Excel、SQL 等多种数据源类型
|
|
23
|
+
- 封装加载器注册表的查询和实例化逻辑
|
|
24
|
+
|
|
25
|
+
架构设计:
|
|
26
|
+
- 加载器继承自 DataSourceLoader 抽象基类
|
|
27
|
+
- 通过 LOADER_REGISTRY 注册表实现加载器发现
|
|
28
|
+
- 支持按 source_type 字符串动态获取加载器类
|
|
29
|
+
- 加载失败时统一抛出 DataLoadError 异常
|
|
30
|
+
|
|
31
|
+
输入示例:
|
|
32
|
+
>>> from app.shared.core.data_source.specs.json_source import JSONSourceSpec
|
|
33
|
+
>>> spec = JSONSourceSpec(path="data/users.json", format="auto")
|
|
34
|
+
|
|
35
|
+
输出示例:
|
|
36
|
+
>>> from app.shared.core.data_source.loaders import load_source_data
|
|
37
|
+
>>> df = load_source_data(spec)
|
|
38
|
+
>>> print(df.head())
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from __future__ import annotations
|
|
42
|
+
|
|
43
|
+
import logging
|
|
44
|
+
from typing import Any
|
|
45
|
+
|
|
46
|
+
import pandas as pd
|
|
47
|
+
|
|
48
|
+
from .base import DataLoadError, DataSourceLoader
|
|
49
|
+
from .registry import LOADER_REGISTRY, register_loader
|
|
50
|
+
|
|
51
|
+
logger = logging.getLogger(__name__)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def load_source_data(spec: Any) -> pd.DataFrame:
|
|
55
|
+
"""
|
|
56
|
+
@methoddesc 统一的数据源加载入口
|
|
57
|
+
|
|
58
|
+
============================================================================
|
|
59
|
+
功能说明
|
|
60
|
+
============================================================================
|
|
61
|
+
根据数据源配置(spec)自动选择合适的加载器并加载数据。
|
|
62
|
+
这是推荐的数据加载接口,屏蔽了不同数据源类型之间的差异。
|
|
63
|
+
|
|
64
|
+
============================================================================
|
|
65
|
+
支持的数据源类型
|
|
66
|
+
============================================================================
|
|
67
|
+
- JSON: JSONSourceSpec → JSONLoader
|
|
68
|
+
- CSV: CSVSourceSpec → CSVLoader
|
|
69
|
+
- Excel: ExcelSourceSpec → ExcelLoader
|
|
70
|
+
- SQL: SQLSourceSpec → SQLLoader
|
|
71
|
+
|
|
72
|
+
============================================================================
|
|
73
|
+
使用示例
|
|
74
|
+
============================================================================
|
|
75
|
+
>>> from app.shared.core.data_source.loaders import load_source_data
|
|
76
|
+
>>> from app.shared.core.data_source.specs.json_source import JSONSourceSpec
|
|
77
|
+
>>>
|
|
78
|
+
>>> spec = JSONSourceSpec(path="data/users.json", format="auto")
|
|
79
|
+
>>> df = load_source_data(spec)
|
|
80
|
+
>>> print(df.head())
|
|
81
|
+
|
|
82
|
+
============================================================================
|
|
83
|
+
错误处理
|
|
84
|
+
============================================================================
|
|
85
|
+
如果加载失败,会抛出 DataLoadError 异常,包含详细的错误信息。
|
|
86
|
+
调用方应该捕获该异常并提供适当的错误处理。
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
spec: 数据源配置对象(必须是 DataSourceSpec 的子类)
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
加载的 DataFrame
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
DataLoadError: 加载失败时抛出
|
|
96
|
+
TypeError: spec 类型不支持时抛出
|
|
97
|
+
"""
|
|
98
|
+
if not hasattr(spec, "type"):
|
|
99
|
+
raise TypeError("spec 必须包含 'type' 属性")
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
loader_class = get_loader_for_source_type(spec.type)
|
|
103
|
+
except TypeError:
|
|
104
|
+
raise TypeError(f"不支持的数据源类型: {spec.type}")
|
|
105
|
+
|
|
106
|
+
loader = loader_class(spec)
|
|
107
|
+
return loader.load()
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_loader_for_source_type(source_type: str) -> type[DataSourceLoader]:
|
|
111
|
+
"""
|
|
112
|
+
@methoddesc 根据数据源类型获取对应的加载器类
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
source_type: 数据源类型(如 "json", "csv", "excel")
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
加载器类
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
TypeError: 不支持的数据源类型
|
|
122
|
+
"""
|
|
123
|
+
loader_class = LOADER_REGISTRY.get(source_type)
|
|
124
|
+
if not loader_class:
|
|
125
|
+
raise TypeError(f"不支持的数据源类型: {source_type}")
|
|
126
|
+
return loader_class
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def get_supported_types() -> list:
|
|
130
|
+
"""
|
|
131
|
+
@methoddesc 获取所有支持的数据源类型
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
支持的数据源类型列表
|
|
135
|
+
"""
|
|
136
|
+
return list(LOADER_REGISTRY.keys())
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def can_load_type(source_type: str) -> bool:
|
|
140
|
+
"""
|
|
141
|
+
@methoddesc 检查是否支持指定的数据源类型
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
source_type: 数据源类型
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
是否支持
|
|
148
|
+
"""
|
|
149
|
+
return source_type in LOADER_REGISTRY
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def load_source_data_safe(spec: Any) -> tuple[pd.DataFrame, list]:
|
|
153
|
+
"""
|
|
154
|
+
@methoddesc 安全的数据源加载入口
|
|
155
|
+
|
|
156
|
+
与 load_source_data 不同,此函数不会抛出异常,
|
|
157
|
+
而是返回 (DataFrame, errors) 元组。
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
spec: 数据源配置对象
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
(DataFrame, errors) 元组
|
|
164
|
+
- DataFrame: 加载的数据
|
|
165
|
+
- errors: 错误信息列表
|
|
166
|
+
"""
|
|
167
|
+
try:
|
|
168
|
+
df = load_source_data(spec)
|
|
169
|
+
return df, []
|
|
170
|
+
except Exception as e:
|
|
171
|
+
return pd.DataFrame(), [str(e)]
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# 延迟导入具体加载器,避免循环依赖
|
|
175
|
+
def __getattr__(name: str) -> type[DataSourceLoader]:
|
|
176
|
+
if name == "ExcelLoader":
|
|
177
|
+
from .excel_loader import ExcelLoader
|
|
178
|
+
|
|
179
|
+
return ExcelLoader
|
|
180
|
+
elif name == "CSVLoader":
|
|
181
|
+
from .csv_loader import CSVLoader
|
|
182
|
+
|
|
183
|
+
return CSVLoader
|
|
184
|
+
elif name == "JSONLoader":
|
|
185
|
+
from .json_loader import JSONLoader
|
|
186
|
+
|
|
187
|
+
return JSONLoader
|
|
188
|
+
elif name == "SQLLoader":
|
|
189
|
+
from .sql_loader import SQLLoader
|
|
190
|
+
|
|
191
|
+
return SQLLoader
|
|
192
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
__all__ = [
|
|
196
|
+
# 基类
|
|
197
|
+
"DataSourceLoader",
|
|
198
|
+
"DataLoadError",
|
|
199
|
+
"register_loader",
|
|
200
|
+
# 注册表
|
|
201
|
+
"LOADER_REGISTRY",
|
|
202
|
+
# 统一加载接口
|
|
203
|
+
"load_source_data",
|
|
204
|
+
"load_source_data_safe",
|
|
205
|
+
"get_loader_for_source_type",
|
|
206
|
+
"get_supported_types",
|
|
207
|
+
"can_load_type",
|
|
208
|
+
# 具体加载器(延迟加载)
|
|
209
|
+
"ExcelLoader",
|
|
210
|
+
"CSVLoader",
|
|
211
|
+
"JSONLoader",
|
|
212
|
+
"SQLLoader",
|
|
213
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2026 Precis Team
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
"""
|
|
17
|
+
@fileoverview 数据源加载器基类模块
|
|
18
|
+
|
|
19
|
+
功能概述:
|
|
20
|
+
- 定义加载数据源的通用抽象接口
|
|
21
|
+
- 提供泛型基类支持类型安全的规格绑定
|
|
22
|
+
- 支持批量加载的默认实现(可被子类覆盖)
|
|
23
|
+
- 提供数据源配置验证接口
|
|
24
|
+
|
|
25
|
+
架构设计:
|
|
26
|
+
- 抽象基类模式(ABC + Generic[SpecType])
|
|
27
|
+
- 子类只需实现 load 方法即可支持新数据源
|
|
28
|
+
- 支持迭代器形式的批量加载,便于处理大文件
|
|
29
|
+
- 与 DataSourceSpec 规格类形成一对一映射
|
|
30
|
+
|
|
31
|
+
输入示例:
|
|
32
|
+
class JSONLoader(DataSourceLoader[JSONSourceSpec]):
|
|
33
|
+
spec_class = JSONSourceSpec
|
|
34
|
+
|
|
35
|
+
def load(self) -> pd.DataFrame:
|
|
36
|
+
# 实现加载逻辑
|
|
37
|
+
return pd.read_json(self.spec.path)
|
|
38
|
+
|
|
39
|
+
输出示例:
|
|
40
|
+
loader = JSONLoader(spec)
|
|
41
|
+
df = loader.load() # 返回 pd.DataFrame
|
|
42
|
+
batches = loader.load_batch(10000) # 返回 Iterator[pd.DataFrame]
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
from abc import ABC, abstractmethod
|
|
48
|
+
from collections.abc import Iterator
|
|
49
|
+
from typing import Generic, TypeVar
|
|
50
|
+
|
|
51
|
+
import pandas as pd
|
|
52
|
+
|
|
53
|
+
# 类型变量,用于泛型
|
|
54
|
+
SpecType = TypeVar("SpecType", bound="DataSourceSpec")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class DataSourceLoader(ABC, Generic[SpecType]):
|
|
58
|
+
"""
|
|
59
|
+
@classdesc 数据源加载器抽象基类
|
|
60
|
+
|
|
61
|
+
定义加载数据源的通用接口。子类只需实现 load 方法即可支持新数据源。
|
|
62
|
+
|
|
63
|
+
示例:
|
|
64
|
+
class JSONLoader(DataSourceLoader[JSONSourceSpec]):
|
|
65
|
+
spec_class = JSONSourceSpec
|
|
66
|
+
|
|
67
|
+
def load(self) -> pd.DataFrame:
|
|
68
|
+
# 实现加载逻辑
|
|
69
|
+
return pd.read_json(self.spec.path)
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
# 类级别的规范类型,子类必须覆盖
|
|
73
|
+
spec_class: type
|
|
74
|
+
|
|
75
|
+
def __init__(self, spec: SpecType):
|
|
76
|
+
"""
|
|
77
|
+
初始化加载器
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
spec: 数据源规范配置
|
|
81
|
+
"""
|
|
82
|
+
self.spec = spec
|
|
83
|
+
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def load(self) -> pd.DataFrame:
|
|
86
|
+
"""
|
|
87
|
+
@methoddesc 加载数据并返回 DataFrame
|
|
88
|
+
|
|
89
|
+
这是唯一需要子类实现的方法。
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
加载的数据(pandas DataFrame)
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
DataLoadError: 加载失败时抛出
|
|
96
|
+
"""
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
def load_batch(self, batch_size: int = 10000) -> Iterator[pd.DataFrame]:
|
|
100
|
+
"""
|
|
101
|
+
@methoddesc 批量加载数据(用于大文件)
|
|
102
|
+
|
|
103
|
+
默认实现是单批次返回全部数据,
|
|
104
|
+
子类可重写以实现真正的流式读取。
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
batch_size: 每批次的行数
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
DataFrame 迭代器
|
|
111
|
+
"""
|
|
112
|
+
yield self.load()
|
|
113
|
+
|
|
114
|
+
def validate(self) -> list[str]:
|
|
115
|
+
"""
|
|
116
|
+
@methoddesc 验证数据源配置是否正确(不实际加载数据)
|
|
117
|
+
|
|
118
|
+
检查:
|
|
119
|
+
- 文件是否存在(文件型)
|
|
120
|
+
- 连接是否可达(连接型)
|
|
121
|
+
- 权限是否足够
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
错误信息列表(空列表表示验证通过)
|
|
125
|
+
"""
|
|
126
|
+
return []
|
|
127
|
+
|
|
128
|
+
def preview(self, nrows: int = 10) -> pd.DataFrame:
|
|
129
|
+
"""
|
|
130
|
+
@methoddesc 预览前 n 行数据
|
|
131
|
+
|
|
132
|
+
默认实现使用 load() 后截取,
|
|
133
|
+
子类可重写以提高性能。
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
nrows: 预览行数
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
预览数据
|
|
140
|
+
"""
|
|
141
|
+
df = self.load()
|
|
142
|
+
return df.head(nrows)
|
|
143
|
+
|
|
144
|
+
def get_schema(self) -> dict[str, str]:
|
|
145
|
+
"""
|
|
146
|
+
@methoddesc 获取数据源的 schema(列名和类型)
|
|
147
|
+
|
|
148
|
+
用于前端展示和自动推断配置。
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
字典,键为列名,值为类型字符串
|
|
152
|
+
"""
|
|
153
|
+
df = self.preview(nrows=100)
|
|
154
|
+
return {col: str(dtype) for col, dtype in df.dtypes.items()}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class DataLoadError(Exception):
|
|
158
|
+
"""
|
|
159
|
+
@classdesc 数据加载异常
|
|
160
|
+
|
|
161
|
+
当数据源加载过程中发生错误时抛出此异常。
|
|
162
|
+
包含原始错误信息、数据源规格和根本原因,便于调试和错误报告。
|
|
163
|
+
|
|
164
|
+
Attributes:
|
|
165
|
+
spec: 发生错误的数据源规格对象(可选)
|
|
166
|
+
cause: 原始异常对象(可选)
|
|
167
|
+
|
|
168
|
+
示例:
|
|
169
|
+
>>> raise DataLoadError("文件不存在", spec, original_exception)
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def __init__(self, message: str, spec: DataSourceSpec | None = None, cause: Exception | None = None):
|
|
173
|
+
"""
|
|
174
|
+
初始化数据加载异常
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
message: 错误描述信息
|
|
178
|
+
spec: 发生错误的数据源规格对象(可选)
|
|
179
|
+
cause: 导致此错误的原始异常(可选)
|
|
180
|
+
"""
|
|
181
|
+
super().__init__(message)
|
|
182
|
+
self.spec = spec
|
|
183
|
+
self.cause = cause
|
|
184
|
+
|
|
185
|
+
def __str__(self) -> str:
|
|
186
|
+
"""
|
|
187
|
+
@methoddesc 生成格式化的错误信息字符串
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
包含数据源类型和根本原因的完整错误信息
|
|
191
|
+
"""
|
|
192
|
+
msg = super().__str__()
|
|
193
|
+
if self.spec:
|
|
194
|
+
msg = f"[{self.spec.type}] {msg}"
|
|
195
|
+
if self.cause:
|
|
196
|
+
msg = f"{msg} (原因: {self.cause})"
|
|
197
|
+
return msg
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class ValidationError(Exception):
|
|
201
|
+
"""
|
|
202
|
+
@classdesc 数据验证异常
|
|
203
|
+
|
|
204
|
+
当数据源配置验证失败时抛出此异常。
|
|
205
|
+
用于在数据加载前检查配置合法性(如文件不存在、参数错误等)。
|
|
206
|
+
|
|
207
|
+
示例:
|
|
208
|
+
>>> raise ValidationError("连接字符串不能为空")
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# 延迟导入,避免循环依赖
|
|
215
|
+
from ..specs.base import DataSourceSpec
|