csvpath 0.0.533__tar.gz → 0.0.534__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.533 → csvpath-0.0.534}/PKG-INFO +5 -2
- {csvpath-0.0.533 → csvpath-0.0.534/assets}/config/config.ini +13 -2
- csvpath-0.0.534/assets/config/jenkins-local-filesystem-mysql.ini +138 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-local-gcs.ini +1 -1
- {csvpath-0.0.533/assets → csvpath-0.0.534}/config/config.ini +13 -2
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/files/file_manager.py +3 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/files/file_metadata.py +1 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/files/file_registrar.py +7 -1
- csvpath-0.0.534/csvpath/managers/integrations/sql/engine.py +24 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/sql_file_listener.py +85 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/sql_listener.py +29 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/sql_paths_listener.py +78 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/sql_result_listener.py +100 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/sql_results_listener.py +115 -0
- csvpath-0.0.534/csvpath/managers/integrations/sql/tables.py +185 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +1 -1
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/metadata.py +7 -4
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/result_serializer.py +1 -1
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/results_metadata.py +1 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/config.py +13 -2
- {csvpath-0.0.533 → csvpath-0.0.534}/pyproject.toml +5 -2
- {csvpath-0.0.533 → csvpath-0.0.534}/LICENSE +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/README.md +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/function.imports +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-local-azure.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-local-filesystem.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-local-sftp.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-s3.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-windows-azure.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-windows-local.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/jenkins-windows-sftp.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/config/local-localhost-sftp.ini +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sqlite/csvpath +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/assets/integrations/sqlite/schema.sql +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/asker.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/cli.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/const.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/debug_config.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/drill_down.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/function_describer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/function_lister.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/cli/selecter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/csvpath.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/csvpaths.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/errors/error.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/errors/error_collector.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/errors/error_comms.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/errors/error_manager.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/files/files_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ckan/ckan.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ckan/datafile.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ckan/dataset.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/event.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/event_result.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/job.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/run.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/run_state.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/ol/sender.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/metrics.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/slack/event.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/slack/sender.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/paths/paths_listener.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/paths/paths_manager.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/paths/paths_metadata.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/paths/paths_registrar.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/registrar.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/readers/readers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/result.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/result_file_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/result_metadata.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/result_registrar.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/results_manager.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/results/results_registrar.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/run/run_listener_stdout.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/run/run_metadata.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/managers/run/run_registrar.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/args.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/args_helper.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/notf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/count.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/count_bytes.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/counter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/increment.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/tally.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/function.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/function_factory.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/function_finder.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/append.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/insert.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/headers/reset_headers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/dups.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/first.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/lines/stop.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/intf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/odd.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/subtotal.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/math/sum.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/misc/fingerprint.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/misc/random.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/print/printf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/stats/minf.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/stats/percent_unique.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/alter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/caps.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/contains.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/regex.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/boolean.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/datef.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/decimal.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/email.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/nonef.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/string.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/type.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/types/url.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/validity/line.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/variables/pushpop.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/variables/track.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/matchable.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/qualified.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/matching/util/runtime_data_collector.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/error_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/explain_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/files_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/logic_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/mode_controller.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/print_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/return_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/run_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/source_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/transfer_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/unmatched_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/modes/validation_mode.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/__init__.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/exceptions.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/parser.out +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/parsetab.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/scanner.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/scanning/scanning_lexer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_data_writer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_fingerprinter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_nos.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_utils.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/box.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/caser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/class_loader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/code.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/file_info.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/file_readers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/file_writers.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_data_writer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_nos.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_utils.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/hasher.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/http/http_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/intermediary.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/line_spooler.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/nos.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/pandas_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/path_util.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/reference_finder.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/reference_parser.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_data_writer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_fingerprinter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_nos.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_utils.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_config.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_data_writer.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_nos.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/sqliter.py +0 -0
- {csvpath-0.0.533 → csvpath-0.0.534}/csvpath/util/var_utility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: csvpath
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.534
|
|
4
4
|
Summary: A data preboarding framework for managing and validating CSV, Excel, and other tabular data files using a Collect, Store, Validate, Publish pattern to create a trusted publisher for downstream data consumers.
|
|
5
5
|
Author: David Kershaw
|
|
6
6
|
Author-email: dk107dk@hotmail.com
|
|
@@ -27,22 +27,25 @@ Requires-Dist: ckanapi (>=4.8,<5.0)
|
|
|
27
27
|
Requires-Dist: email-validator (>=2.2.0,<3.0.0)
|
|
28
28
|
Requires-Dist: google-cloud-storage (>=3.1.0,<4.0.0)
|
|
29
29
|
Requires-Dist: inflect (>=7.4.0,<8.0.0)
|
|
30
|
-
Requires-Dist: jinja2 (>=3.1.
|
|
30
|
+
Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
|
|
31
31
|
Requires-Dist: lark (>=1.2.2,<2.0.0)
|
|
32
32
|
Requires-Dist: marquez-python (>=0.50.0,<0.51.0)
|
|
33
33
|
Requires-Dist: metaphone (>=0.6,<0.7)
|
|
34
|
+
Requires-Dist: mysqlclient (>=2.2.7,<3.0.0)
|
|
34
35
|
Requires-Dist: openlineage-python (>=1.25.0,<2.0.0)
|
|
35
36
|
Requires-Dist: opentelemetry-distro[otlp] (>=0.50b0,<0.51)
|
|
36
37
|
Requires-Dist: paramiko (>=3.5.0,<4.0.0)
|
|
37
38
|
Requires-Dist: pdoc (>=15.0.1,<16.0.0)
|
|
38
39
|
Requires-Dist: ply (>=3.11,<4.0)
|
|
39
40
|
Requires-Dist: prompt-toolkit (>=3.0.50,<4.0.0)
|
|
41
|
+
Requires-Dist: psycopg2-binary (>=2.9.10,<3.0.0)
|
|
40
42
|
Requires-Dist: pylightxl (>=1.61,<2.0)
|
|
41
43
|
Requires-Dist: pytest (>=8.3.3,<9.0.0)
|
|
42
44
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
|
43
45
|
Requires-Dist: pytz (>=2024.2,<2025.0)
|
|
44
46
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
45
47
|
Requires-Dist: smart-open (>=7.1.0,<8.0.0)
|
|
48
|
+
Requires-Dist: sqlalchemy (>=2.0.38,<3.0.0)
|
|
46
49
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
47
50
|
Requires-Dist: validators (>=0.34.0,<0.35.0)
|
|
48
51
|
Project-URL: Csvpath.org, https://www.csvpath.org
|
|
@@ -33,9 +33,9 @@ archive = archive
|
|
|
33
33
|
|
|
34
34
|
[inputs]
|
|
35
35
|
files = inputs/named_files
|
|
36
|
+
csvpaths = inputs/named_paths
|
|
36
37
|
#csvpaths = s3://csvpath-example-1/inputs/named_paths
|
|
37
38
|
#files = sftp://172.17.0.3:10022/inputs/named_files
|
|
38
|
-
|
|
39
39
|
on_unmatched_file_fingerprints = halt
|
|
40
40
|
|
|
41
41
|
#
|
|
@@ -46,7 +46,13 @@ on_unmatched_file_fingerprints = halt
|
|
|
46
46
|
groups =
|
|
47
47
|
#slack, marquez, ckan, sftp, sftpplus, otlp, default, sqlite
|
|
48
48
|
|
|
49
|
-
# add
|
|
49
|
+
# add sql to capture staging, loads, and results in mysql, postgres, ms sql server, or sqlite
|
|
50
|
+
sql.file = from csvpath.managers.integrations.sql.sql_file_listener import SqlFileListener
|
|
51
|
+
sql.paths = from csvpath.managers.integrations.sql.sql_paths_listener import SqlPathsListener
|
|
52
|
+
sql.result = from csvpath.managers.integrations.sql.sql_result_listener import SqlResultListener
|
|
53
|
+
sql.results = from csvpath.managers.integrations.sql.sql_results_listener import SqlResultsListener
|
|
54
|
+
|
|
55
|
+
# add sqlite to capture staging, loads, and results in a local sqlite file
|
|
50
56
|
sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
|
|
51
57
|
sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
|
|
52
58
|
|
|
@@ -99,6 +105,11 @@ password = tinpenny
|
|
|
99
105
|
[sqlite]
|
|
100
106
|
db = archive/csvpath.db
|
|
101
107
|
|
|
108
|
+
[sql]
|
|
109
|
+
# sqlite, mysql, postgres, or sql_server
|
|
110
|
+
dialect = sqlite
|
|
111
|
+
connection_string = sqlite:///archive/csvpath-sqlite.db
|
|
112
|
+
|
|
102
113
|
[sftpplus]
|
|
103
114
|
# these are only needed by the csvpath writer
|
|
104
115
|
mailbox_user = MAILBOX_USER
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
[csvpath_files]
|
|
2
|
+
extensions = txt, csvpath, csvpaths
|
|
3
|
+
|
|
4
|
+
[csv_files]
|
|
5
|
+
extensions = txt, csv, tsv, dat, tab, psv, ssv
|
|
6
|
+
|
|
7
|
+
[errors]
|
|
8
|
+
csvpath = raise, collect, stop, fail, print
|
|
9
|
+
csvpaths = raise, collect
|
|
10
|
+
use_format = full
|
|
11
|
+
pattern = {time}:{file}:{line}:{paths}:{instance}:{chain}: {message}
|
|
12
|
+
|
|
13
|
+
[logging]
|
|
14
|
+
csvpath = debug
|
|
15
|
+
csvpaths = debug
|
|
16
|
+
log_file = logs/csvpath.log
|
|
17
|
+
log_files_to_keep = 100
|
|
18
|
+
log_file_size = 52428800
|
|
19
|
+
|
|
20
|
+
[config]
|
|
21
|
+
path = assets/config/jenkins-local-filesystem.ini
|
|
22
|
+
|
|
23
|
+
[cache]
|
|
24
|
+
path = cache
|
|
25
|
+
use_cache = no
|
|
26
|
+
|
|
27
|
+
[functions]
|
|
28
|
+
imports = config/functions.imports
|
|
29
|
+
|
|
30
|
+
[results]
|
|
31
|
+
archive = archive
|
|
32
|
+
|
|
33
|
+
[inputs]
|
|
34
|
+
files = inputs/named_files
|
|
35
|
+
csvpaths = inputs/named_paths
|
|
36
|
+
on_unmatched_file_fingerprints = halt
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# integrations activation
|
|
40
|
+
#
|
|
41
|
+
|
|
42
|
+
[listeners]
|
|
43
|
+
groups = sql
|
|
44
|
+
#slack, marquez, ckan, sftp, sftpplus, otlp, default, sqlite
|
|
45
|
+
|
|
46
|
+
sql.file = from csvpath.managers.integrations.sql.sql_file_listener import SqlFileListener
|
|
47
|
+
sql.paths = from csvpath.managers.integrations.sql.sql_paths_listener import SqlPathsListener
|
|
48
|
+
sql.result = from csvpath.managers.integrations.sql.sql_result_listener import SqlResultListener
|
|
49
|
+
sql.results = from csvpath.managers.integrations.sql.sql_results_listener import SqlResultsListener
|
|
50
|
+
|
|
51
|
+
# add sqlite to capture staging, loads, and results in a local sqlite db
|
|
52
|
+
sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
|
|
53
|
+
sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
|
|
54
|
+
|
|
55
|
+
# these simple default listeners track all files staged and all paths loaded in
|
|
56
|
+
# central manifests. unlike other manifest writers, if they have multiple
|
|
57
|
+
# concurrent users they have potential a race condition. users that do not
|
|
58
|
+
# share inputs directories do not need to worry about this. you should vet
|
|
59
|
+
# using them against your use case; potential utility vs. the modest but non-0
|
|
60
|
+
# risk of lost updates. they can be disabled with little loss of function.
|
|
61
|
+
# alternatively a database-backed version may be more suitable.
|
|
62
|
+
default.file = from csvpath.managers.files.files_listener import FilesListener
|
|
63
|
+
default.paths = from csvpath.managers.paths.paths_listener import PathsListener
|
|
64
|
+
|
|
65
|
+
# add otlp to support any OpenTelemetry backend
|
|
66
|
+
otlp.result = from csvpath.managers.integrations.otlp.otlp_result_listener import OpenTelemetryResultListener
|
|
67
|
+
otlp.results = from csvpath.managers.integrations.otlp.otlp_results_listener import OpenTelemetryResultsListener
|
|
68
|
+
otlp.errors = from csvpath.managers.integrations.otlp.otlp_error_listener import OpenTelemetryErrorListener
|
|
69
|
+
|
|
70
|
+
# add sftpplus to the list of groups above to automate registration and named-paths group runs on file arrival at an SFTPPlus server
|
|
71
|
+
sftpplus.paths = from csvpath.managers.integrations.sftpplus.sftpplus_listener import SftpPlusListener
|
|
72
|
+
|
|
73
|
+
# add sftp to the list of groups above to push results to an sftp account
|
|
74
|
+
sftp.results = from csvpath.managers.integrations.sftp.sftp_listener import SftpListener
|
|
75
|
+
|
|
76
|
+
# add ckan to the list of groups above for alerts to slack webhooks
|
|
77
|
+
ckan.results = from csvpath.managers.integrations.ckan.ckan_listener import CkanListener
|
|
78
|
+
|
|
79
|
+
#add marquez to the list of groups above for OpenLineage events to a Marquez server
|
|
80
|
+
marquez.file = from csvpath.managers.integrations.ol.file_listener_ol import OpenLineageFileListener
|
|
81
|
+
marquez.paths = from csvpath.managers.integrations.ol.paths_listener_ol import OpenLineagePathsListener
|
|
82
|
+
marquez.result = from csvpath.managers.integrations.ol.result_listener_ol import OpenLineageResultListener
|
|
83
|
+
marquez.results = from csvpath.managers.integrations.ol.results_listener_ol import OpenLineageResultsListener
|
|
84
|
+
|
|
85
|
+
# add slack to the list of groups above for alerts to slack webhooks
|
|
86
|
+
slack.file = from csvpath.managers.integrations.slack.sender import SlackSender
|
|
87
|
+
slack.paths = from csvpath.managers.integrations.slack.sender import SlackSender
|
|
88
|
+
slack.result = from csvpath.managers.integrations.slack.sender import SlackSender
|
|
89
|
+
slack.results = from csvpath.managers.integrations.slack.sender import SlackSender
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
# integrations setup
|
|
93
|
+
#
|
|
94
|
+
|
|
95
|
+
[sftp]
|
|
96
|
+
server = 192.168.67.2
|
|
97
|
+
port = 10022
|
|
98
|
+
username = tinpenny
|
|
99
|
+
password = tinpenny
|
|
100
|
+
|
|
101
|
+
[sql]
|
|
102
|
+
dialect = mysql
|
|
103
|
+
connection_string = mysql://csvpath:hangzhou@127.0.0.1/csvpath
|
|
104
|
+
|
|
105
|
+
[sqlite]
|
|
106
|
+
db = archive/csvpath.db
|
|
107
|
+
|
|
108
|
+
[sftpplus]
|
|
109
|
+
# these are only needed by the csvpath writer
|
|
110
|
+
mailbox_user = MAILBOX_USER
|
|
111
|
+
mailbox_password = MAILBOX_PASSWORD
|
|
112
|
+
server = SFTPPLUS_SERVER
|
|
113
|
+
port = SFTPPLUS_PORT
|
|
114
|
+
# these are only needed on the server
|
|
115
|
+
admin_username = SFTPPLUS_ADMIN_USERNAME
|
|
116
|
+
admin_password = SFTPPLUS_ADMIN_PASSWORD
|
|
117
|
+
api_url = https://localhost:10020/json
|
|
118
|
+
scripts_dir =
|
|
119
|
+
execute_timeout = 300
|
|
120
|
+
|
|
121
|
+
[ckan]
|
|
122
|
+
server = http://localhost:80
|
|
123
|
+
api_token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3akJwc1ZuSkVrZm1aNnBtVTJfTW5CNlJXZ211YjdOOHVXZ1l1cUFDa0Q4IiwiaWF0IjoxNzM0NzE4NDQ3fQ.QXWXoJoSxVES4NwXYBteYUD7enX9D5T2htmETLGFzrs
|
|
124
|
+
|
|
125
|
+
[marquez]
|
|
126
|
+
base_url = http://localhost:5000
|
|
127
|
+
endpoint = api/v1/lineage
|
|
128
|
+
api_key = "none"
|
|
129
|
+
timeout = 5
|
|
130
|
+
verify = False
|
|
131
|
+
|
|
132
|
+
[slack]
|
|
133
|
+
# add your main webhook here. to set webhooks on a csvpath-by-csvpath basis add
|
|
134
|
+
# on-valid-slack: webhook-minus-'https://' and/or
|
|
135
|
+
# on-invalid-slack: webhook-minus-'https://'
|
|
136
|
+
webhook_url =
|
|
137
|
+
|
|
138
|
+
|
|
@@ -33,9 +33,9 @@ archive = archive
|
|
|
33
33
|
|
|
34
34
|
[inputs]
|
|
35
35
|
files = inputs/named_files
|
|
36
|
+
csvpaths = inputs/named_paths
|
|
36
37
|
#csvpaths = s3://csvpath-example-1/inputs/named_paths
|
|
37
38
|
#files = sftp://172.17.0.3:10022/inputs/named_files
|
|
38
|
-
|
|
39
39
|
on_unmatched_file_fingerprints = halt
|
|
40
40
|
|
|
41
41
|
#
|
|
@@ -46,7 +46,13 @@ on_unmatched_file_fingerprints = halt
|
|
|
46
46
|
groups =
|
|
47
47
|
#slack, marquez, ckan, sftp, sftpplus, otlp, default, sqlite
|
|
48
48
|
|
|
49
|
-
# add
|
|
49
|
+
# add sql to capture staging, loads, and results in mysql, postgres, ms sql server, or sqlite
|
|
50
|
+
sql.file = from csvpath.managers.integrations.sql.sql_file_listener import SqlFileListener
|
|
51
|
+
sql.paths = from csvpath.managers.integrations.sql.sql_paths_listener import SqlPathsListener
|
|
52
|
+
sql.result = from csvpath.managers.integrations.sql.sql_result_listener import SqlResultListener
|
|
53
|
+
sql.results = from csvpath.managers.integrations.sql.sql_results_listener import SqlResultsListener
|
|
54
|
+
|
|
55
|
+
# add sqlite to capture staging, loads, and results in a local sqlite file
|
|
50
56
|
sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
|
|
51
57
|
sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
|
|
52
58
|
|
|
@@ -99,6 +105,11 @@ password = tinpenny
|
|
|
99
105
|
[sqlite]
|
|
100
106
|
db = archive/csvpath.db
|
|
101
107
|
|
|
108
|
+
[sql]
|
|
109
|
+
# sqlite, mysql, postgres, or sql_server
|
|
110
|
+
dialect = sqlite
|
|
111
|
+
connection_string = sqlite:///archive/csvpath-sqlite.db
|
|
112
|
+
|
|
102
113
|
[sftpplus]
|
|
103
114
|
# these are only needed by the csvpath writer
|
|
104
115
|
mailbox_user = MAILBOX_USER
|
|
@@ -302,6 +302,9 @@ class FileManager:
|
|
|
302
302
|
mdata.file_name = file_home[file_home.rfind(nos.sep) + 1 :]
|
|
303
303
|
mdata.name_home = name_home
|
|
304
304
|
mdata.mark = mark
|
|
305
|
+
#
|
|
306
|
+
# TODO: add file_size. move FileInfo into Nos. for now it is 0.
|
|
307
|
+
#
|
|
305
308
|
self.registrar.register_complete(mdata)
|
|
306
309
|
|
|
307
310
|
def _clean_file_name(self, fname: str) -> str:
|
|
@@ -49,6 +49,10 @@ class FileRegistrar(Registrar, Listener):
|
|
|
49
49
|
return j
|
|
50
50
|
|
|
51
51
|
def patch_named_file(self, *, name, patch, index=-1) -> None:
|
|
52
|
+
#
|
|
53
|
+
# TODO: distribute an metadata event to give metadata stores a
|
|
54
|
+
# chance to update their info re: the file
|
|
55
|
+
#
|
|
52
56
|
home = self.csvpaths.file_manager.named_file_home(name)
|
|
53
57
|
mp = self.manifest_path(home)
|
|
54
58
|
mani = self.get_manifest(mp)
|
|
@@ -140,10 +144,12 @@ class FileRegistrar(Registrar, Listener):
|
|
|
140
144
|
f"File mgr and registrar marks should match: {mdata.mark}, {mark}"
|
|
141
145
|
)
|
|
142
146
|
if (
|
|
147
|
+
# TODO: s3 can do nos.exists
|
|
143
148
|
not path.startswith("s3:")
|
|
149
|
+
# Nos doesn't handle http files. they are special--inbound only.
|
|
144
150
|
and not path.startswith("http:")
|
|
145
151
|
and not path.startswith("https:")
|
|
146
|
-
# and not azure?
|
|
152
|
+
# and not azure? gcp? should be handled by nos anyway.
|
|
147
153
|
and not Nos(path).exists()
|
|
148
154
|
):
|
|
149
155
|
# if not path.startswith("s3:") and not os.path.exists(path):
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from sqlalchemy import create_engine, Engine
|
|
2
|
+
from csvpath.util.config import Config
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Db:
|
|
6
|
+
@classmethod
|
|
7
|
+
def get(self, config: Config) -> Engine:
|
|
8
|
+
dialect = config.get(section="sql", name="dialect")
|
|
9
|
+
c_str = config.get(section="sql", name="connection_string")
|
|
10
|
+
if dialect == "sqlite":
|
|
11
|
+
# sqlite:///example.db
|
|
12
|
+
engine = create_engine(c_str)
|
|
13
|
+
elif dialect == "postgres":
|
|
14
|
+
# postgresql+psycopg2://user:password@localhost/dbname
|
|
15
|
+
engine = create_engine(c_str)
|
|
16
|
+
elif dialect == "mysql":
|
|
17
|
+
# mysql+pymysql://user:password@localhost/dbname
|
|
18
|
+
engine = create_engine(c_str)
|
|
19
|
+
elif dialect == "sql_server":
|
|
20
|
+
# mssql+pyodbc://user:password@localhost/dbname
|
|
21
|
+
engine = create_engine(c_str)
|
|
22
|
+
else:
|
|
23
|
+
raise ValueError("Unknown RDBMS dialect %s", dialect)
|
|
24
|
+
return engine
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from sqlalchemy import Table
|
|
2
|
+
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
|
3
|
+
from sqlalchemy.dialects.mysql import insert as mysql_insert
|
|
4
|
+
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
|
|
5
|
+
from csvpath.managers.metadata import Metadata
|
|
6
|
+
from .sql_listener import SqlListener
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SqlFileListener(SqlListener):
|
|
10
|
+
def __init__(self, config=None):
|
|
11
|
+
SqlListener.__init__(self, config=config)
|
|
12
|
+
self._named_file = None
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def named_file(self) -> Table:
|
|
16
|
+
if self._named_file is None:
|
|
17
|
+
self._named_file = self.tables.named_file
|
|
18
|
+
return self._named_file
|
|
19
|
+
|
|
20
|
+
def metadata_update(self, mdata: Metadata) -> None:
|
|
21
|
+
if not self.csvpaths:
|
|
22
|
+
raise RuntimeError("CsvPaths cannot be None")
|
|
23
|
+
named_file_data = {
|
|
24
|
+
"uuid": mdata.uuid_string,
|
|
25
|
+
"at": mdata.time,
|
|
26
|
+
"named_file_name": mdata.named_file_name,
|
|
27
|
+
"origin_path": mdata.origin_path,
|
|
28
|
+
"name_home": mdata.name_home,
|
|
29
|
+
"file_home": mdata.file_home,
|
|
30
|
+
"file_path": mdata.file_path,
|
|
31
|
+
"file_name": mdata.file_name,
|
|
32
|
+
"mark": mdata.mark,
|
|
33
|
+
"type": mdata.type,
|
|
34
|
+
"file_size": mdata.file_size,
|
|
35
|
+
"ip_address": mdata.ip_address,
|
|
36
|
+
"hostname": mdata.hostname,
|
|
37
|
+
"username": mdata.username,
|
|
38
|
+
"files_root": mdata.named_files_root,
|
|
39
|
+
"base_path": mdata.base_path,
|
|
40
|
+
"manifest_path": mdata.manifest_path,
|
|
41
|
+
}
|
|
42
|
+
self._upsert_named_file(named_file_data)
|
|
43
|
+
|
|
44
|
+
def _upsert_named_file(self, named_file_data: dict, *, dispose: bool = True):
|
|
45
|
+
with self.engine.connect() as conn:
|
|
46
|
+
dialect = conn.dialect.name
|
|
47
|
+
self.csvpaths.logger.info("Inserting named-file metadata into %s", dialect)
|
|
48
|
+
stmt = None
|
|
49
|
+
if dialect in ["postgresql", "sqlite"]:
|
|
50
|
+
ist = pg_insert if dialect == "postgresql" else sqlite_insert
|
|
51
|
+
stmt = (
|
|
52
|
+
ist(self.named_file)
|
|
53
|
+
.values(named_file_data)
|
|
54
|
+
.on_conflict_do_update(
|
|
55
|
+
index_elements=["uuid"], set_=self._set(named_file_data)
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
elif dialect == "mysql":
|
|
59
|
+
stmt = (
|
|
60
|
+
mysql_insert(self.named_file)
|
|
61
|
+
.values(named_file_data)
|
|
62
|
+
.on_duplicate_key_update(self._set(named_file_data))
|
|
63
|
+
)
|
|
64
|
+
elif dialect == "mssql":
|
|
65
|
+
raise NotImplementedError("SQL Server support is not yet implemented.")
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError(f"Unsupported database dialect: {dialect}")
|
|
68
|
+
conn.execute(stmt)
|
|
69
|
+
conn.commit()
|
|
70
|
+
if dispose is True:
|
|
71
|
+
self.engine.dispose()
|
|
72
|
+
|
|
73
|
+
def _set(self, named_file_data) -> dict:
|
|
74
|
+
return {
|
|
75
|
+
"files_root": named_file_data["files_root"],
|
|
76
|
+
"file_home": named_file_data["file_home"],
|
|
77
|
+
"file_path": named_file_data["file_path"],
|
|
78
|
+
"file_name": named_file_data["file_name"],
|
|
79
|
+
"mark": named_file_data["mark"],
|
|
80
|
+
"type": named_file_data["type"],
|
|
81
|
+
"file_size": named_file_data["file_size"],
|
|
82
|
+
"ip_address": named_file_data["ip_address"],
|
|
83
|
+
"hostname": named_file_data["hostname"],
|
|
84
|
+
"username": named_file_data["username"],
|
|
85
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from sqlalchemy import Engine
|
|
2
|
+
from csvpath.managers.listener import Listener
|
|
3
|
+
from .engine import Db
|
|
4
|
+
from .tables import Tables
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SqlListener(Listener):
|
|
8
|
+
def __init__(self, config=None):
|
|
9
|
+
Listener.__init__(self, config=config)
|
|
10
|
+
self.csvpaths = None
|
|
11
|
+
self._tables = None
|
|
12
|
+
self._engine = None
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def tables(self) -> Tables:
|
|
16
|
+
if self._tables is None:
|
|
17
|
+
self._tables = Tables(self.config, engine=self.engine)
|
|
18
|
+
self._tables.assure_tables()
|
|
19
|
+
return self._tables
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def engine(self) -> Engine:
|
|
23
|
+
if self._engine is None:
|
|
24
|
+
self._engine = Db.get(self.config)
|
|
25
|
+
return self._engine
|
|
26
|
+
|
|
27
|
+
@engine.setter
|
|
28
|
+
def engine(self, engine: Engine):
|
|
29
|
+
self._engine = engine
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from sqlalchemy import Table
|
|
2
|
+
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
|
3
|
+
from sqlalchemy.dialects.mysql import insert as mysql_insert
|
|
4
|
+
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
|
|
5
|
+
from csvpath.managers.metadata import Metadata
|
|
6
|
+
from .sql_listener import SqlListener
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SqlPathsListener(SqlListener):
|
|
10
|
+
def __init__(self, config=None):
|
|
11
|
+
SqlListener.__init__(self, config=config)
|
|
12
|
+
self._named_paths = None
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def named_paths(self) -> Table:
|
|
16
|
+
if self._named_paths is None:
|
|
17
|
+
self._named_paths = self.tables.named_paths
|
|
18
|
+
return self._named_paths
|
|
19
|
+
|
|
20
|
+
def metadata_update(self, mdata: Metadata) -> None:
|
|
21
|
+
if not self.csvpaths:
|
|
22
|
+
raise RuntimeError("CsvPaths cannot be None")
|
|
23
|
+
named_paths_data = {
|
|
24
|
+
"uuid": mdata.uuid_string,
|
|
25
|
+
"at": mdata.time,
|
|
26
|
+
"paths_root": mdata.named_paths_root,
|
|
27
|
+
"paths_name": mdata.named_paths_name,
|
|
28
|
+
"paths_home": mdata.named_paths_home,
|
|
29
|
+
"group_file_path": mdata.group_file_path,
|
|
30
|
+
"paths_count": mdata.named_paths_count,
|
|
31
|
+
"ip_address": mdata.ip_address,
|
|
32
|
+
"hostname": mdata.hostname,
|
|
33
|
+
"username": mdata.username,
|
|
34
|
+
"base_path": mdata.base_path,
|
|
35
|
+
"manifest_path": mdata.manifest_path,
|
|
36
|
+
}
|
|
37
|
+
self._upsert_named_paths(named_paths_data)
|
|
38
|
+
|
|
39
|
+
def _upsert_named_paths(self, named_paths_data: dict, *, dispose: bool = True):
|
|
40
|
+
with self.engine.connect() as conn:
|
|
41
|
+
dialect = conn.dialect.name
|
|
42
|
+
self.csvpaths.logger.info("Inserting named-paths metadata into %s", dialect)
|
|
43
|
+
stmt = None
|
|
44
|
+
if dialect in ["postgresql", "sqlite"]:
|
|
45
|
+
ist = pg_insert if dialect == "postgresql" else sqlite_insert
|
|
46
|
+
stmt = (
|
|
47
|
+
ist(self.named_paths)
|
|
48
|
+
.values(named_paths_data)
|
|
49
|
+
.on_conflict_do_update(
|
|
50
|
+
index_elements=["uuid"], set_=self._set(named_paths_data)
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
elif dialect == "mysql":
|
|
54
|
+
stmt = (
|
|
55
|
+
mysql_insert(self.named_paths)
|
|
56
|
+
.values(named_paths_data)
|
|
57
|
+
.on_duplicate_key_update(self._set(named_paths_data))
|
|
58
|
+
)
|
|
59
|
+
elif dialect == "mssql":
|
|
60
|
+
raise NotImplementedError("SQL Server support is not yet implemented.")
|
|
61
|
+
else:
|
|
62
|
+
raise ValueError(f"Unsupported database dialect: {dialect}")
|
|
63
|
+
conn.execute(stmt)
|
|
64
|
+
conn.commit()
|
|
65
|
+
if dispose is True:
|
|
66
|
+
self.engine.dispose()
|
|
67
|
+
|
|
68
|
+
def _set(self, named_paths_data) -> dict:
|
|
69
|
+
return {
|
|
70
|
+
"paths_root": named_paths_data["paths_name"],
|
|
71
|
+
"paths_name": named_paths_data["paths_name"],
|
|
72
|
+
"paths_home": named_paths_data["paths_home"],
|
|
73
|
+
"group_file_path": named_paths_data["group_file_path"],
|
|
74
|
+
"paths_count": named_paths_data["paths_count"],
|
|
75
|
+
"ip_address": named_paths_data["ip_address"],
|
|
76
|
+
"hostname": named_paths_data["hostname"],
|
|
77
|
+
"username": named_paths_data["username"],
|
|
78
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from sqlalchemy import Table
|
|
2
|
+
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
|
3
|
+
from sqlalchemy.dialects.mysql import insert as mysql_insert
|
|
4
|
+
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
|
|
5
|
+
from csvpath.managers.metadata import Metadata
|
|
6
|
+
from .sql_listener import SqlListener
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SqlResultListener(SqlListener):
|
|
10
|
+
def __init__(self, config=None):
|
|
11
|
+
SqlListener.__init__(self, config=config)
|
|
12
|
+
self._instance_run = None
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def instance_run(self) -> Table:
|
|
16
|
+
if self._instance_run is None:
|
|
17
|
+
self._instance_run = self.tables.instance_run
|
|
18
|
+
return self._instance_run
|
|
19
|
+
|
|
20
|
+
def metadata_update(self, mdata: Metadata) -> None:
|
|
21
|
+
if not self.csvpaths:
|
|
22
|
+
raise RuntimeError("CsvPaths cannot be None")
|
|
23
|
+
instance_run_data = {
|
|
24
|
+
"uuid": mdata.uuid_string,
|
|
25
|
+
"at": mdata.time,
|
|
26
|
+
"group_run_uuid": mdata.named_paths_uuid_string,
|
|
27
|
+
"instance_identity": mdata.instance_identity,
|
|
28
|
+
"instance_index": mdata.instance_index,
|
|
29
|
+
"instance_home": mdata.instance_home,
|
|
30
|
+
"preceding_instance_identity": mdata.preceding_instance_identity,
|
|
31
|
+
"actual_data_file": mdata.actual_data_file,
|
|
32
|
+
"source_mode_preceding": "Y"
|
|
33
|
+
if (
|
|
34
|
+
mdata.source_mode_preceding is True
|
|
35
|
+
or mdata.source_mode_preceding == "Y"
|
|
36
|
+
)
|
|
37
|
+
else "N",
|
|
38
|
+
"valid": "Y" if (mdata.valid is True or mdata.valid == "Y") else "N",
|
|
39
|
+
"completed": "Y"
|
|
40
|
+
if (mdata.completed is True or mdata.completed == "Y")
|
|
41
|
+
else "N",
|
|
42
|
+
"files_expected": "Y"
|
|
43
|
+
if (mdata.files_expected is True or mdata.files_expected == "Y")
|
|
44
|
+
else "N",
|
|
45
|
+
"error_count": mdata.error_count if mdata.error_count else 0,
|
|
46
|
+
"number_of_files_expected": mdata.number_of_files_expected,
|
|
47
|
+
"number_of_files_generated": mdata.number_of_files_generated,
|
|
48
|
+
"lines_scanned": mdata.lines_scanned,
|
|
49
|
+
"lines_total": mdata.lines_total,
|
|
50
|
+
"lines_matched": mdata.lines_matched,
|
|
51
|
+
"manifest_path": mdata.manifest_path,
|
|
52
|
+
}
|
|
53
|
+
self._upsert_instance_run(instance_run_data)
|
|
54
|
+
|
|
55
|
+
def _upsert_instance_run(self, instance_run_data, *, dispose=True):
|
|
56
|
+
with self.engine.connect() as conn:
|
|
57
|
+
dialect = conn.dialect.name
|
|
58
|
+
self.csvpaths.logger.info("Inserting run result metadata into %s", dialect)
|
|
59
|
+
s = self._set(instance_run_data)
|
|
60
|
+
if dialect in ["postgresql", "sqlite"]:
|
|
61
|
+
ist = pg_insert if dialect == "postgresql" else sqlite_insert
|
|
62
|
+
stmt = (
|
|
63
|
+
ist(self.instance_run)
|
|
64
|
+
.values(instance_run_data)
|
|
65
|
+
.on_conflict_do_update(index_elements=["uuid"], set_=s)
|
|
66
|
+
)
|
|
67
|
+
elif dialect == "mysql":
|
|
68
|
+
stmt = (
|
|
69
|
+
mysql_insert(self.instance_run)
|
|
70
|
+
.values(instance_run_data)
|
|
71
|
+
.on_duplicate_key_update(self._set(instance_run_data))
|
|
72
|
+
)
|
|
73
|
+
elif dialect == "mssql":
|
|
74
|
+
raise NotImplementedError("SQL Server support is not yet implemented.")
|
|
75
|
+
else:
|
|
76
|
+
raise ValueError(f"Unsupported database dialect: {dialect}")
|
|
77
|
+
conn.execute(stmt)
|
|
78
|
+
conn.commit()
|
|
79
|
+
if dispose is True:
|
|
80
|
+
self.engine.dispose()
|
|
81
|
+
|
|
82
|
+
def _set(self, instance_run_data: dict) -> dict:
|
|
83
|
+
return {
|
|
84
|
+
"valid": "Y"
|
|
85
|
+
if (instance_run_data["valid"] is True or instance_run_data["valid"] == "Y")
|
|
86
|
+
else "N",
|
|
87
|
+
"completed": "Y"
|
|
88
|
+
if (
|
|
89
|
+
instance_run_data["completed"] is True
|
|
90
|
+
or instance_run_data["completed"] == "Y"
|
|
91
|
+
)
|
|
92
|
+
else "N",
|
|
93
|
+
"error_count": instance_run_data["error_count"],
|
|
94
|
+
"number_of_files_expected": instance_run_data["number_of_files_expected"],
|
|
95
|
+
"number_of_files_generated": instance_run_data["number_of_files_generated"],
|
|
96
|
+
"files_expected": instance_run_data["files_expected"],
|
|
97
|
+
"lines_scanned": instance_run_data["lines_scanned"],
|
|
98
|
+
"lines_total": instance_run_data["lines_total"],
|
|
99
|
+
"lines_matched": instance_run_data["lines_matched"],
|
|
100
|
+
}
|