csvpath 0.0.605__tar.gz → 0.0.608__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.
Files changed (404) hide show
  1. {csvpath-0.0.605 → csvpath-0.0.608}/PKG-INFO +1 -1
  2. {csvpath-0.0.605 → csvpath-0.0.608}/assets/.DS_Store +0 -0
  3. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/.DS_Store +0 -0
  4. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/csvpaths.py +5 -4
  5. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/file_manager.py +5 -3
  6. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/files_activation_listener.py +2 -4
  7. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/webhook/webhook_listener.py +2 -4
  8. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/webhook/webhook_results_listener.py +38 -1
  9. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/paths/paths_describer.py +7 -2
  10. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/paths/paths_manager.py +1 -1
  11. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/results_manager.py +0 -4
  12. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_data_writer.py +4 -5
  13. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_nos.py +0 -4
  14. csvpath-0.0.608/csvpath/util/azure/azure_timing_policy.py +14 -0
  15. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_utils.py +11 -4
  16. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/config.py +4 -1
  17. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_fingerprinter.py +4 -3
  18. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_nos.py +103 -55
  19. csvpath-0.0.608/csvpath/util/stopwatch.py +43 -0
  20. {csvpath-0.0.605 → csvpath-0.0.608}/pyproject.toml +1 -1
  21. {csvpath-0.0.605 → csvpath-0.0.608}/LICENSE +0 -0
  22. {csvpath-0.0.605 → csvpath-0.0.608}/README.md +0 -0
  23. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/config.ini +0 -0
  24. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/extra-functions.imports +0 -0
  25. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/function.imports +0 -0
  26. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-local-azure.ini +0 -0
  27. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-local-filesystem-mysql.ini +0 -0
  28. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-local-gcs.ini +0 -0
  29. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-local-s3.ini +0 -0
  30. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-local-sftp.ini +0 -0
  31. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-windows-azure.ini +0 -0
  32. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-windows-gcs.ini +0 -0
  33. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-windows-local.ini +0 -0
  34. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-windows-s3.ini +0 -0
  35. {csvpath-0.0.605 → csvpath-0.0.608}/assets/config/jenkins-windows-sftp.ini +0 -0
  36. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/Mac.goenvironment.json +0 -0
  37. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/Windows.goenvironment.json +0 -0
  38. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/azure-pipeline.gopipeline.json +0 -0
  39. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/azure.sh +0 -0
  40. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/gcs.sh +0 -0
  41. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/google-pipeline.gopipeline.json +0 -0
  42. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/local-pipeline.gopipeline copy.json +0 -0
  43. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/local.sh +0 -0
  44. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/s3-pipeline.gopipeline.json +0 -0
  45. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/s3.sh +0 -0
  46. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/sftp-pipeline.gopipeline.json +0 -0
  47. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/mac/sftp.sh +0 -0
  48. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/azure.bat +0 -0
  49. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/gcs.bat +0 -0
  50. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/local.bat +0 -0
  51. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/s3.bat +0 -0
  52. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/sftp.bat +0 -0
  53. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/windows-azure.gopipeline.json +0 -0
  54. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/windows-gcs.gopipeline.json +0 -0
  55. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/windows-local.gopipeline.json +0 -0
  56. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/windows-s3.gopipeline.json +0 -0
  57. {csvpath-0.0.605 → csvpath-0.0.608}/assets/gocd/windows/windows-sftp.gopipeline.json +0 -0
  58. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/.DS_Store +0 -0
  59. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  60. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  61. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  62. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  63. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  64. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  65. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sqlite/csvpath +0 -0
  66. {csvpath-0.0.605 → csvpath-0.0.608}/assets/integrations/sqlite/schema.sql +0 -0
  67. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.25-py3-none-any.whl +0 -0
  68. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.27-py3-none-any.whl +0 -0
  69. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.28-py3-none-any.whl +0 -0
  70. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.29-py3-none-any.whl +0 -0
  71. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.30.tar.gz +0 -0
  72. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.31.tar.gz +0 -0
  73. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.33.tar.gz +0 -0
  74. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.34.tar.gz +0 -0
  75. {csvpath-0.0.605 → csvpath-0.0.608}/assets/libs/release_candidate_maker-0.0.35.tar.gz +0 -0
  76. {csvpath-0.0.605 → csvpath-0.0.608}/config/config.ini +0 -0
  77. {csvpath-0.0.605 → csvpath-0.0.608}/config/env.json +0 -0
  78. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/__init__.py +0 -0
  79. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/__init__.py +0 -0
  80. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/asker.py +0 -0
  81. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/cli.py +0 -0
  82. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/const.py +0 -0
  83. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/debug_config.py +0 -0
  84. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/drill_down.py +0 -0
  85. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/function_describer.py +0 -0
  86. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/function_lister.py +0 -0
  87. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/cli/selecter.py +0 -0
  88. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/csvpath.py +0 -0
  89. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/__init__.py +0 -0
  90. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/errors/error.py +0 -0
  91. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/errors/error_collector.py +0 -0
  92. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/errors/error_comms.py +0 -0
  93. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/errors/error_manager.py +0 -0
  94. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/file_activator.py +0 -0
  95. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/file_describer.py +0 -0
  96. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/file_metadata.py +0 -0
  97. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/file_registrar.py +0 -0
  98. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/files_listener.py +0 -0
  99. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  100. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  101. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  102. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  103. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  104. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/event.py +0 -0
  105. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/event_result.py +0 -0
  106. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
  107. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/job.py +0 -0
  108. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  109. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
  110. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
  111. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
  112. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/run.py +0 -0
  113. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
  114. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/run_state.py +0 -0
  115. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/ol/sender.py +0 -0
  116. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  117. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  118. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  119. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_file_listener.py +0 -0
  120. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  121. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_paths_listener.py +0 -0
  122. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  123. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  124. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  125. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  126. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
  127. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
  128. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
  129. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
  130. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
  131. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/slack/event.py +0 -0
  132. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/slack/sender.py +0 -0
  133. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/engine.py +0 -0
  134. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  135. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  136. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  137. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  138. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  139. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/tables.py +0 -0
  140. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sql/updates.py +0 -0
  141. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  142. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  143. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  144. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/listener.py +0 -0
  145. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/metadata.py +0 -0
  146. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/paths/paths_listener.py +0 -0
  147. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/paths/paths_metadata.py +0 -0
  148. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/paths/paths_registrar.py +0 -0
  149. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/registrar.py +0 -0
  150. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  151. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  152. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  153. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  154. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/readers/readers.py +0 -0
  155. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/result.py +0 -0
  156. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/result_file_reader.py +0 -0
  157. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/result_metadata.py +0 -0
  158. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/result_registrar.py +0 -0
  159. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/result_serializer.py +0 -0
  160. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/results_metadata.py +0 -0
  161. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/results/results_registrar.py +0 -0
  162. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/run/run_listener_stdout.py +0 -0
  163. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/run/run_metadata.py +0 -0
  164. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/run/run_registrar.py +0 -0
  165. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/managers/test_listener.py +0 -0
  166. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/__init__.py +0 -0
  167. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/__init__.py +0 -0
  168. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/args.py +0 -0
  169. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/args_helper.py +0 -0
  170. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/all.py +0 -0
  171. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/andf.py +0 -0
  172. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/any.py +0 -0
  173. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/between.py +0 -0
  174. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/empty.py +0 -0
  175. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/exists.py +0 -0
  176. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/inf.py +0 -0
  177. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/no.py +0 -0
  178. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/notf.py +0 -0
  179. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/orf.py +0 -0
  180. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/boolean/yes.py +0 -0
  181. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/count.py +0 -0
  182. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  183. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/count_headers.py +0 -0
  184. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/count_lines.py +0 -0
  185. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/count_scans.py +0 -0
  186. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/counter.py +0 -0
  187. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/every.py +0 -0
  188. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/has_matches.py +0 -0
  189. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/increment.py +0 -0
  190. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/tally.py +0 -0
  191. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/counting/total_lines.py +0 -0
  192. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/dates/now.py +0 -0
  193. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/dates/part.py +0 -0
  194. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/dates/roll.py +0 -0
  195. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/function.py +0 -0
  196. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/function_factory.py +0 -0
  197. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/function_finder.py +0 -0
  198. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/function_focus.py +0 -0
  199. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/append.py +0 -0
  200. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/collect.py +0 -0
  201. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  202. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/end.py +0 -0
  203. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/header_name.py +0 -0
  204. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  205. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/headers.py +0 -0
  206. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/headers_stack.py +0 -0
  207. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/insert.py +0 -0
  208. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/line_before.py +0 -0
  209. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/mismatch.py +0 -0
  210. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/remove.py +0 -0
  211. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/rename.py +0 -0
  212. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/replace.py +0 -0
  213. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  214. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/json/jsonpath.py +0 -0
  215. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/advance.py +0 -0
  216. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/after_blank.py +0 -0
  217. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/dups.py +0 -0
  218. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/first.py +0 -0
  219. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/first_line.py +0 -0
  220. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/last.py +0 -0
  221. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/lines/stop.py +0 -0
  222. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/above.py +0 -0
  223. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/add.py +0 -0
  224. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/divide.py +0 -0
  225. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/equals.py +0 -0
  226. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/intf.py +0 -0
  227. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/mod.py +0 -0
  228. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/multiply.py +0 -0
  229. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/odd.py +0 -0
  230. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/round.py +0 -0
  231. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/subtotal.py +0 -0
  232. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/subtract.py +0 -0
  233. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/math/sum.py +0 -0
  234. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  235. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/misc/importf.py +0 -0
  236. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/misc/parquet.py +0 -0
  237. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/misc/random.py +0 -0
  238. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/print/jinjaf.py +0 -0
  239. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/print/print_line.py +0 -0
  240. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/print/print_queue.py +0 -0
  241. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/print/printf.py +0 -0
  242. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/print/table.py +0 -0
  243. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/sql/sql_in.py +0 -0
  244. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/stats/minf.py +0 -0
  245. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/stats/nminmax.py +0 -0
  246. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/stats/percent.py +0 -0
  247. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  248. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/stats/stdev.py +0 -0
  249. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/alter.py +0 -0
  250. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/caps.py +0 -0
  251. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/concat.py +0 -0
  252. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/contains.py +0 -0
  253. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/format.py +0 -0
  254. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/length.py +0 -0
  255. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/lower.py +0 -0
  256. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/metaphone.py +0 -0
  257. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/regex.py +0 -0
  258. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/starts_with.py +0 -0
  259. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/strip.py +0 -0
  260. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/substring.py +0 -0
  261. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/strings/upper.py +0 -0
  262. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/testing/debug.py +0 -0
  263. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/__init__.py +0 -0
  264. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/blank.py +0 -0
  265. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/boolean.py +0 -0
  266. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/datatype.py +0 -0
  267. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/datef.py +0 -0
  268. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/decimal.py +0 -0
  269. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/email.py +0 -0
  270. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/nonef.py +0 -0
  271. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/string.py +0 -0
  272. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/type.py +0 -0
  273. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/url.py +0 -0
  274. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/types/wildcard.py +0 -0
  275. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/validity/fail.py +0 -0
  276. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/validity/failed.py +0 -0
  277. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/validity/line.py +0 -0
  278. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/validity/matches.py +0 -0
  279. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/validity/percent_matching.py +0 -0
  280. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/clear.py +0 -0
  281. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/get.py +0 -0
  282. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/index_of.py +0 -0
  283. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/pushpop.py +0 -0
  284. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/put.py +0 -0
  285. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/slice.py +0 -0
  286. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/sort.py +0 -0
  287. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/track.py +0 -0
  288. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/variables/variables.py +0 -0
  289. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/functions/xml/xpath.py +0 -0
  290. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/lark_parser.py +0 -0
  291. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/lark_transformer.py +0 -0
  292. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/matcher.py +0 -0
  293. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/__init__.py +0 -0
  294. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/equality.py +0 -0
  295. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/expression.py +0 -0
  296. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/header.py +0 -0
  297. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/matchable.py +0 -0
  298. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/qualified.py +0 -0
  299. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/reference.py +0 -0
  300. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/term.py +0 -0
  301. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/productions/variable.py +0 -0
  302. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/exceptions.py +0 -0
  303. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/expression_encoder.py +0 -0
  304. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/expression_utility.py +0 -0
  305. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/lark_print_parser.py +0 -0
  306. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/parquet_utility.py +0 -0
  307. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/print_parser.py +0 -0
  308. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/matching/util/runtime_data_collector.py +0 -0
  309. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/error_mode.py +0 -0
  310. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/explain_mode.py +0 -0
  311. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/files_mode.py +0 -0
  312. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/logic_mode.py +0 -0
  313. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/mode_controller.py +0 -0
  314. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/print_mode.py +0 -0
  315. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/return_mode.py +0 -0
  316. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/run_mode.py +0 -0
  317. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/source_mode.py +0 -0
  318. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/transfer_mode.py +0 -0
  319. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/unmatched_mode.py +0 -0
  320. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/modes/validation_mode.py +0 -0
  321. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/scanning/__init__.py +0 -0
  322. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/scanning/scanner2.py +0 -0
  323. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/scanning/scanner2_parser.py +0 -0
  324. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/scanning/scanner2_transformer.py +0 -0
  325. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_data_reader.py +0 -0
  326. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  327. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_json_data_reader.py +0 -0
  328. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  329. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/backend_check.py +0 -0
  330. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/box.py +0 -0
  331. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/cache.py +0 -0
  332. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/caser.py +0 -0
  333. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/class_loader.py +0 -0
  334. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/code.py +0 -0
  335. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/config_env.py +0 -0
  336. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/config_exception.py +0 -0
  337. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/date_util.py +0 -0
  338. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/exceptions.py +0 -0
  339. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/file_info.py +0 -0
  340. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/file_readers.py +0 -0
  341. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/file_utility.py +0 -0
  342. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/file_writers.py +0 -0
  343. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  344. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  345. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  346. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_json_data_reader.py +0 -0
  347. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_nos.py +0 -0
  348. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_utils.py +0 -0
  349. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  350. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/hasher.py +0 -0
  351. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/http/http_data_reader.py +0 -0
  352. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/intermediary.py +0 -0
  353. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/json/json_data_reader.py +0 -0
  354. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/json/json_reader_helper.py +0 -0
  355. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/last_line_stats.py +0 -0
  356. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/line_counter.py +0 -0
  357. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/line_monitor.py +0 -0
  358. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/line_spooler.py +0 -0
  359. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/log_utility.py +0 -0
  360. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/metadata_parser.py +0 -0
  361. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/nos.py +0 -0
  362. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/pandas_data_reader.py +0 -0
  363. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/path_util.py +0 -0
  364. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/printer.py +0 -0
  365. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/py_file_utility.py +0 -0
  366. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/files_reference_finder_2.py +0 -0
  367. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/files_tools/fingerprint_finder.py +0 -0
  368. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/files_tools/range_finder.py +0 -0
  369. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/ref_utils.py +0 -0
  370. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_exceptions.py +0 -0
  371. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_grammar.py +0 -0
  372. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_manifest_entry_finder.py +0 -0
  373. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_parser.py +0 -0
  374. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_results.py +0 -0
  375. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/reference_transformer.py +0 -0
  376. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_reference_finder_2.py +0 -0
  377. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/data_finder.py +0 -0
  378. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/date_filter.py +0 -0
  379. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/identity_finder.py +0 -0
  380. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/path_filter.py +0 -0
  381. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/resolve_possibles.py +0 -0
  382. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/token_filters.py +0 -0
  383. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/results_tools/yesterday_or_today_translator.py +0 -0
  384. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/references/tools/date_completer.py +0 -0
  385. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/referrer_printer.py +0 -0
  386. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/run_home_maker.py +0 -0
  387. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_data_reader.py +0 -0
  388. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_data_writer.py +0 -0
  389. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  390. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_json_data_reader.py +0 -0
  391. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_nos.py +0 -0
  392. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_utils.py +0 -0
  393. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  394. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_config.py +0 -0
  395. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_data_reader.py +0 -0
  396. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  397. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_json_data_reader.py +0 -0
  398. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_walk.py +0 -0
  399. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  400. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/sqliter.py +0 -0
  401. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/template_util.py +0 -0
  402. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/var_utility.py +0 -0
  403. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/xlsx/xlsx_data_reader.py +0 -0
  404. {csvpath-0.0.605 → csvpath-0.0.608}/csvpath/util/xlsx/xlsx_reader_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csvpath
3
- Version: 0.0.605
3
+ Version: 0.0.608
4
4
  Summary: CsvPath Framework is a data preboarding automation library for receiving, validating, and tracking CSV, Excel, JSONL and other tabular data files before they can corrupt downstream data consumers.
5
5
  License-File: LICENSE
6
6
  Author: David Kershaw
@@ -172,8 +172,8 @@ class CsvPaths(CsvPathsCoordinator, ErrorCollector):
172
172
  #
173
173
  #
174
174
  #
175
- self.info_dump()
176
- """ @private """
175
+ # self.info_dump()
176
+
177
177
  self._errors = []
178
178
  # coordinator attributes
179
179
  self._stop_all = False
@@ -269,8 +269,9 @@ class CsvPaths(CsvPathsCoordinator, ErrorCollector):
269
269
  if subs not in ["env", "none"]:
270
270
  subs = f"{subs} with keys:"
271
271
  e = self.config.config_env.env
272
- for k, v in e.items():
273
- subs = f"{subs}\n - {k}"
272
+ if e is not None:
273
+ for k, v in e.items():
274
+ subs = f"{subs}\n - {k}"
274
275
  cache = self.config.get(section="cache", name="path")
275
276
  cache = cache if self.config.get(section="cache", name="use_cache") else "none"
276
277
  logstr = self.logger if self.logger else "pending"
@@ -1,6 +1,4 @@
1
- import os
2
1
  import json
3
- import csv
4
2
  import traceback
5
3
  from typing import NewType
6
4
  from json import JSONDecodeError
@@ -13,7 +11,7 @@ from csvpath.util.references.files_reference_finder_2 import (
13
11
  from csvpath.util.references.results_reference_finder_2 import (
14
12
  ResultsReferenceFinder2 as ResultsReferenceFinder,
15
13
  )
16
- from csvpath.util.exceptions import InputException, FileException
14
+ from csvpath.util.exceptions import FileException
17
15
  from csvpath.util.nos import Nos
18
16
  from csvpath.util.box import Box
19
17
  from csvpath.util.path_util import PathUtility as pathu
@@ -641,10 +639,12 @@ class FileManager:
641
639
  #
642
640
  self.csvpaths.logger.debug("Path after removing mark, if any: %s", path)
643
641
  self._copy_in(path, home, template)
642
+ self.csvpaths.logger.debug("Done copying in")
644
643
  #
645
644
  #
646
645
  #
647
646
  self.assure_docs_and_discriptor(name)
647
+ self.csvpaths.logger.debug("Assured docs and discriptor")
648
648
  #
649
649
  # create the reference to the bytes/version added to the named-file.
650
650
  # this is the most specific reference possible. we return it when we're
@@ -658,6 +658,7 @@ class FileManager:
658
658
  # create the metadata event for this registration
659
659
  #
660
660
  name_home = self.named_file_home(name)
661
+ self.csvpaths.logger.debug("Name home is %s", name_home)
661
662
  mdata = FileMetadata(self.csvpaths.config)
662
663
  mdata.named_file_name = name
663
664
  mdata.named_file_ref = ret
@@ -678,6 +679,7 @@ class FileManager:
678
679
  mdata.name_home = name_home
679
680
  mdata.mark = mark
680
681
  mdata.template = template
682
+ self.csvpaths.logger.debug("Created metadata")
681
683
  #
682
684
  # TODO: add file_size. move FileInfo into Nos. for now it is 0.
683
685
  #
@@ -1,7 +1,5 @@
1
- import requests
2
1
  import threading
3
2
 
4
- from abc import ABC
5
3
 
6
4
  from csvpath import CsvPaths
7
5
  from csvpath.managers.metadata import Metadata
@@ -28,6 +26,6 @@ class FileActivationListener(Listener, threading.Thread):
28
26
  csvpaths = CsvPaths()
29
27
  activator = csvpaths.file_manager.activator
30
28
  ref = mdata.named_file_ref
31
- csvpaths.logger.info("Activating for {ref} if any activation is configured")
29
+ csvpaths.logger.info(f"Activating for {ref} if any activation is configured")
32
30
  activator.activate_if(ref)
33
- csvpaths.logger.info("Activation for {ref} if any completed")
31
+ csvpaths.logger.info(f"Activation for {ref} if any completed")
@@ -1,8 +1,6 @@
1
1
  import requests
2
2
  import threading
3
3
 
4
- from abc import ABC
5
- from csvpath.util.box import Box
6
4
  from csvpath.managers.metadata import Metadata
7
5
  from csvpath.managers.listener import Listener
8
6
  from csvpath.matching.util.expression_utility import ExpressionUtility
@@ -22,8 +20,7 @@ from csvpath.matching.util.expression_utility import ExpressionUtility
22
20
  #
23
21
 
24
22
 
25
- class WebhookException(Exception):
26
- ...
23
+ class WebhookException(Exception): ...
27
24
 
28
25
 
29
26
  class WebhookListener(Listener, threading.Thread):
@@ -113,6 +110,7 @@ class WebhookListener(Listener, threading.Thread):
113
110
  # prep request
114
111
  #
115
112
  headers = {"Content-Type": "application/json"}
113
+ headers = headers | self._headers_for_type(mdata, atype)
116
114
  #
117
115
  # send
118
116
  #
@@ -64,7 +64,7 @@ class WebhookResultsListener(WebhookListener):
64
64
  return False
65
65
  return True
66
66
 
67
- def _url_for_type(self, mdata: Metadata, atype: str):
67
+ def _url_for_type(self, mdata: Metadata, atype: str) -> str:
68
68
  cfg = self.csvpaths.paths_manager.describer.get_webhooks(mdata.named_paths_name)
69
69
  if cfg is None:
70
70
  return None
@@ -79,6 +79,43 @@ class WebhookResultsListener(WebhookListener):
79
79
  else:
80
80
  raise ValueError(f"Unknown type: {atype}")
81
81
 
82
+ def _headers_for_type(self, mdata: Metadata, atype: str) -> dict:
83
+ cfg = self.csvpaths.paths_manager.describer.get_webhooks(mdata.named_paths_name)
84
+ if cfg is None:
85
+ return None
86
+ headers = None
87
+ if atype.find("all") > -1:
88
+ headers = cfg.on_complete_all.headers
89
+ elif atype.find("invalid") > -1:
90
+ headers = cfg.on_complete_invalid.headers
91
+ elif atype.find("valid") > -1:
92
+ headers = cfg.on_complete_valid.headers
93
+ elif atype.find("error") > -1:
94
+ headers = cfg.on_complete_error.headers
95
+ else:
96
+ raise ValueError(f"Unknown type: {atype}")
97
+ #
98
+ # get raw headers
99
+ #
100
+ _ = {}
101
+ if headers and len(headers) > 0:
102
+ _ = {
103
+ header.name: header.value
104
+ for header in headers
105
+ if header.name and header.value
106
+ }
107
+ #
108
+ # do var sub. this looks goofy but it will have the correct source and do {} var sub
109
+ #
110
+ faux = "___never_say_never___"
111
+ headers = {}
112
+ for k, v in _.items():
113
+ self.config.set(section=faux, name=k, value=v)
114
+ v = self.config.get(section=faux, name=k)
115
+ headers[k] = v
116
+ self.config.config_parser.remove_section(faux)
117
+ return headers
118
+
82
119
  def _payload_for_type(self, mdata: Metadata, atype: str) -> dict:
83
120
  if mdata is None:
84
121
  raise ValueError("Metadata cannot be None")
@@ -20,9 +20,15 @@ class Scripts(BaseModel):
20
20
  on_complete_error: Optional[str] = None
21
21
 
22
22
 
23
+ class Header(BaseModel):
24
+ name: Optional[str] = None
25
+ value: Optional[str] = None
26
+
27
+
23
28
  class Webhook(BaseModel):
24
29
  url: Optional[str] = None
25
30
  payload: Optional[str] = None
31
+ headers: list[Header] = []
26
32
 
27
33
 
28
34
  class Webhooks(BaseModel):
@@ -85,7 +91,6 @@ class NamedPathsDescriber:
85
91
  configs = j[self.CONFIG]
86
92
  if "groups" in configs:
87
93
  configs = configs["groups"]
88
- print(f"configs: {configs}")
89
94
  for _k, _v in j[self.CONFIG].items():
90
95
  rms = []
91
96
  for k, v in _v.items():
@@ -331,7 +336,7 @@ class NamedPathsDescriber:
331
336
  else:
332
337
  raise ValueError(f"Script {path} not found")
333
338
 
334
- # ========== scripts ============
339
+ # ========== webhooks ============
335
340
 
336
341
  def store_webhooks(self, name: NamedPathsName, w: Webhooks) -> None:
337
342
  config = self.get_config(name)
@@ -390,7 +390,7 @@ class PathsManager:
390
390
  assure_definition: bool = True,
391
391
  ) -> str:
392
392
  self.last_add_metadata = None
393
- if template is not None:
393
+ if template is not None and str(template).strip() != "":
394
394
  #
395
395
  # this will raise an error. if that's a problem use temu.validate
396
396
  #
@@ -363,11 +363,7 @@ class ResultsManager: # pylint: disable=C0115
363
363
  print(f"regsman: me: {id(self)}")
364
364
  print(f"regsman: my csvpaths: {id(self.csvpaths)}")
365
365
  print(f"regsman: dylsi: {self.dynamic_run_listeners}")
366
- from csvpath.util.log_utility import LogUtility as lout
367
-
368
- lout.log_brief_trace()
369
366
  for _ in self.dynamic_run_listeners:
370
- print(f"regsman: adding int lsit: {_}")
371
367
  rr.add_internal_listener(_)
372
368
  rr.register_start(mdata)
373
369
  #
@@ -1,9 +1,9 @@
1
1
  # pylint: disable=C0114
2
2
 
3
- import os
4
3
  from smart_open import open
5
4
  from ..file_writers import DataFileWriter
6
5
  from csvpath.util.azure.azure_utils import AzureUtility
6
+ from csvpath.util.stopwatch import Stopwatch
7
7
 
8
8
 
9
9
  class AzureDataWriter(DataFileWriter):
@@ -13,17 +13,16 @@ class AzureDataWriter(DataFileWriter):
13
13
  if self.sink is None:
14
14
  client = AzureUtility.make_client()
15
15
  self.sink = open(
16
- self.path,
17
- self.mode,
18
- transport_params={"client": client},
19
- newline=''
16
+ self.path, self.mode, transport_params={"client": client}, newline=""
20
17
  )
21
18
  AzureDataWriter._write_file_count += 1
22
19
 
23
20
  def write(self, data) -> None:
24
21
  if self.is_binary and not isinstance(data, bytes):
25
22
  data = data.encode(self.encoding)
23
+ s = Stopwatch()
26
24
  self.sink.write(data)
25
+ s.end()
27
26
 
28
27
  def file_info(self) -> dict[str, str | int | float]:
29
28
  # TODO: what can/should we provide here?
@@ -1,6 +1,4 @@
1
1
  # pylint: disable=C0114
2
- import os
3
- from azure.storage.blob import BlobServiceClient, ContainerClient
4
2
  from azure.storage.blob._list_blobs_helper import BlobPrefix
5
3
  from .azure_utils import AzureUtility
6
4
  from ..path_util import PathUtility as pathu
@@ -100,8 +98,6 @@ class AzureDo:
100
98
  if files_only is True and dirs_only is True:
101
99
  raise ValueError("Cannot list with neither files nor dirs")
102
100
  container, blob = AzureUtility.path_to_parts(path)
103
-
104
- # listed = os.path.basename(self.path)
105
101
  if not blob.endswith("/"):
106
102
  blob = f"{blob}/"
107
103
  if blob == "/":
@@ -0,0 +1,14 @@
1
+ from azure.core.pipeline.policies import HTTPPolicy
2
+ import time
3
+
4
+
5
+ class TimingPolicy(HTTPPolicy):
6
+ def send(self, request):
7
+ start = time.perf_counter()
8
+ response = self.next.send(request)
9
+ elapsed = time.perf_counter() - start
10
+ url = request.http_request.url.split("?")[0] # strip query params
11
+ print(
12
+ f">>>>> timing policy: {elapsed:.3f}s — {request.http_request.method} {url} → {response.http_response.status_code}"
13
+ )
14
+ return response
@@ -1,5 +1,4 @@
1
- import os
2
- from azure.storage.blob import BlobServiceClient, BlobClient
1
+ from azure.storage.blob import BlobServiceClient
3
2
  from csvpath.util.box import Box
4
3
  from csvpath.util.config import Config
5
4
 
@@ -48,14 +47,22 @@ class AzureUtility:
48
47
  connection_string = config.get(
49
48
  section=None, name=cls.AZURE_STORAGE_CONNECTION_STRING
50
49
  )
51
- # connection_string = os.getenv(cls.AZURE_STORAGE_CONNECTION_STRING)
52
50
  if not connection_string:
53
51
  raise ValueError(
54
52
  f"{cls.AZURE_STORAGE_CONNECTION_STRING} environment variable not set."
55
53
  )
56
54
  client = BlobServiceClient.from_connection_string(connection_string)
57
55
  #
58
- # exp!
56
+ # if needed, use the following to dump call timings
57
+ #
58
+ # from .azure_timing_policy import TimingPolicy
59
+ # client = BlobServiceClient.from_connection_string(
60
+ # connection_string,
61
+ # _additional_pipeline_policies=[TimingPolicy()],
62
+ # read_timeout=5
63
+ # )
64
+ #
65
+ #
59
66
  #
60
67
  client.close = MyClose(client.close).close
61
68
  box.add(Box.AZURE_BLOB_CLIENT, client)
@@ -114,7 +114,7 @@ allow_local_files=True
114
114
 
115
115
  [listeners]
116
116
  # add listener group names to send events to the channel they represent
117
- groups = default
117
+ groups = default,activation
118
118
  #slack, openlineage, ckan, sftp, sftpplus, otlp, sqlite, sql
119
119
 
120
120
  # general purpose webhook caller
@@ -138,6 +138,9 @@ sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener
138
138
  default.file = from csvpath.managers.files.files_listener import FilesListener
139
139
  default.paths = from csvpath.managers.paths.paths_listener import PathsListener
140
140
 
141
+ # adds a listener that uses info in a named-file descriptor to create a run when data arrives
142
+ activation.file = from csvpath.managers.files.files_activation_listener import FileActivationListener
143
+
141
144
  # add otlp to the list of groups above to push observability metrics to an OpenTelemetry endpoint
142
145
  otlp.result = from csvpath.managers.integrations.otlp.otlp_result_listener import OpenTelemetryResultListener
143
146
  otlp.results = from csvpath.managers.integrations.otlp.otlp_results_listener import OpenTelemetryResultsListener
@@ -1,4 +1,3 @@
1
- import uuid
2
1
  import tempfile
3
2
  from smart_open import open
4
3
  from csvpath.util.hasher import Hasher
@@ -22,7 +21,7 @@ class SftpFingerprinter:
22
21
  Box().add(Box.CSVPATHS_CONFIG, config)
23
22
  return config
24
23
 
25
- def fingerprint(self, path: str) -> str:
24
+ def fingerprint(self, path: str, *, retry=True) -> str:
26
25
  config = self._config
27
26
  #
28
27
  #
@@ -55,5 +54,7 @@ class SftpFingerprinter:
55
54
  to.write(s)
56
55
  h = Hasher().hash(to)
57
56
  except Exception as e:
58
- print(f"SftpFingerprinter: second chance failed with {type(e)}: {e}")
57
+ print(f"SftpFingerprinter: second method failed with {type(e)}: {e}")
58
+ if retry is True:
59
+ return self.fingerprint(path, retry=False)
59
60
  return h
@@ -1,8 +1,6 @@
1
1
  # pylint: disable=C0114
2
- import os
3
2
  import paramiko
4
3
  import stat
5
- from stat import S_ISDIR, S_ISREG
6
4
  from csvpath import CsvPaths
7
5
  from csvpath.util.box import Box
8
6
  from ..path_util import PathUtility as pathu
@@ -10,6 +8,14 @@ from .sftp_config import SftpConfig
10
8
  from .sftp_walk import SftpWalk
11
9
 
12
10
 
11
+ #
12
+ # apr 2026. this class now does 1x retry to attempt to manage sketchy
13
+ # network conditions. it covers SftpWalk and fingerprinter. it does not
14
+ # cover the read and write classes. retrying a simple atomic operation
15
+ # feels reasonable. retrying a read or write feels potentially less
16
+ # safe and less like something we should cover for, rather than draw
17
+ # attention to.
18
+ #
13
19
  class SftpDo:
14
20
  @property
15
21
  def _config(self):
@@ -81,14 +87,19 @@ class SftpDo:
81
87
  return f"{self._orig_path}/{name}"
82
88
  # return f"{self.path}/{name}"
83
89
 
84
- def remove(self) -> None:
85
- if self.path == "/":
86
- raise ValueError("Cannot remove the root")
87
- if self.isfile():
88
- self._config.sftp_client.remove(self.path)
89
- else:
90
- walk = SftpWalk(self._config)
91
- walk.remove(self.path)
90
+ def remove(self, *, retry=True) -> None:
91
+ try:
92
+ if self.path == "/":
93
+ raise ValueError("Cannot remove the root")
94
+ if self.isfile():
95
+ self._config.sftp_client.remove(self.path)
96
+ else:
97
+ walk = SftpWalk(self._config)
98
+ walk.remove(self.path)
99
+ except Exception:
100
+ if retry is True:
101
+ self._config.reset()
102
+ self.remove(retry=False)
92
103
 
93
104
  def listdir(
94
105
  self,
@@ -97,53 +108,74 @@ class SftpDo:
97
108
  recurse: bool = False,
98
109
  dirs_only: bool = False,
99
110
  default=None,
111
+ retry=True,
100
112
  ) -> list[str]:
101
- if files_only is True and dirs_only is True:
102
- raise ValueError("Cannot list with neither files nor dirs")
103
- walk = SftpWalk(self._config)
104
- path = self.path
105
- lst = walk.listdir(path=path, default=[], recurse=recurse)
106
- if files_only is True:
107
- lst = [_ for _ in lst if _[1] is True]
108
- if dirs_only is True:
109
- lst = [_ for _ in lst if _[1] is False]
110
- if recurse is True:
111
- lst = [_[0] for _ in lst]
112
- else:
113
- lst2 = []
114
- path = path.lstrip("/")
115
- for _ in lst:
116
- t = _[0]
117
- t = t.lstrip("/")
118
- if t.startswith(path):
119
- t = t[len(path) + 1 :]
120
- if t.count("/") > 0:
121
- continue
122
- lst2.append(t)
123
- lst = lst2
124
- return lst
125
-
126
- def copy(self, to) -> None:
127
- if not self.exists():
128
- raise FileNotFoundError(f"Source {self.path} does not exist.")
129
- a = self._config.ssh_client
130
- a.set_missing_host_key_policy(paramiko.AutoAddPolicy())
131
- a.connect(
132
- self._config.server,
133
- port=self._config.port,
134
- username=self._config.username,
135
- password=self._config.password,
136
- allow_agent=False,
137
- look_for_keys=False,
138
- )
139
- stdin, stdout, stderr = a.exec_command(f"cp {self.path} {to}")
140
-
141
- def exists(self) -> bool:
113
+ try:
114
+ if files_only is True and dirs_only is True:
115
+ raise ValueError("Cannot list with neither files nor dirs")
116
+ walk = SftpWalk(self._config)
117
+ path = self.path
118
+ lst = walk.listdir(path=path, default=[], recurse=recurse)
119
+ if files_only is True:
120
+ lst = [_ for _ in lst if _[1] is True]
121
+ if dirs_only is True:
122
+ lst = [_ for _ in lst if _[1] is False]
123
+ if recurse is True:
124
+ lst = [_[0] for _ in lst]
125
+ else:
126
+ lst2 = []
127
+ path = path.lstrip("/")
128
+ for _ in lst:
129
+ t = _[0]
130
+ t = t.lstrip("/")
131
+ if t.startswith(path):
132
+ t = t[len(path) + 1 :]
133
+ if t.count("/") > 0:
134
+ continue
135
+ lst2.append(t)
136
+ lst = lst2
137
+ return lst
138
+ except Exception:
139
+ if retry is True:
140
+ self._config.reset()
141
+ return self.listdir(
142
+ files_only=files_only,
143
+ recurse=recurse,
144
+ dirs_only=dirs_only,
145
+ default=default,
146
+ retry=False,
147
+ )
148
+
149
+ def copy(self, to, *, retry=True) -> None:
150
+ try:
151
+ if not self.exists():
152
+ raise FileNotFoundError(f"Source {self.path} does not exist.")
153
+ a = self._config.ssh_client
154
+ a.set_missing_host_key_policy(paramiko.AutoAddPolicy())
155
+ a.connect(
156
+ self._config.server,
157
+ port=self._config.port,
158
+ username=self._config.username,
159
+ password=self._config.password,
160
+ allow_agent=False,
161
+ look_for_keys=False,
162
+ )
163
+ stdin, stdout, stderr = a.exec_command(f"cp {self.path} {to}")
164
+ except Exception:
165
+ if retry is True:
166
+ self._config.reset()
167
+ self.copy(self, to, retry=False)
168
+
169
+ def exists(self, *, retry=True) -> bool:
142
170
  try:
143
171
  self._config.sftp_client.stat(self.path)
144
172
  return True
145
173
  except FileNotFoundError:
146
174
  return False
175
+ except Exception:
176
+ if retry is True:
177
+ self._config.reset()
178
+ return self.exists(retry=False)
147
179
 
148
180
  def dir_exists(self) -> bool:
149
181
  try:
@@ -160,12 +192,16 @@ class SftpDo:
160
192
  except FileNotFoundError:
161
193
  return False
162
194
 
163
- def isdir(self, path) -> bool:
195
+ def isdir(self, path, *, retry=True) -> bool:
164
196
  try:
165
197
  attr = self._config.sftp_client.stat(path)
166
198
  return stat.S_ISDIR(attr.st_mode)
167
199
  except FileNotFoundError:
168
200
  return False
201
+ except Exception:
202
+ if retry is True:
203
+ self._config.reset()
204
+ return self.isdir(path, retry=False)
169
205
 
170
206
  def physical_dirs(self) -> bool:
171
207
  return True
@@ -192,14 +228,18 @@ class SftpDo:
192
228
  return r
193
229
  """
194
230
 
195
- def _isfile(self, path) -> bool:
231
+ def _isfile(self, path, *, retry=True) -> bool:
196
232
  try:
197
233
  attr = self._config.sftp_client.stat(path)
198
234
  return stat.S_ISREG(attr.st_mode)
199
235
  except FileNotFoundError:
200
236
  return False
237
+ except Exception:
238
+ if retry is True:
239
+ self._config.reset()
240
+ return self._isfile(path, retry=False)
201
241
 
202
- def rename(self, new_path: str) -> None:
242
+ def rename(self, new_path: str, *, retry=True) -> None:
203
243
  try:
204
244
  np = pathu.resep(new_path, hint="posix")
205
245
  np = pathu.stripp(np)
@@ -208,6 +248,10 @@ class SftpDo:
208
248
  raise
209
249
  except (IOError, PermissionError):
210
250
  raise RuntimeError(f"Failed to rename {self.path} to {new_path}")
251
+ except Exception:
252
+ if retry is True:
253
+ self._config.reset()
254
+ self.rename(new_path, retry=False)
211
255
 
212
256
  def makedirs(self) -> None:
213
257
  lst = self.path.split("/")
@@ -216,7 +260,7 @@ class SftpDo:
216
260
  path = f"{p}" if path == "" else f"{path}/{p}"
217
261
  self._mkdirs(path)
218
262
 
219
- def _mkdirs(self, path):
263
+ def _mkdirs(self, path, *, retry=False):
220
264
  try:
221
265
  self._config.sftp_client.mkdir(path)
222
266
  except OSError:
@@ -225,6 +269,10 @@ class SftpDo:
225
269
  except IOError:
226
270
  ...
227
271
  # TODO: should log
272
+ except Exception:
273
+ if retry is True:
274
+ self._config.reset()
275
+ self._mkdirs(path, retry=False)
228
276
 
229
277
  def makedir(self) -> None:
230
278
  self.makedirs()
@@ -0,0 +1,43 @@
1
+ import time
2
+
3
+
4
+ class Stopwatch:
5
+ #
6
+ # slow is the slow threshold as a number of ms
7
+ #
8
+ def __init__(self, slow=150, *, mark=None) -> None:
9
+ self.start = time.perf_counter()
10
+ self.last = time.perf_counter()
11
+ self.clicks = 0
12
+ self.slow = slow
13
+ space = "" if mark is None else " "
14
+ mark = "" if mark is None else mark
15
+ print(f"Stopwatch: {mark}{space}start: {self.start}")
16
+
17
+ def show(self, mark: str = ""):
18
+ self.click(mark, show=True)
19
+
20
+ def click(self, mark: str = "", *, show=False) -> None:
21
+ self.clicks = self.clicks + 1
22
+ t = time.perf_counter()
23
+ c = t - self.last
24
+ if show or c > self.slow:
25
+ s = t - self.start
26
+ space = " " if mark else ""
27
+ print(
28
+ f"Stopwatch: slow click: {mark}{space}{self.clicks}: {c} at time: {s} "
29
+ )
30
+ self.last = t
31
+
32
+ def start(self) -> None:
33
+ self.start = time.perf_counter()
34
+ self.last = time.perf_counter()
35
+ self.clicks = 0
36
+
37
+ def end(self, mark=None) -> None:
38
+ self.clicks = self.clicks + 1
39
+ t = time.perf_counter()
40
+ s = t - self.start
41
+ space = "" if mark is None else " "
42
+ mark = "" if mark is None else mark
43
+ print(f"Stopwatch: {mark}{space}end: {self.clicks}: {s} ")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "csvpath"
3
- version = "0.0.605"
3
+ version = "0.0.608"
4
4
  description = "CsvPath Framework is a data preboarding automation library for receiving, validating, and tracking CSV, Excel, JSONL and other tabular data files before they can corrupt downstream data consumers."
5
5
  authors = ["David Kershaw <info@csvpath.org>"]
6
6
  readme = "README.md"
File without changes
File without changes