csvpath 0.0.522__tar.gz → 0.0.524__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {csvpath-0.0.522 → csvpath-0.0.524}/PKG-INFO +14 -6
- {csvpath-0.0.522 → csvpath-0.0.524}/README.md +11 -4
- csvpath-0.0.524/csvpath/__init__.py +18 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/asker.py +14 -7
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/cli.py +120 -41
- csvpath-0.0.524/csvpath/cli/const.py +26 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/drill_down.py +19 -14
- csvpath-0.0.524/csvpath/cli/function_describer.py +190 -0
- csvpath-0.0.524/csvpath/cli/function_lister.py +30 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/selecter.py +19 -2
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/csvpath.py +136 -81
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/csvpaths.py +124 -98
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/files/file_cacher.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/files/file_manager.py +22 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/files/file_metadata.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/files/file_registrar.py +2 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/files/files_listener.py +2 -3
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/paths/paths_listener.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/paths/paths_manager.py +19 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/paths/paths_metadata.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/paths/paths_registrar.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/result.py +14 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/result_file_reader.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/result_metadata.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/result_registrar.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/result_serializer.py +6 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/results_manager.py +38 -3
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/results_metadata.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/results_registrar.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/args.py +5 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/args_helper.py +8 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/notf.py +8 -2
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/count.py +2 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/counter.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/increment.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/tally.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/function.py +4 -0
- csvpath-0.0.524/csvpath/matching/functions/function_factory.py +373 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/header_names_mismatch.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/reset_headers.py +7 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/dups.py +22 -8
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/first.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/stop.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/intf.py +2 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/subtotal.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/sum.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/misc/fingerprint.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/misc/random.py +1 -10
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/print/printf.py +12 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/stats/minf.py +6 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/stats/percent_unique.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/regex.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/boolean.py +13 -2
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/datef.py +12 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/decimal.py +13 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/email.py +11 -8
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/nonef.py +15 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/string.py +14 -3
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/url.py +8 -8
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/validity/line.py +10 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/variables/pushpop.py +8 -1
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/variables/track.py +1 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/matchable.py +6 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/qualified.py +1 -1
- csvpath-0.0.524/docs/csvpath/managers/files/file_cacher.html +298 -0
- csvpath-0.0.524/docs/csvpath/managers/files/file_manager.html +1148 -0
- csvpath-0.0.524/docs/csvpath/managers/files/file_metadata.html +264 -0
- csvpath-0.0.524/docs/csvpath/managers/files/file_registrar.html +399 -0
- csvpath-0.0.524/docs/csvpath/managers/files/files_listener.html +324 -0
- csvpath-0.0.524/docs/csvpath/managers/files.html +236 -0
- csvpath-0.0.524/docs/csvpath/managers/paths/paths_listener.html +314 -0
- csvpath-0.0.524/docs/csvpath/managers/paths/paths_manager.html +1398 -0
- csvpath-0.0.524/docs/csvpath/managers/paths/paths_metadata.html +255 -0
- csvpath-0.0.524/docs/csvpath/managers/paths/paths_registrar.html +391 -0
- csvpath-0.0.524/docs/csvpath/managers/paths.html +235 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers/file_errors_reader.html +358 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers/file_lines_reader.html +351 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers/file_printouts_reader.html +445 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers/file_unmatched_reader.html +335 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers/readers.html +1033 -0
- csvpath-0.0.524/docs/csvpath/managers/results/readers.html +241 -0
- csvpath-0.0.524/docs/csvpath/managers/results/result.html +1629 -0
- csvpath-0.0.524/docs/csvpath/managers/results/result_file_reader.html +274 -0
- csvpath-0.0.524/docs/csvpath/managers/results/result_metadata.html +357 -0
- csvpath-0.0.524/docs/csvpath/managers/results/result_registrar.html +496 -0
- csvpath-0.0.524/docs/csvpath/managers/results/result_serializer.html +435 -0
- csvpath-0.0.524/docs/csvpath/managers/results/results_manager.html +1898 -0
- csvpath-0.0.524/docs/csvpath/managers/results/results_metadata.html +281 -0
- csvpath-0.0.524/docs/csvpath/managers/results/results_registrar.html +419 -0
- csvpath-0.0.524/docs/csvpath/managers/results.html +240 -0
- csvpath-0.0.524/docs/csvpath.html +4443 -0
- csvpath-0.0.524/docs/index.html +7 -0
- csvpath-0.0.524/docs/search.js +46 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/pyproject.toml +3 -2
- csvpath-0.0.522/csvpath/__init__.py +0 -6
- csvpath-0.0.522/csvpath/matching/functions/function_factory.py +0 -447
- {csvpath-0.0.522 → csvpath-0.0.524}/LICENSE +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/config/config.ini +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/cli/debug_config.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/errors/error.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/errors/error_collector.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/errors/error_comms.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/errors/error_manager.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ckan/ckan.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ckan/datafile.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ckan/dataset.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/event.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/event_result.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/job.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/run.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/run_state.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/ol/sender.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/metrics.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/slack/event.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/integrations/slack/sender.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/listener.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/metadata.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/registrar.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/results/readers/readers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/run/run_listener_stdout.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/run/run_metadata.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/managers/run/run_registrar.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/count_bytes.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/function_finder.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/append.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/insert.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/odd.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/alter.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/caps.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/contains.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/types/type.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/matching/util/runtime_data_collector.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/error_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/explain_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/files_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/logic_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/mode_controller.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/print_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/return_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/run_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/source_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/transfer_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/unmatched_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/modes/validation_mode.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/__init__.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/exceptions.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/parser.out +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/parsetab.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/scanner.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/scanning/scanning_lexer.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/box.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/class_loader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/config.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/file_info.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/file_readers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/file_writers.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/hasher.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/line_spooler.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/nos.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/pandas_data_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/reference_parser.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/s3/s3_data_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/s3/s3_data_writer.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/s3/s3_fingerprinter.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/s3/s3_utils.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/csvpath/util/var_utility.py +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/asbool.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/assignment.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/comments.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/config.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/examples.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/files.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/above.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/advance.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/after_blank.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/all.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/andor.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/any.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/average.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/between.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/collect.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/contains.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/correlate.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/count.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/count_bytes.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/count_headers.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/counter.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/date.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/email.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/empty.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/empty_stack.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/end.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/equal.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/every.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/fail.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/fingerprint.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/first.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/get.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/has_dups.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/has_matches.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/header.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/header_name.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/header_names_mismatch.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/implementing_functions.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/import.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/in.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/increment.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/intf.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/jinja.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/last.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/line.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/line_number.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/max.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/metaphone.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/mismatch.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/no.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/not.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/now.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/odd.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/percent_unique.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/pop.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/print.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/print_line.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/print_queue.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/random.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/regex.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/replace.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/reset_headers.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/stdev.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/stop.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/string_functions.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/subtotal.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/subtract.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/sum.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/tally.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/total_lines.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/track.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/types.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/variables.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions/variables_and_headers.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/functions.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/grammar.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/headers.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/ckan-logo-sm.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/csvpath-icon-sm.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/csvpath-logo-wordmark-tight-2.svg +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/logo-wordmark-3.svg +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/logo-wordmark-4.svg +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/logo-wordmark-white-trimmed.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/marquez-logo-sm.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/openlineage-logo-sm.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/opentelemetry.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/sftpplus-logo2.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/images/sftpplus-logo3.png +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/paths.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/printing.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/qualifiers.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/references.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/terms.md +0 -0
- {csvpath-0.0.522 → csvpath-0.0.524}/docs/variables.md +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: csvpath
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.524
|
|
4
4
|
Summary: An edge governance framework for managing and validating CSV, Excel, and other tabular data files
|
|
5
5
|
Author: David Kershaw
|
|
6
6
|
Author-email: dk107dk@hotmail.com
|
|
7
|
-
Requires-Python: >3.10
|
|
7
|
+
Requires-Python: >3.10,<4.0
|
|
8
8
|
Classifier: Development Status :: 3 - Alpha
|
|
9
9
|
Classifier: Environment :: Console
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
@@ -32,6 +32,7 @@ Requires-Dist: metaphone (>=0.6,<0.7)
|
|
|
32
32
|
Requires-Dist: openlineage-python (>=1.25.0,<2.0.0)
|
|
33
33
|
Requires-Dist: opentelemetry-distro[otlp] (>=0.50b0,<0.51)
|
|
34
34
|
Requires-Dist: paramiko (>=3.5.0,<4.0.0)
|
|
35
|
+
Requires-Dist: pdoc (>=15.0.1,<16.0.0)
|
|
35
36
|
Requires-Dist: ply (>=3.11,<4.0)
|
|
36
37
|
Requires-Dist: prompt-toolkit (>=3.0.50,<4.0.0)
|
|
37
38
|
Requires-Dist: pylightxl (>=1.61,<2.0)
|
|
@@ -49,9 +50,9 @@ Description-Content-Type: text/markdown
|
|
|
49
50
|
|
|
50
51
|
# <a href='https://www.csvpath.org/'><img src='https://github.com/csvpath/csvpath/blob/main/docs/images/logo-wordmark-4.svg'/></a>
|
|
51
52
|
|
|
52
|
-
The CsvPath Language defines a declarative syntax for inspecting and validating CSV and Excel files, and other tabular data.
|
|
53
|
+
The CsvPath Framework helps you close the gap between Managed File Transfer and your data lake and/or applications. CsvPath Language is the core of the Framework. It defines a declarative syntax for inspecting and validating CSV and Excel files, and other tabular data.
|
|
53
54
|
|
|
54
|
-
The CsvPath Framework makes it easy to setup a <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics.pdf'>Collect, Store, Validate Pattern</a> flat-file landing zone that:
|
|
55
|
+
The CsvPath Framework makes it easy to setup a <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics-88gj.pdf'>Collect, Store, Validate Pattern</a> flat-file landing zone that:
|
|
55
56
|
- Registers files for **clear and durable identity**
|
|
56
57
|
- **Validates the data** against expectations
|
|
57
58
|
- Provides **operations and validity reports**
|
|
@@ -93,6 +94,7 @@ If you need help, use the <a href='https://www.csvpath.org/getting-started/get-h
|
|
|
93
94
|
|
|
94
95
|
- [Motivation](#motivation)
|
|
95
96
|
- [Install](#install)
|
|
97
|
+
- [Python Interface Docs (pdocs)](#pdocs)
|
|
96
98
|
- [High-level Description](#description)
|
|
97
99
|
- [Running CsvPath](#running)
|
|
98
100
|
- [Validation](#validating)
|
|
@@ -126,9 +128,9 @@ This project tackles two needs:
|
|
|
126
128
|
- A more robust validation language for delimited and tabular data
|
|
127
129
|
- A systems integration framework for flat-file landing and staging
|
|
128
130
|
|
|
129
|
-
CsvPath Language is
|
|
131
|
+
CsvPath Language is the core of the CsvPath Framework. It is a simple validation language for delimited data. It supports both schema definitions and rules-based validation. CsvPath Language describes data so you can easily tell if a file is valid. CsvPath can also extract and shape data and create reports. Overall the goal is to automate human judgement out of the processing loop and instead move it to the process definition stage.
|
|
130
132
|
|
|
131
|
-
The CsvPath Framework implements CsvPath Language, but goes far beyond it to provide a full <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics.pdf'>Collect, Store, Validate Pattern</a> framework for landing flat files, registering them, validating them, shaping them to a consistent and comparable form, and staging them for a data lake. In that way, CsvPath fills the gap commonly found between an organization's MFT (managed file transfer) and a typical data lake architecture.
|
|
133
|
+
The CsvPath Framework implements CsvPath Language, but goes far beyond it to provide a full <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics-88gj.pdf'>Collect, Store, Validate Pattern</a> framework for landing flat files, registering them, validating them, shaping them to a consistent and comparable form, and staging them for a data lake. In that way, CsvPath fills the gap commonly found between an organization's MFT (managed file transfer) and a typical data lake architecture.
|
|
132
134
|
|
|
133
135
|
CsvPath's goal is to make simple validations almost trivial and more complex situations more manageable. It is a library and framework, not a system, so it relies on being easy to integrate with other DataOps tools.
|
|
134
136
|
|
|
@@ -150,6 +152,12 @@ CsvPath has an optional dependency on Pandas. Pandas data frames can be used as
|
|
|
150
152
|
|
|
151
153
|
Pandas and its dependencies can make it harder to use CsvPath in certain specific MFT use cases. For e.g., using Pandas in an AWS Lambda layer may be less straightforward. If you need the capability, though, it is easy to install.
|
|
152
154
|
|
|
155
|
+
|
|
156
|
+
<a name="pdocs"></a>
|
|
157
|
+
# Python Interface Docs
|
|
158
|
+
<a href='https://csvpath.github.io/csvpath/' target='_blank'>Python docs are here</a>.
|
|
159
|
+
The CsvPath Framework's public interface is streamlined. csvpath.CsvPath and csvpath.CsvPaths are where most of the magic happens. Docs for deeper levels will be added over time.
|
|
160
|
+
|
|
153
161
|
# Description
|
|
154
162
|
<a name="description"></a>
|
|
155
163
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
# <a href='https://www.csvpath.org/'><img src='https://github.com/csvpath/csvpath/blob/main/docs/images/logo-wordmark-4.svg'/></a>
|
|
3
3
|
|
|
4
|
-
The CsvPath Language defines a declarative syntax for inspecting and validating CSV and Excel files, and other tabular data.
|
|
4
|
+
The CsvPath Framework helps you close the gap between Managed File Transfer and your data lake and/or applications. CsvPath Language is the core of the Framework. It defines a declarative syntax for inspecting and validating CSV and Excel files, and other tabular data.
|
|
5
5
|
|
|
6
|
-
The CsvPath Framework makes it easy to setup a <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics.pdf'>Collect, Store, Validate Pattern</a> flat-file landing zone that:
|
|
6
|
+
The CsvPath Framework makes it easy to setup a <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics-88gj.pdf'>Collect, Store, Validate Pattern</a> flat-file landing zone that:
|
|
7
7
|
- Registers files for **clear and durable identity**
|
|
8
8
|
- **Validates the data** against expectations
|
|
9
9
|
- Provides **operations and validity reports**
|
|
@@ -45,6 +45,7 @@ If you need help, use the <a href='https://www.csvpath.org/getting-started/get-h
|
|
|
45
45
|
|
|
46
46
|
- [Motivation](#motivation)
|
|
47
47
|
- [Install](#install)
|
|
48
|
+
- [Python Interface Docs (pdocs)](#pdocs)
|
|
48
49
|
- [High-level Description](#description)
|
|
49
50
|
- [Running CsvPath](#running)
|
|
50
51
|
- [Validation](#validating)
|
|
@@ -78,9 +79,9 @@ This project tackles two needs:
|
|
|
78
79
|
- A more robust validation language for delimited and tabular data
|
|
79
80
|
- A systems integration framework for flat-file landing and staging
|
|
80
81
|
|
|
81
|
-
CsvPath Language is
|
|
82
|
+
CsvPath Language is the core of the CsvPath Framework. It is a simple validation language for delimited data. It supports both schema definitions and rules-based validation. CsvPath Language describes data so you can easily tell if a file is valid. CsvPath can also extract and shape data and create reports. Overall the goal is to automate human judgement out of the processing loop and instead move it to the process definition stage.
|
|
82
83
|
|
|
83
|
-
The CsvPath Framework implements CsvPath Language, but goes far beyond it to provide a full <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics.pdf'>Collect, Store, Validate Pattern</a> framework for landing flat files, registering them, validating them, shaping them to a consistent and comparable form, and staging them for a data lake. In that way, CsvPath fills the gap commonly found between an organization's MFT (managed file transfer) and a typical data lake architecture.
|
|
84
|
+
The CsvPath Framework implements CsvPath Language, but goes far beyond it to provide a full <a href='https://www.atestaanalytics.com/s/The-Collect-Store-Validate-Pattern-Atesta-Analytics-88gj.pdf'>Collect, Store, Validate Pattern</a> framework for landing flat files, registering them, validating them, shaping them to a consistent and comparable form, and staging them for a data lake. In that way, CsvPath fills the gap commonly found between an organization's MFT (managed file transfer) and a typical data lake architecture.
|
|
84
85
|
|
|
85
86
|
CsvPath's goal is to make simple validations almost trivial and more complex situations more manageable. It is a library and framework, not a system, so it relies on being easy to integrate with other DataOps tools.
|
|
86
87
|
|
|
@@ -102,6 +103,12 @@ CsvPath has an optional dependency on Pandas. Pandas data frames can be used as
|
|
|
102
103
|
|
|
103
104
|
Pandas and its dependencies can make it harder to use CsvPath in certain specific MFT use cases. For e.g., using Pandas in an AWS Lambda layer may be less straightforward. If you need the capability, though, it is easy to install.
|
|
104
105
|
|
|
106
|
+
|
|
107
|
+
<a name="pdocs"></a>
|
|
108
|
+
# Python Interface Docs
|
|
109
|
+
<a href='https://csvpath.github.io/csvpath/' target='_blank'>Python docs are here</a>.
|
|
110
|
+
The CsvPath Framework's public interface is streamlined. csvpath.CsvPath and csvpath.CsvPaths are where most of the magic happens. Docs for deeper levels will be added over time.
|
|
111
|
+
|
|
105
112
|
# Description
|
|
106
113
|
<a name="description"></a>
|
|
107
114
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The CsvPath Framework makes it easy to pre-board external data files. It sits between Managed File Transfer and the data lake or applications. CsvPath provides durable dataset identification, validation and canonicalization, and stages data for internal use as a known-good raw data source. The goal is to automate the pre-boarding process.
|
|
3
|
+
|
|
4
|
+
CsvPath Language is the core validation and canonicalization engine of the Framework. The validation files can be developed without coding using the CLI. When you are ready to automate pre-boarding you will use the classes documented here, in particular csvpath.CsvPath, csvpath.CsvPaths, and the managers in csvpath.managers:
|
|
5
|
+
|
|
6
|
+
- csvpath.managers.files.file_manager
|
|
7
|
+
- csvpath.managers.paths.paths_manager
|
|
8
|
+
- csvpath.managers.results.results_manager
|
|
9
|
+
|
|
10
|
+
You access the managers from a csvpath.CsvPaths instance. You should not construct your own.
|
|
11
|
+
|
|
12
|
+
There are many other classes you could potentially use in some specific and narrow cases, such as building a new integration, a new function, or a new type of printer. But for 99% of automation use cases these classes are all you need.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from csvpath.csvpath import CsvPath
|
|
16
|
+
from csvpath.csvpaths import CsvPaths
|
|
17
|
+
|
|
18
|
+
__all__ = ["CsvPath", "CsvPaths"]
|
|
@@ -14,7 +14,7 @@ from prompt_toolkit.completion import WordCompleter
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Asker:
|
|
17
|
-
def __init__(self, cli, *, name_type) -> None:
|
|
17
|
+
def __init__(self, cli, *, name_type, prompt=None) -> None:
|
|
18
18
|
self._cli = cli
|
|
19
19
|
names = None
|
|
20
20
|
self.name_type = name_type
|
|
@@ -24,18 +24,24 @@ class Asker:
|
|
|
24
24
|
elif name_type == "paths":
|
|
25
25
|
names = self._cli.csvpaths.paths_manager.named_paths_names
|
|
26
26
|
names.sort()
|
|
27
|
+
elif name_type == "none":
|
|
28
|
+
names = []
|
|
27
29
|
else:
|
|
28
30
|
raise ValueError("Name type must be files or paths")
|
|
29
31
|
self.completer = WordCompleter(names, ignore_case=True)
|
|
30
32
|
self.result = None
|
|
33
|
+
self.prompt = prompt
|
|
31
34
|
|
|
32
35
|
def create_prompt_application(self, prompt_text=None):
|
|
33
36
|
if prompt_text is None:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if self.prompt is None:
|
|
38
|
+
prompt_text = (
|
|
39
|
+
"Named-file name? "
|
|
40
|
+
if self.name_type == "files"
|
|
41
|
+
else "Named-paths name? "
|
|
42
|
+
)
|
|
43
|
+
else:
|
|
44
|
+
prompt_text = self.prompt
|
|
39
45
|
# Create a buffer to store input
|
|
40
46
|
buffer = Buffer(completer=self.completer, complete_while_typing=True)
|
|
41
47
|
# Create key bindings
|
|
@@ -83,8 +89,9 @@ class Asker:
|
|
|
83
89
|
# complete_while_typing=True
|
|
84
90
|
)
|
|
85
91
|
|
|
86
|
-
def ask(self) -> str:
|
|
92
|
+
def ask(self, prompt=None) -> str:
|
|
87
93
|
try:
|
|
94
|
+
self.prompt = prompt
|
|
88
95
|
app = self.create_prompt_application()
|
|
89
96
|
app.run()
|
|
90
97
|
return self.result
|
|
@@ -6,13 +6,18 @@ from csvpath import CsvPaths
|
|
|
6
6
|
from .drill_down import DrillDown
|
|
7
7
|
from .selecter import Selecter
|
|
8
8
|
from .debug_config import DebugConfig
|
|
9
|
+
from csvpath.util.nos import Nos
|
|
10
|
+
from .asker import Asker
|
|
11
|
+
from .function_lister import FunctionLister
|
|
12
|
+
from .const import Const
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
class Cli:
|
|
12
16
|
def __init__(self):
|
|
13
17
|
self.csvpaths = CsvPaths()
|
|
14
18
|
self.clear()
|
|
15
|
-
|
|
19
|
+
"""
|
|
20
|
+
splash = ""
|
|
16
21
|
*** * ****** ** **
|
|
17
22
|
*** ** * ** ** **** **
|
|
18
23
|
** ** ** * ** *** ***** ** *****
|
|
@@ -24,7 +29,7 @@ CsvPath Command Line Interface
|
|
|
24
29
|
Try tab completion and menu-by-key.
|
|
25
30
|
For help see https://www.csvpath.org
|
|
26
31
|
"""
|
|
27
|
-
print(
|
|
32
|
+
print(Const.SPLASH)
|
|
28
33
|
self._return_to_cont()
|
|
29
34
|
self.clear()
|
|
30
35
|
|
|
@@ -38,33 +43,33 @@ For help see https://www.csvpath.org
|
|
|
38
43
|
time.sleep(0.5)
|
|
39
44
|
|
|
40
45
|
ITALIC = "\033[3m"
|
|
41
|
-
SIDEBAR_COLOR = "\033[36m"
|
|
42
|
-
REVERT = "\033[0m"
|
|
43
|
-
STOP_HERE = f"{SIDEBAR_COLOR}{ITALIC}... done picking dir{REVERT}"
|
|
44
|
-
STOP_HERE2 = "👍 pick this dir"
|
|
45
|
-
CANCEL = f"{SIDEBAR_COLOR}{ITALIC}... cancel{REVERT}"
|
|
46
|
-
CANCEL2 = "← cancel"
|
|
47
|
-
QUIT = "← quit"
|
|
48
|
-
NAMED_FILES = "register data"
|
|
49
|
-
NAMED_PATHS = "load csvpaths"
|
|
50
|
-
ARCHIVE = "access the archive"
|
|
46
|
+
# SIDEBAR_COLOR = "\033[36m"
|
|
47
|
+
# REVERT = "\033[0m"
|
|
48
|
+
# STOP_HERE = f"{Const.SIDEBAR_COLOR}{ITALIC}... done picking dir{Const.REVERT}"
|
|
49
|
+
# STOP_HERE2 = "👍 pick this dir"
|
|
50
|
+
# CANCEL = f"{Const.SIDEBAR_COLOR}{ITALIC}... cancel{Const.REVERT}"
|
|
51
|
+
# CANCEL2 = "← cancel"
|
|
52
|
+
# QUIT = "← quit"
|
|
53
|
+
# NAMED_FILES = "register data"
|
|
54
|
+
# NAMED_PATHS = "load csvpaths"
|
|
55
|
+
# ARCHIVE = "access the archive"
|
|
51
56
|
|
|
52
57
|
def _return_to_cont(self):
|
|
53
58
|
print(
|
|
54
|
-
f"\n{
|
|
59
|
+
f"\n{Const.SIDEBAR_COLOR}{Cli.ITALIC}... Hit return to continue{Const.REVERT}\n"
|
|
55
60
|
)
|
|
56
61
|
self._input("")
|
|
57
62
|
|
|
58
63
|
def _response(self, text: str) -> None:
|
|
59
|
-
sys.stdout.write(f"\u001b[30;1m{text}{
|
|
64
|
+
sys.stdout.write(f"\u001b[30;1m{text}{Const.REVERT}\n")
|
|
60
65
|
|
|
61
66
|
def action(self, text: str) -> None:
|
|
62
|
-
sys.stdout.write(f"\033[36m{text}{
|
|
67
|
+
sys.stdout.write(f"\033[36m{text}{Const.REVERT}\n")
|
|
63
68
|
|
|
64
69
|
def _input(self, prompt: str) -> str:
|
|
65
70
|
try:
|
|
66
71
|
response = input(f"{prompt}\033[93m")
|
|
67
|
-
sys.stdout.write(
|
|
72
|
+
sys.stdout.write(Const.REVERT)
|
|
68
73
|
return response.strip()
|
|
69
74
|
except KeyboardInterrupt:
|
|
70
75
|
return "cancel"
|
|
@@ -78,12 +83,12 @@ For help see https://www.csvpath.org
|
|
|
78
83
|
return
|
|
79
84
|
if q is not None:
|
|
80
85
|
print(q)
|
|
81
|
-
if choices[len(choices) - 1] ==
|
|
82
|
-
choices[len(choices) - 1] =
|
|
83
|
-
if choices[len(choices) - 2] ==
|
|
84
|
-
choices[len(choices) - 2] =
|
|
86
|
+
if choices[len(choices) - 1] == Const.CANCEL:
|
|
87
|
+
choices[len(choices) - 1] = Const.CANCEL2
|
|
88
|
+
if choices[len(choices) - 2] == Const.STOP_HERE:
|
|
89
|
+
choices[len(choices) - 2] = Const.STOP_HERE2
|
|
85
90
|
cs = [(s, s) for s in choices]
|
|
86
|
-
t = Selecter().ask(title="", values=cs, cancel_value=
|
|
91
|
+
t = Selecter().ask(title="", values=cs, cancel_value=Const.CANCEL)
|
|
87
92
|
self.clear()
|
|
88
93
|
return t
|
|
89
94
|
|
|
@@ -92,47 +97,53 @@ For help see https://www.csvpath.org
|
|
|
92
97
|
t = None
|
|
93
98
|
try:
|
|
94
99
|
choices = [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
Const.NAMED_FILES,
|
|
101
|
+
Const.NAMED_PATHS,
|
|
102
|
+
Const.ARCHIVE,
|
|
98
103
|
"run",
|
|
99
104
|
"config",
|
|
100
|
-
|
|
105
|
+
"functions",
|
|
106
|
+
Const.QUIT,
|
|
101
107
|
]
|
|
102
108
|
t = self.ask(choices)
|
|
103
109
|
except KeyboardInterrupt:
|
|
104
110
|
self.end()
|
|
105
111
|
return
|
|
106
112
|
t = self._do(t)
|
|
107
|
-
if t ==
|
|
113
|
+
if t == Const.QUIT:
|
|
108
114
|
self.end()
|
|
109
115
|
return
|
|
110
116
|
|
|
111
117
|
def _do(self, t: str) -> str | None:
|
|
112
|
-
if t ==
|
|
118
|
+
if t == Const.QUIT:
|
|
113
119
|
return t
|
|
114
120
|
try:
|
|
115
121
|
if t == "run":
|
|
116
122
|
self.run()
|
|
117
|
-
if t ==
|
|
123
|
+
if t == Const.NAMED_FILES:
|
|
118
124
|
self._files()
|
|
119
|
-
if t ==
|
|
125
|
+
if t == Const.NAMED_PATHS:
|
|
120
126
|
self._paths()
|
|
121
|
-
if t ==
|
|
127
|
+
if t == Const.ARCHIVE:
|
|
122
128
|
self._results()
|
|
123
129
|
if t == "config":
|
|
124
130
|
self._config()
|
|
131
|
+
if t == "functions":
|
|
132
|
+
self._functions()
|
|
125
133
|
except KeyboardInterrupt:
|
|
126
|
-
return
|
|
134
|
+
return Const.QUIT
|
|
127
135
|
except Exception:
|
|
128
136
|
print(traceback.format_exc())
|
|
129
137
|
self._return_to_cont()
|
|
130
138
|
|
|
139
|
+
def _functions(self) -> None:
|
|
140
|
+
FunctionLister(self).list_functions()
|
|
141
|
+
|
|
131
142
|
def _config(self) -> None:
|
|
132
143
|
DebugConfig(self).show()
|
|
133
144
|
|
|
134
145
|
def _files(self) -> None:
|
|
135
|
-
choices = ["add named-file", "list named-files",
|
|
146
|
+
choices = ["add named-file", "list named-files", Const.CANCEL2]
|
|
136
147
|
t = self.ask(choices)
|
|
137
148
|
if t == "add named-file":
|
|
138
149
|
DrillDown(self).name_file()
|
|
@@ -140,7 +151,7 @@ For help see https://www.csvpath.org
|
|
|
140
151
|
self.list_named_files()
|
|
141
152
|
|
|
142
153
|
def _paths(self) -> None:
|
|
143
|
-
choices = ["add named-paths", "list named-paths",
|
|
154
|
+
choices = ["add named-paths", "list named-paths", Const.CANCEL2]
|
|
144
155
|
t = self.ask(choices)
|
|
145
156
|
if t == "add named-paths":
|
|
146
157
|
DrillDown(self).name_paths()
|
|
@@ -148,7 +159,7 @@ For help see https://www.csvpath.org
|
|
|
148
159
|
self.list_named_paths()
|
|
149
160
|
|
|
150
161
|
def _results(self) -> None:
|
|
151
|
-
choices = ["open named-result", "list named-results",
|
|
162
|
+
choices = ["open named-result", "list named-results", Const.CANCEL2]
|
|
152
163
|
t = self.ask(choices)
|
|
153
164
|
if t == "open named-result":
|
|
154
165
|
self.open_named_result()
|
|
@@ -171,14 +182,17 @@ For help see https://www.csvpath.org
|
|
|
171
182
|
names = self.csvpaths.results_manager.list_named_results()
|
|
172
183
|
names = [n for n in names if n.find(".") == -1]
|
|
173
184
|
print(f"{len(names)} named-results names:")
|
|
174
|
-
names.append(
|
|
185
|
+
names.append(Const.CANCEL)
|
|
175
186
|
t = self.ask(names)
|
|
176
|
-
if t ==
|
|
187
|
+
if t == Const.CANCEL:
|
|
177
188
|
return
|
|
178
189
|
t = f"{self.csvpaths.config.archive_path}{os.sep}{t}"
|
|
179
190
|
self.action(f"Opening results at {t}...")
|
|
180
191
|
self.short_pause()
|
|
181
|
-
|
|
192
|
+
#
|
|
193
|
+
# not sure if this works for the linux desktop user
|
|
194
|
+
#
|
|
195
|
+
c = f"open {t}" if os.sep == "/" else f"explorer {t}"
|
|
182
196
|
os.system(c)
|
|
183
197
|
except Exception:
|
|
184
198
|
print(traceback.format_exc())
|
|
@@ -208,19 +222,42 @@ For help see https://www.csvpath.org
|
|
|
208
222
|
input("You must add a named-file. Press any key to continue.")
|
|
209
223
|
return
|
|
210
224
|
files.sort()
|
|
211
|
-
file = self.ask(
|
|
225
|
+
file = self.ask(
|
|
226
|
+
files, q="What named-file? \n(enter $ on any line to build a reference) "
|
|
227
|
+
)
|
|
228
|
+
#
|
|
229
|
+
# if '$' user wants to use a reference, possibly for replay
|
|
230
|
+
#
|
|
231
|
+
if file.startswith("$"):
|
|
232
|
+
# find the run and instance
|
|
233
|
+
file = self.complete_file_reference()
|
|
234
|
+
if file is None:
|
|
235
|
+
input(
|
|
236
|
+
"Could not build the reference. Check if all files are present. Press any key to continue."
|
|
237
|
+
)
|
|
238
|
+
return
|
|
239
|
+
|
|
212
240
|
self.clear()
|
|
213
241
|
allpaths = self.csvpaths.paths_manager.named_paths_names
|
|
214
242
|
if len(allpaths) == 0:
|
|
215
243
|
input("You must add a named-paths file. Press any key to continue.")
|
|
216
244
|
return
|
|
217
245
|
allpaths.sort()
|
|
218
|
-
paths = self.ask(
|
|
246
|
+
paths = self.ask(
|
|
247
|
+
allpaths,
|
|
248
|
+
q="What named-paths? \n(enter $ on any line to build a reference) ",
|
|
249
|
+
)
|
|
250
|
+
#
|
|
251
|
+
# if '$' user wants to use a reference to rewind
|
|
252
|
+
#
|
|
253
|
+
if paths.startswith("$"):
|
|
254
|
+
paths = self.complete_paths_reference(paths)
|
|
255
|
+
|
|
219
256
|
self.clear()
|
|
220
|
-
choices = ["collect", "fast-forward",
|
|
257
|
+
choices = ["collect", "fast-forward", Const.CANCEL2]
|
|
221
258
|
method = self.ask(choices, q="What method? ")
|
|
222
259
|
self.clear()
|
|
223
|
-
if method ==
|
|
260
|
+
if method == Const.CANCEL2:
|
|
224
261
|
return
|
|
225
262
|
self.action(f"Running {paths} against {file} using {method}\n")
|
|
226
263
|
self.pause()
|
|
@@ -249,6 +286,48 @@ For help see https://www.csvpath.org
|
|
|
249
286
|
self.clear()
|
|
250
287
|
self._return_to_cont()
|
|
251
288
|
|
|
289
|
+
def complete_file_reference(self) -> str:
|
|
290
|
+
allpaths = self.csvpaths.paths_manager.named_paths_names
|
|
291
|
+
allpaths.sort()
|
|
292
|
+
file = self.ask(allpaths, q="Building a reference. Use what results? ")
|
|
293
|
+
file = file.lstrip("$")
|
|
294
|
+
results = self.csvpaths.config.get(section="results", name="archive")
|
|
295
|
+
results = f"{results}{os.sep}{file}"
|
|
296
|
+
if not Nos(results).dir_exists():
|
|
297
|
+
return None
|
|
298
|
+
runs = Nos(results).listdir()
|
|
299
|
+
runs.sort()
|
|
300
|
+
run = self.ask(runs, q="Which run? ")
|
|
301
|
+
run = run.lstrip("$")
|
|
302
|
+
results = f"{results}{os.sep}{run}"
|
|
303
|
+
instances = Nos(results).listdir()
|
|
304
|
+
instances = [i for i in instances if i.find(".json") == -1]
|
|
305
|
+
instance = self.ask(instances, q="Which csvpath? ")
|
|
306
|
+
instance = instance.lstrip("$")
|
|
307
|
+
return f"${file}.results.{run}.{instance}"
|
|
308
|
+
|
|
309
|
+
def complete_paths_reference(self, paths) -> str:
|
|
310
|
+
allpaths = self.csvpaths.paths_manager.named_paths_names
|
|
311
|
+
allpaths.sort()
|
|
312
|
+
path = self.ask(allpaths, q="Building a reference. Use what paths? ")
|
|
313
|
+
path = path.lstrip("$")
|
|
314
|
+
instances = self.csvpaths.paths_manager.get_identified_paths_in(path)
|
|
315
|
+
ids = [i[0] for i in instances]
|
|
316
|
+
run = self.ask(ids, q="Which csvpath? ")
|
|
317
|
+
run = run.lstrip("$")
|
|
318
|
+
# ft = Asker(self, name_type="none").ask("from:, to:, or neither? ")
|
|
319
|
+
ft = self.ask(
|
|
320
|
+
["from", "to", "neither"], q=f"Limit csvpaths in group relative to {run}? "
|
|
321
|
+
)
|
|
322
|
+
ft = ft.lstrip("$")
|
|
323
|
+
ft = ft.replace(":", "")
|
|
324
|
+
ft = ft.strip()
|
|
325
|
+
if ft in ["from", "to"]:
|
|
326
|
+
ft = f":{ft}"
|
|
327
|
+
else:
|
|
328
|
+
ft = ""
|
|
329
|
+
return f"${path}.csvpaths.{run}{ft}"
|
|
330
|
+
|
|
252
331
|
|
|
253
332
|
def run():
|
|
254
333
|
cli = Cli()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class Const:
|
|
2
|
+
|
|
3
|
+
SPLASH = """
|
|
4
|
+
*** * ****** ** **
|
|
5
|
+
*** ** * ** ** **** **
|
|
6
|
+
** ** ** * ** *** ***** ** *****
|
|
7
|
+
** * **** **** ***** *** ** ** ** **
|
|
8
|
+
** **** ****** ** ** ** *** ** ** **
|
|
9
|
+
*** **** * ** *** ** **** **
|
|
10
|
+
***************************
|
|
11
|
+
CsvPath Command Line Interface
|
|
12
|
+
Try tab completion and menu-by-key.
|
|
13
|
+
For help see https://www.csvpath.org
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
ITALIC = "\033[3m"
|
|
17
|
+
SIDEBAR_COLOR = "\033[36m"
|
|
18
|
+
REVERT = "\033[0m"
|
|
19
|
+
STOP_HERE = f"{SIDEBAR_COLOR}{ITALIC}... done picking dir{REVERT}"
|
|
20
|
+
STOP_HERE2 = "👍 pick this dir"
|
|
21
|
+
CANCEL = f"{SIDEBAR_COLOR}{ITALIC}... cancel{REVERT}"
|
|
22
|
+
CANCEL2 = "← cancel"
|
|
23
|
+
QUIT = "← quit"
|
|
24
|
+
NAMED_FILES = "register data"
|
|
25
|
+
NAMED_PATHS = "load csvpaths"
|
|
26
|
+
ARCHIVE = "access the archive"
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import traceback
|
|
3
3
|
from .debug_config import DebugConfig
|
|
4
4
|
from .asker import Asker
|
|
5
|
+
from .const import Const
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class DrillDown:
|
|
@@ -16,14 +17,16 @@ class DrillDown:
|
|
|
16
17
|
#
|
|
17
18
|
# get name
|
|
18
19
|
#
|
|
20
|
+
t = self._get_add_type()
|
|
21
|
+
if t == Const.CANCEL2:
|
|
22
|
+
return
|
|
19
23
|
self._cli.clear()
|
|
20
|
-
name =
|
|
24
|
+
name = None
|
|
25
|
+
if t == "file":
|
|
26
|
+
name = Asker(self._cli, name_type="files").ask()
|
|
21
27
|
#
|
|
22
28
|
# get path
|
|
23
29
|
#
|
|
24
|
-
t = self._get_add_type()
|
|
25
|
-
if t == self._cli.CANCEL2:
|
|
26
|
-
return
|
|
27
30
|
p = self._get_path(t, self._cli.csvpaths.config.csv_file_extensions)
|
|
28
31
|
if p is False:
|
|
29
32
|
return
|
|
@@ -63,17 +66,19 @@ class DrillDown:
|
|
|
63
66
|
# ============================
|
|
64
67
|
|
|
65
68
|
def name_paths(self):
|
|
69
|
+
t = self._get_add_type()
|
|
70
|
+
if t == Const.CANCEL2:
|
|
71
|
+
return
|
|
66
72
|
#
|
|
67
73
|
# get name
|
|
68
74
|
#
|
|
69
75
|
self._cli.clear()
|
|
70
|
-
name =
|
|
76
|
+
name = None
|
|
77
|
+
if t == "file":
|
|
78
|
+
name = Asker(self._cli, name_type="paths").ask()
|
|
71
79
|
#
|
|
72
80
|
# get path
|
|
73
81
|
#
|
|
74
|
-
t = self._get_add_type()
|
|
75
|
-
if t == self._cli.CANCEL2:
|
|
76
|
-
return
|
|
77
82
|
exts = self._cli.csvpaths.config.csvpath_file_extensions
|
|
78
83
|
p = self._get_path(t, exts)
|
|
79
84
|
if p is False:
|
|
@@ -145,7 +150,7 @@ class DrillDown:
|
|
|
145
150
|
|
|
146
151
|
def _get_add_type(self) -> str:
|
|
147
152
|
self._cli.clear()
|
|
148
|
-
choices = ["dir", "file", "json",
|
|
153
|
+
choices = ["dir", "file", "json", Const.CANCEL2]
|
|
149
154
|
t = None
|
|
150
155
|
t = self._cli.ask(choices)
|
|
151
156
|
return t
|
|
@@ -160,9 +165,9 @@ class DrillDown:
|
|
|
160
165
|
names.sort()
|
|
161
166
|
names = self._decorate(path, names, select_dir=dir_only)
|
|
162
167
|
t = self._cli.ask(names)
|
|
163
|
-
if t in [
|
|
168
|
+
if t in [Const.STOP_HERE, Const.STOP_HERE2]:
|
|
164
169
|
return (path, True)
|
|
165
|
-
if t in [
|
|
170
|
+
if t in [Const.CANCEL, Const.CANCEL2]:
|
|
166
171
|
return (path, False)
|
|
167
172
|
if t.startswith("📂 ") or t.startswith("📄 "):
|
|
168
173
|
t = t[2:]
|
|
@@ -171,7 +176,7 @@ class DrillDown:
|
|
|
171
176
|
def _decorate(self, path, names, select_dir=False) -> list[str]:
|
|
172
177
|
ns = []
|
|
173
178
|
for n in names:
|
|
174
|
-
if n in [
|
|
179
|
+
if n in [Const.STOP_HERE, Const.STOP_HERE2]:
|
|
175
180
|
pass
|
|
176
181
|
elif os.path.isfile(os.path.join(path, n)):
|
|
177
182
|
n = f"📄 {n}"
|
|
@@ -179,8 +184,8 @@ class DrillDown:
|
|
|
179
184
|
n = f"📂 {n}"
|
|
180
185
|
ns.append(n)
|
|
181
186
|
if select_dir is True:
|
|
182
|
-
ns.append(
|
|
183
|
-
ns.append(
|
|
187
|
+
ns.append(Const.STOP_HERE)
|
|
188
|
+
ns.append(Const.CANCEL)
|
|
184
189
|
return ns
|
|
185
190
|
|
|
186
191
|
def _filter_hidden(self, names) -> list[str]:
|