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,165 @@
|
|
|
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
|
+
- 定义 Schema 文件中的内嵌约束 (ConstraintItem)
|
|
21
|
+
- 支持多种约束类型: NotNull, Unique, AllowedValues, ForeignKey 等
|
|
22
|
+
|
|
23
|
+
架构设计:
|
|
24
|
+
- 统一模型: 所有约束类型使用同一个模型
|
|
25
|
+
- 字段可选: 根据约束类型不同,需要填写不同字段
|
|
26
|
+
- 简化写法: 支持 column 简写和 columns 列表
|
|
27
|
+
|
|
28
|
+
输入示例 (schema.yaml):
|
|
29
|
+
constraints:
|
|
30
|
+
# 非空约束 (简化写法)
|
|
31
|
+
- id: not_null_email
|
|
32
|
+
type: NotNull
|
|
33
|
+
column: email
|
|
34
|
+
|
|
35
|
+
# 允许值约束
|
|
36
|
+
- id: status_allowed
|
|
37
|
+
type: AllowedValues
|
|
38
|
+
column: status
|
|
39
|
+
params:
|
|
40
|
+
allowed_values:
|
|
41
|
+
- active
|
|
42
|
+
- inactive
|
|
43
|
+
- pending
|
|
44
|
+
|
|
45
|
+
# 外键约束
|
|
46
|
+
- id: fk_orders
|
|
47
|
+
type: ForeignKey
|
|
48
|
+
from_column: user_id
|
|
49
|
+
to_table: users
|
|
50
|
+
to_column: id
|
|
51
|
+
|
|
52
|
+
输出示例:
|
|
53
|
+
ConstraintItem(
|
|
54
|
+
id="not_null_email",
|
|
55
|
+
type="NotNull",
|
|
56
|
+
enabled=True,
|
|
57
|
+
column="email"
|
|
58
|
+
)
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
from __future__ import annotations
|
|
62
|
+
|
|
63
|
+
from typing import Any, Literal
|
|
64
|
+
|
|
65
|
+
from pydantic import BaseModel, Field, model_validator
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ConstraintItem(BaseModel):
|
|
69
|
+
"""@classdesc 内嵌约束项
|
|
70
|
+
|
|
71
|
+
在 Schema 文件中直接定义的约束。
|
|
72
|
+
|
|
73
|
+
字段说明:
|
|
74
|
+
- id: 约束 ID (表内唯一)
|
|
75
|
+
- type: 约束类型
|
|
76
|
+
- NotNull: 非空约束
|
|
77
|
+
- Unique: 唯一性约束
|
|
78
|
+
- AllowedValues: 允许值约束
|
|
79
|
+
- ForeignKey: 外键约束
|
|
80
|
+
- Conditional: 条件约束
|
|
81
|
+
- Scripted: 脚本约束
|
|
82
|
+
- Range: 范围约束
|
|
83
|
+
- Charset: 字符集约束
|
|
84
|
+
- DateLogic: 日期逻辑约束
|
|
85
|
+
- enabled: 是否启用
|
|
86
|
+
- description: 约束描述 (可选)
|
|
87
|
+
|
|
88
|
+
# 列级约束 (二选一)
|
|
89
|
+
- column: 目标列名 (单列)
|
|
90
|
+
- columns: 目标列名列表 (多列,如联合唯一键)
|
|
91
|
+
|
|
92
|
+
# 外键约束 (仅 ForeignKey 类型)
|
|
93
|
+
- from_table: 源表名
|
|
94
|
+
- from_column: 源列名
|
|
95
|
+
- to_table: 目标表名
|
|
96
|
+
- to_column: 目标列名
|
|
97
|
+
|
|
98
|
+
# 通用参数
|
|
99
|
+
- params: 约束参数 (如 AllowedValues 的 allowed_values 列表)
|
|
100
|
+
|
|
101
|
+
输入示例 (schema.yaml):
|
|
102
|
+
constraints:
|
|
103
|
+
# 非空约束 (简化写法)
|
|
104
|
+
- id: not_null_email
|
|
105
|
+
type: NotNull
|
|
106
|
+
column: email
|
|
107
|
+
|
|
108
|
+
# 允许值约束
|
|
109
|
+
- id: status_allowed
|
|
110
|
+
type: AllowedValues
|
|
111
|
+
column: status
|
|
112
|
+
params:
|
|
113
|
+
allowed_values:
|
|
114
|
+
- active
|
|
115
|
+
- inactive
|
|
116
|
+
- pending
|
|
117
|
+
|
|
118
|
+
# 外键约束
|
|
119
|
+
- id: fk_orders
|
|
120
|
+
type: ForeignKey
|
|
121
|
+
from_column: user_id
|
|
122
|
+
to_table: users
|
|
123
|
+
to_column: id
|
|
124
|
+
|
|
125
|
+
输出示例:
|
|
126
|
+
ConstraintItem(
|
|
127
|
+
id="not_null_email",
|
|
128
|
+
type="NotNull",
|
|
129
|
+
enabled=True,
|
|
130
|
+
column="email"
|
|
131
|
+
)
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
id: str = Field(..., description="约束 ID(同一表内必须唯一)")
|
|
135
|
+
type: Literal[
|
|
136
|
+
"NotNull",
|
|
137
|
+
"Unique",
|
|
138
|
+
"AllowedValues",
|
|
139
|
+
"ForeignKey",
|
|
140
|
+
"Conditional",
|
|
141
|
+
"Scripted",
|
|
142
|
+
"Range",
|
|
143
|
+
"Charset",
|
|
144
|
+
"DateLogic",
|
|
145
|
+
"Composite",
|
|
146
|
+
] = Field(..., description="约束类型")
|
|
147
|
+
enabled: bool = Field(True, description="是否启用")
|
|
148
|
+
description: str | None = Field(None, description="约束描述")
|
|
149
|
+
|
|
150
|
+
column: str | None = Field(None, description="目标列名(简化写法)")
|
|
151
|
+
columns: list[str] | None = Field(None, description="目标列名列表(多列约束)")
|
|
152
|
+
|
|
153
|
+
from_table: str | None = Field(None, description="外键源表名")
|
|
154
|
+
from_column: str | None = Field(None, description="外键源列名")
|
|
155
|
+
to_table: str | None = Field(None, description="外键目标表名")
|
|
156
|
+
to_column: str | None = Field(None, description="外键目标列名")
|
|
157
|
+
|
|
158
|
+
params: dict[str, Any] = Field(default_factory=dict, description="约束参数(如 allowed_values 等)")
|
|
159
|
+
|
|
160
|
+
@model_validator(mode="after")
|
|
161
|
+
def _validate_column_exclusivity(self) -> ConstraintItem:
|
|
162
|
+
"""B20 修复:column 与 columns 互斥,同时填写会引发歧义。"""
|
|
163
|
+
if self.column is not None and self.columns is not None:
|
|
164
|
+
raise ValueError("column 与 columns 不可同时设置,请仅使用其一")
|
|
165
|
+
return self
|
|
@@ -0,0 +1,66 @@
|
|
|
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 Schema ID 工具模块
|
|
17
|
+
|
|
18
|
+
功能概述:
|
|
19
|
+
- 提供 Schema source 标准化函数,用于唯一性检测
|
|
20
|
+
- 旧版路径派生 ID 逻辑已移除,Schema ID 现在由人/AI 显式命名
|
|
21
|
+
|
|
22
|
+
设计原则:
|
|
23
|
+
- Schema ID 不再从路径派生,而是由用户或 AI 显式提供
|
|
24
|
+
- 唯一性通过两层保证:ID 不重名 + (source.path, source.sheet) 不重复
|
|
25
|
+
- source 标准化逻辑集中在此处,前后端共用
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def normalize_source_key(path: str, sheet: str | None) -> tuple[str, str | None]:
|
|
32
|
+
"""标准化 source 的 (path, sheet) 元组,用于唯一性检测和索引
|
|
33
|
+
|
|
34
|
+
处理流程:
|
|
35
|
+
1. 路径:反斜杠 → 正斜杠、去 ./ 前缀、pathlib 规范化、转小写
|
|
36
|
+
2. sheet:strip + 转小写;空字符串/None 统一为 None
|
|
37
|
+
|
|
38
|
+
参数:
|
|
39
|
+
path: 数据文件路径(相对或绝对)
|
|
40
|
+
sheet: Excel 工作表名(非 Excel 文件传 None)
|
|
41
|
+
|
|
42
|
+
返回:
|
|
43
|
+
标准化的 (path, sheet) 元组
|
|
44
|
+
|
|
45
|
+
示例:
|
|
46
|
+
>>> normalize_source_key("data\\\\users.xlsx", "Sheet1")
|
|
47
|
+
('data/users.xlsx', 'sheet1')
|
|
48
|
+
>>> normalize_source_key("./data/users.csv", None)
|
|
49
|
+
('data/users.csv', None)
|
|
50
|
+
>>> normalize_source_key("data/users.xlsx", "")
|
|
51
|
+
('data/users.xlsx', None)
|
|
52
|
+
"""
|
|
53
|
+
from pathlib import PurePosixPath
|
|
54
|
+
|
|
55
|
+
p = str(path or "").replace("\\", "/").strip()
|
|
56
|
+
if p.startswith("./"):
|
|
57
|
+
p = p[2:]
|
|
58
|
+
p = str(PurePosixPath(p))
|
|
59
|
+
if p.startswith("./"):
|
|
60
|
+
p = p[2:]
|
|
61
|
+
p = p.lower()
|
|
62
|
+
|
|
63
|
+
s: str | None = (sheet or "").strip().lower()
|
|
64
|
+
s = s or None
|
|
65
|
+
|
|
66
|
+
return (p, s)
|
|
@@ -0,0 +1,255 @@
|
|
|
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
|
+
- 定义 Schema 中的数据源结构 (SourceSpec)
|
|
21
|
+
- 指定数据文件的路径和工作表信息
|
|
22
|
+
- 支持多种数据源格式:Excel、CSV、JSON 等
|
|
23
|
+
- 格式选项通过 FormatOptions 联合类型实现
|
|
24
|
+
|
|
25
|
+
架构设计:
|
|
26
|
+
- 路径模式: 支持相对路径和绝对路径
|
|
27
|
+
- Excel 支持: 可指定工作表名和表头行
|
|
28
|
+
- 格式选项: 通过 FormatOptions 联合类型支持不同格式的特定配置
|
|
29
|
+
|
|
30
|
+
输入示例 (schema.yaml):
|
|
31
|
+
# Excel 数据源
|
|
32
|
+
source:
|
|
33
|
+
mode: relative_file
|
|
34
|
+
path: data/users.xlsx
|
|
35
|
+
sheet: Sheet1
|
|
36
|
+
header_row: 0
|
|
37
|
+
|
|
38
|
+
# JSON 数据源
|
|
39
|
+
source:
|
|
40
|
+
mode: relative_file
|
|
41
|
+
path: data/users.json
|
|
42
|
+
options:
|
|
43
|
+
format: auto
|
|
44
|
+
|
|
45
|
+
# 嵌套 JSON 数据源
|
|
46
|
+
source:
|
|
47
|
+
mode: relative_file
|
|
48
|
+
path: data/api_response.json
|
|
49
|
+
options:
|
|
50
|
+
format: object
|
|
51
|
+
json_path: "$.data.items"
|
|
52
|
+
sep: "."
|
|
53
|
+
|
|
54
|
+
# CSV 数据源
|
|
55
|
+
source:
|
|
56
|
+
mode: relative_file
|
|
57
|
+
path: data/users.csv
|
|
58
|
+
options:
|
|
59
|
+
delimiter: ","
|
|
60
|
+
encoding: utf-8
|
|
61
|
+
|
|
62
|
+
输出示例:
|
|
63
|
+
SourceSpec(
|
|
64
|
+
mode="relative_file",
|
|
65
|
+
path="data/users.xlsx",
|
|
66
|
+
sheet="Sheet1",
|
|
67
|
+
header_row=0,
|
|
68
|
+
options=ExcelOptions()
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
原理说明:
|
|
72
|
+
为什么需要 mode 字段?
|
|
73
|
+
- relative_file: 便于项目迁移,路径相对于项目根目录
|
|
74
|
+
- absolute_file: 用于共享数据源,多个项目共享同一文件
|
|
75
|
+
|
|
76
|
+
为什么需要 options 字段?
|
|
77
|
+
- 将格式特定配置分离到独立的对象中
|
|
78
|
+
- 提高类型安全性,避免 JSON 配置污染 CSV/Excel schema
|
|
79
|
+
- 便于扩展新格式的支持
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
from __future__ import annotations
|
|
83
|
+
|
|
84
|
+
from typing import Any, Literal
|
|
85
|
+
|
|
86
|
+
from pydantic import BaseModel, Field, field_validator
|
|
87
|
+
|
|
88
|
+
from app.shared.core.utils.path_utils import normalize_to_posix
|
|
89
|
+
|
|
90
|
+
from .source_options import (
|
|
91
|
+
FormatOptions,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class SourceSpec(BaseModel):
|
|
96
|
+
"""@classdesc 数据源规范
|
|
97
|
+
|
|
98
|
+
指定 Schema 对应的数据文件位置。
|
|
99
|
+
|
|
100
|
+
字段说明:
|
|
101
|
+
- mode: 路径模式
|
|
102
|
+
- relative_file: 相对于项目根目录
|
|
103
|
+
- absolute_file: 绝对路径
|
|
104
|
+
- path: 文件路径
|
|
105
|
+
- sheet: Excel 工作表名 (可选,仅 Excel 文件需要)
|
|
106
|
+
- header_row: 表头行索引 (默认 0,即第一行)
|
|
107
|
+
- options: 格式特定配置(JSONOptions/CSVOptions/ExcelOptions)
|
|
108
|
+
|
|
109
|
+
输入示例 (schema.yaml):
|
|
110
|
+
# Excel 数据源
|
|
111
|
+
source:
|
|
112
|
+
mode: relative_file
|
|
113
|
+
path: data/users.xlsx
|
|
114
|
+
sheet: Sheet1
|
|
115
|
+
header_row: 0
|
|
116
|
+
|
|
117
|
+
# JSON 数据源
|
|
118
|
+
source:
|
|
119
|
+
mode: relative_file
|
|
120
|
+
path: data/users.json
|
|
121
|
+
options:
|
|
122
|
+
format: auto
|
|
123
|
+
|
|
124
|
+
# 嵌套 JSON 数据源
|
|
125
|
+
source:
|
|
126
|
+
mode: relative_file
|
|
127
|
+
path: data/api_response.json
|
|
128
|
+
options:
|
|
129
|
+
format: object
|
|
130
|
+
json_path: "$.data.items"
|
|
131
|
+
sep: "."
|
|
132
|
+
|
|
133
|
+
# CSV 数据源
|
|
134
|
+
source:
|
|
135
|
+
mode: relative_file
|
|
136
|
+
path: data/users.csv
|
|
137
|
+
options:
|
|
138
|
+
delimiter: ","
|
|
139
|
+
encoding: utf-8
|
|
140
|
+
|
|
141
|
+
输出示例:
|
|
142
|
+
SourceSpec(
|
|
143
|
+
mode="relative_file",
|
|
144
|
+
path="data/users.xlsx",
|
|
145
|
+
sheet="Sheet1",
|
|
146
|
+
header_row=0,
|
|
147
|
+
options=ExcelOptions()
|
|
148
|
+
)
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
mode: Literal["relative_file", "absolute_file"] = Field(..., description="数据源模式")
|
|
152
|
+
path: str = Field(..., description="文件路径(相对/绝对取决于 mode)")
|
|
153
|
+
sheet: str | None = Field(None, description="Excel 工作表名称")
|
|
154
|
+
header_row: int = Field(0, ge=0, description="表头行索引(与 pandas header 语义一致)")
|
|
155
|
+
|
|
156
|
+
options: FormatOptions | None = Field(None, description="格式特定配置(JSONOptions/CSVOptions/ExcelOptions)")
|
|
157
|
+
|
|
158
|
+
@field_validator("path")
|
|
159
|
+
@classmethod
|
|
160
|
+
def normalize_path(cls, v: str) -> str:
|
|
161
|
+
r"""
|
|
162
|
+
@methoddesc 标准化路径,将反斜杠转换为正斜杠
|
|
163
|
+
|
|
164
|
+
不同操作系统使用不同的路径分隔符:
|
|
165
|
+
- Windows 使用反斜杠(\)
|
|
166
|
+
- Linux/macOS 使用正斜杠(/)
|
|
167
|
+
|
|
168
|
+
为了保证跨平台一致性,统一将反斜杠替换为正斜杠。
|
|
169
|
+
|
|
170
|
+
参数说明:
|
|
171
|
+
:param v: 原始路径字符串
|
|
172
|
+
:return: 标准化后的路径字符串
|
|
173
|
+
|
|
174
|
+
示例:
|
|
175
|
+
>>> normalize_path(r"data\myfile.xlsx")
|
|
176
|
+
'data/myfile.xlsx'
|
|
177
|
+
"""
|
|
178
|
+
return normalize_to_posix(v)
|
|
179
|
+
|
|
180
|
+
def is_json(self) -> bool:
|
|
181
|
+
"""@methoddesc 判断数据源是否为 JSON 格式
|
|
182
|
+
|
|
183
|
+
通过检查文件路径的后缀名来判断是否为 JSON 文件。
|
|
184
|
+
支持的 JSON 扩展名包括:.json、.jsonl(JSON Lines)、.ndjson(Newline Delimited JSON)
|
|
185
|
+
|
|
186
|
+
返回:
|
|
187
|
+
True 表示是 JSON 格式,False 表示不是
|
|
188
|
+
|
|
189
|
+
示例:
|
|
190
|
+
>>> spec = SourceSpec(mode="relative_file", path="data/users.json")
|
|
191
|
+
>>> spec.is_json()
|
|
192
|
+
True
|
|
193
|
+
>>> spec = SourceSpec(mode="relative_file", path="data/users.csv")
|
|
194
|
+
>>> spec.is_json()
|
|
195
|
+
False
|
|
196
|
+
"""
|
|
197
|
+
return self.path.lower().endswith((".json", ".jsonl", ".ndjson"))
|
|
198
|
+
|
|
199
|
+
def get_file_extension(self) -> str:
|
|
200
|
+
"""@methoddesc 获取文件扩展名(小写)
|
|
201
|
+
|
|
202
|
+
从文件路径中提取扩展名部分,用于判断文件格式。
|
|
203
|
+
|
|
204
|
+
返回:
|
|
205
|
+
小写的文件扩展名(不含点号),如果路径中没有扩展名则返回空字符串
|
|
206
|
+
|
|
207
|
+
示例:
|
|
208
|
+
>>> spec = SourceSpec(mode="relative_file", path="data/users.xlsx")
|
|
209
|
+
>>> spec.get_file_extension()
|
|
210
|
+
'xlsx'
|
|
211
|
+
>>> spec = SourceSpec(mode="relative_file", path="data/users")
|
|
212
|
+
>>> spec.get_file_extension()
|
|
213
|
+
''
|
|
214
|
+
"""
|
|
215
|
+
return self.path.split(".")[-1].lower() if "." in self.path else ""
|
|
216
|
+
|
|
217
|
+
def to_loader_config(self) -> dict[str, Any]:
|
|
218
|
+
"""@methoddesc 转换为数据加载器配置字典
|
|
219
|
+
|
|
220
|
+
将 SourceSpec 对象转换为底层数据加载器可识别的配置字典。
|
|
221
|
+
加载器使用这些参数来读取和解析数据文件。
|
|
222
|
+
|
|
223
|
+
处理流程:
|
|
224
|
+
1. 构建基础配置(路径、模式、编码、表头行)
|
|
225
|
+
2. 如果存在格式特定选项(options),将其配置合并到基础配置中
|
|
226
|
+
3. 返回完整的加载器配置字典
|
|
227
|
+
|
|
228
|
+
返回:
|
|
229
|
+
加载器配置字典,包含以下键:
|
|
230
|
+
- path: 文件路径
|
|
231
|
+
- mode: 路径模式("relative" 或 "absolute")
|
|
232
|
+
- encoding: 文件编码
|
|
233
|
+
- header_row: 表头行索引
|
|
234
|
+
- 以及 format options 中的其他配置项
|
|
235
|
+
|
|
236
|
+
示例:
|
|
237
|
+
>>> spec = SourceSpec(mode="relative_file", path="data/users.csv")
|
|
238
|
+
>>> spec.to_loader_config()
|
|
239
|
+
{'path': 'data/users.csv', 'mode': 'relative', 'encoding': 'utf-8', 'header_row': 0}
|
|
240
|
+
"""
|
|
241
|
+
# 构建基础配置字典
|
|
242
|
+
config = {
|
|
243
|
+
"path": self.path,
|
|
244
|
+
# 将 mode 转换为加载器使用的格式
|
|
245
|
+
"mode": "relative" if self.mode == "relative_file" else "absolute",
|
|
246
|
+
"encoding": "utf-8",
|
|
247
|
+
"header_row": self.header_row,
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# 如果存在格式特定选项,合并到配置中
|
|
251
|
+
# 例如 CSVOptions 会添加 delimiter、quotechar 等配置
|
|
252
|
+
if self.options:
|
|
253
|
+
config.update(self.options.to_loader_config())
|
|
254
|
+
|
|
255
|
+
return config
|