csvpath 0.0.537__tar.gz → 0.0.538__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 (311) hide show
  1. {csvpath-0.0.537 → csvpath-0.0.538}/PKG-INFO +1 -1
  2. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-local-filesystem-mysql.ini +9 -8
  3. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/csvpath.py +9 -1
  4. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/files/file_manager.py +39 -4
  5. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/config.py +123 -106
  6. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/nos.py +2 -9
  7. {csvpath-0.0.537 → csvpath-0.0.538}/pyproject.toml +1 -1
  8. {csvpath-0.0.537 → csvpath-0.0.538}/LICENSE +0 -0
  9. {csvpath-0.0.537 → csvpath-0.0.538}/README.md +0 -0
  10. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/config.ini +0 -0
  11. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/function.imports +0 -0
  12. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-local-azure.ini +0 -0
  13. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-local-filesystem.ini +0 -0
  14. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-local-gcs.ini +0 -0
  15. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-local-sftp.ini +0 -0
  16. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-s3.ini +0 -0
  17. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-windows-azure.ini +0 -0
  18. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-windows-local.ini +0 -0
  19. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/jenkins-windows-sftp.ini +0 -0
  20. {csvpath-0.0.537 → csvpath-0.0.538}/assets/config/local-localhost-sftp.ini +0 -0
  21. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  22. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  23. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  24. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  25. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  26. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  27. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sqlite/csvpath +0 -0
  28. {csvpath-0.0.537 → csvpath-0.0.538}/assets/integrations/sqlite/schema.sql +0 -0
  29. {csvpath-0.0.537 → csvpath-0.0.538}/config/config.ini +0 -0
  30. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/__init__.py +0 -0
  31. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/__init__.py +0 -0
  32. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/asker.py +0 -0
  33. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/cli.py +0 -0
  34. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/const.py +0 -0
  35. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/debug_config.py +0 -0
  36. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/drill_down.py +0 -0
  37. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/function_describer.py +0 -0
  38. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/function_lister.py +0 -0
  39. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/cli/selecter.py +0 -0
  40. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/csvpaths.py +0 -0
  41. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/__init__.py +0 -0
  42. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/errors/error.py +0 -0
  43. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/errors/error_collector.py +0 -0
  44. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/errors/error_comms.py +0 -0
  45. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/errors/error_manager.py +0 -0
  46. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/files/file_metadata.py +0 -0
  47. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/files/file_registrar.py +0 -0
  48. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/files/files_listener.py +0 -0
  49. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  50. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  51. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  52. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  53. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  54. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/event.py +0 -0
  55. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/event_result.py +0 -0
  56. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
  57. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/job.py +0 -0
  58. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  59. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
  60. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
  61. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
  62. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/run.py +0 -0
  63. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
  64. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/run_state.py +0 -0
  65. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/ol/sender.py +0 -0
  66. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  67. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  68. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  69. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  70. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  71. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  72. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  73. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  74. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
  75. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
  76. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
  77. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
  78. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
  79. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/slack/event.py +0 -0
  80. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/slack/sender.py +0 -0
  81. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/engine.py +0 -0
  82. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  83. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  84. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  85. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  86. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  87. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/tables.py +0 -0
  88. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sql/updates.py +0 -0
  89. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  90. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  91. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  92. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
  93. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
  94. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/listener.py +0 -0
  95. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/metadata.py +0 -0
  96. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/paths/paths_listener.py +0 -0
  97. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/paths/paths_manager.py +0 -0
  98. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/paths/paths_metadata.py +0 -0
  99. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/paths/paths_registrar.py +0 -0
  100. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/registrar.py +0 -0
  101. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  102. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  103. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  104. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  105. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/readers/readers.py +0 -0
  106. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/result.py +0 -0
  107. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/result_file_reader.py +0 -0
  108. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/result_metadata.py +0 -0
  109. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/result_registrar.py +0 -0
  110. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/result_serializer.py +0 -0
  111. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/results_manager.py +0 -0
  112. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/results_metadata.py +0 -0
  113. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/results/results_registrar.py +0 -0
  114. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/run/run_listener_stdout.py +0 -0
  115. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/run/run_metadata.py +0 -0
  116. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/run/run_registrar.py +0 -0
  117. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/managers/test_listener.py +0 -0
  118. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/__init__.py +0 -0
  119. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/__init__.py +0 -0
  120. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/args.py +0 -0
  121. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/args_helper.py +0 -0
  122. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/all.py +0 -0
  123. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/andf.py +0 -0
  124. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/any.py +0 -0
  125. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/between.py +0 -0
  126. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/empty.py +0 -0
  127. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/exists.py +0 -0
  128. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/inf.py +0 -0
  129. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/no.py +0 -0
  130. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/notf.py +0 -0
  131. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/orf.py +0 -0
  132. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/boolean/yes.py +0 -0
  133. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/count.py +0 -0
  134. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  135. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/count_headers.py +0 -0
  136. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/count_lines.py +0 -0
  137. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/count_scans.py +0 -0
  138. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/counter.py +0 -0
  139. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/every.py +0 -0
  140. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/has_matches.py +0 -0
  141. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/increment.py +0 -0
  142. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/tally.py +0 -0
  143. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/counting/total_lines.py +0 -0
  144. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/dates/now.py +0 -0
  145. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/function.py +0 -0
  146. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/function_factory.py +0 -0
  147. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/function_finder.py +0 -0
  148. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/function_focus.py +0 -0
  149. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/append.py +0 -0
  150. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/collect.py +0 -0
  151. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  152. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/end.py +0 -0
  153. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/header_name.py +0 -0
  154. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  155. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/headers.py +0 -0
  156. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/insert.py +0 -0
  157. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/mismatch.py +0 -0
  158. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/replace.py +0 -0
  159. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  160. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/advance.py +0 -0
  161. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/after_blank.py +0 -0
  162. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/dups.py +0 -0
  163. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/first.py +0 -0
  164. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/first_line.py +0 -0
  165. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/last.py +0 -0
  166. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/lines/stop.py +0 -0
  167. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/above.py +0 -0
  168. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/add.py +0 -0
  169. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/divide.py +0 -0
  170. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/equals.py +0 -0
  171. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/intf.py +0 -0
  172. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/mod.py +0 -0
  173. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/multiply.py +0 -0
  174. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/odd.py +0 -0
  175. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/round.py +0 -0
  176. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/subtotal.py +0 -0
  177. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/subtract.py +0 -0
  178. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/math/sum.py +0 -0
  179. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  180. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/misc/importf.py +0 -0
  181. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/misc/random.py +0 -0
  182. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/print/jinjaf.py +0 -0
  183. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/print/print_line.py +0 -0
  184. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/print/print_queue.py +0 -0
  185. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/print/printf.py +0 -0
  186. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/print/table.py +0 -0
  187. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/stats/minf.py +0 -0
  188. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/stats/percent.py +0 -0
  189. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  190. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/stats/stdev.py +0 -0
  191. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/alter.py +0 -0
  192. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/caps.py +0 -0
  193. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/concat.py +0 -0
  194. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/contains.py +0 -0
  195. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/length.py +0 -0
  196. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/lower.py +0 -0
  197. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/metaphone.py +0 -0
  198. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/regex.py +0 -0
  199. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/starts_with.py +0 -0
  200. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/strip.py +0 -0
  201. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/substring.py +0 -0
  202. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/strings/upper.py +0 -0
  203. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/testing/debug.py +0 -0
  204. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/__init__.py +0 -0
  205. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/boolean.py +0 -0
  206. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/datef.py +0 -0
  207. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/decimal.py +0 -0
  208. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/email.py +0 -0
  209. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/nonef.py +0 -0
  210. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/string.py +0 -0
  211. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/type.py +0 -0
  212. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/types/url.py +0 -0
  213. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/validity/fail.py +0 -0
  214. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/validity/failed.py +0 -0
  215. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/validity/line.py +0 -0
  216. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/variables/get.py +0 -0
  217. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/variables/pushpop.py +0 -0
  218. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/variables/put.py +0 -0
  219. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/variables/track.py +0 -0
  220. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/functions/variables/variables.py +0 -0
  221. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/lark_parser.py +0 -0
  222. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/lark_transformer.py +0 -0
  223. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/matcher.py +0 -0
  224. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/__init__.py +0 -0
  225. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/equality.py +0 -0
  226. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/expression.py +0 -0
  227. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/header.py +0 -0
  228. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/matchable.py +0 -0
  229. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/qualified.py +0 -0
  230. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/reference.py +0 -0
  231. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/term.py +0 -0
  232. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/productions/variable.py +0 -0
  233. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/exceptions.py +0 -0
  234. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/expression_encoder.py +0 -0
  235. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/expression_utility.py +0 -0
  236. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/lark_print_parser.py +0 -0
  237. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/print_parser.py +0 -0
  238. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/matching/util/runtime_data_collector.py +0 -0
  239. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/error_mode.py +0 -0
  240. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/explain_mode.py +0 -0
  241. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/files_mode.py +0 -0
  242. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/logic_mode.py +0 -0
  243. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/mode_controller.py +0 -0
  244. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/print_mode.py +0 -0
  245. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/return_mode.py +0 -0
  246. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/run_mode.py +0 -0
  247. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/source_mode.py +0 -0
  248. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/transfer_mode.py +0 -0
  249. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/unmatched_mode.py +0 -0
  250. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/modes/validation_mode.py +0 -0
  251. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/__init__.py +0 -0
  252. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/exceptions.py +0 -0
  253. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/parser.out +0 -0
  254. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/parsetab.py +0 -0
  255. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/scanner.py +0 -0
  256. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/scanning/scanning_lexer.py +0 -0
  257. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_data_reader.py +0 -0
  258. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_data_writer.py +0 -0
  259. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  260. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_nos.py +0 -0
  261. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_utils.py +0 -0
  262. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  263. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/box.py +0 -0
  264. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/cache.py +0 -0
  265. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/caser.py +0 -0
  266. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/class_loader.py +0 -0
  267. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/code.py +0 -0
  268. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/config_exception.py +0 -0
  269. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/exceptions.py +0 -0
  270. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/file_info.py +0 -0
  271. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/file_readers.py +0 -0
  272. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/file_writers.py +0 -0
  273. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  274. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  275. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  276. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_nos.py +0 -0
  277. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_utils.py +0 -0
  278. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  279. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/hasher.py +0 -0
  280. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/http/http_data_reader.py +0 -0
  281. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/intermediary.py +0 -0
  282. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/last_line_stats.py +0 -0
  283. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/line_counter.py +0 -0
  284. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/line_monitor.py +0 -0
  285. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/line_spooler.py +0 -0
  286. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/log_utility.py +0 -0
  287. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/metadata_parser.py +0 -0
  288. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/pandas_data_reader.py +0 -0
  289. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/path_util.py +0 -0
  290. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/printer.py +0 -0
  291. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/references/files_reference_finder.py +0 -0
  292. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/references/ref_utils.py +0 -0
  293. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/references/reference_parser.py +0 -0
  294. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/references/results_reference_finder.py +0 -0
  295. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/run_home_maker.py +0 -0
  296. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_data_reader.py +0 -0
  297. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_data_writer.py +0 -0
  298. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  299. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_nos.py +0 -0
  300. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_utils.py +0 -0
  301. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  302. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_config.py +0 -0
  303. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_data_reader.py +0 -0
  304. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  305. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
  306. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_nos.py +0 -0
  307. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_walk.py +0 -0
  308. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  309. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/sqliter.py +0 -0
  310. {csvpath-0.0.537 → csvpath-0.0.538}/csvpath/util/template_util.py +0 -0
  311. {csvpath-0.0.537 → csvpath-0.0.538}/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.537
3
+ Version: 0.0.538
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
@@ -36,18 +36,19 @@ csvpaths = inputs/named_paths
36
36
  on_unmatched_file_fingerprints = halt
37
37
 
38
38
  [listeners]
39
- groups = default
39
+ groups = sql
40
+
40
41
  sql.file = from csvpath.managers.integrations.sql.sql_file_listener import SqlFileListener
41
42
  sql.paths = from csvpath.managers.integrations.sql.sql_paths_listener import SqlPathsListener
42
43
  sql.result = from csvpath.managers.integrations.sql.sql_result_listener import SqlResultListener
43
44
  sql.results = from csvpath.managers.integrations.sql.sql_results_listener import SqlResultsListener
44
- sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
45
- sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
46
- default.file = from csvpath.managers.files.files_listener import FilesListener
47
- default.paths = from csvpath.managers.paths.paths_listener import PathsListener
48
45
  otlp.result = from csvpath.managers.integrations.otlp.otlp_result_listener import OpenTelemetryResultListener
49
46
  otlp.results = from csvpath.managers.integrations.otlp.otlp_results_listener import OpenTelemetryResultsListener
50
47
  otlp.errors = from csvpath.managers.integrations.otlp.otlp_error_listener import OpenTelemetryErrorListener
48
+ default.file = from csvpath.managers.files.files_listener import FilesListener
49
+ default.paths = from csvpath.managers.paths.paths_listener import PathsListener
50
+ sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
51
+ sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
51
52
  sftpplus.paths = from csvpath.managers.integrations.sftpplus.sftpplus_listener import SftpPlusListener
52
53
  sftp.results = from csvpath.managers.integrations.sftp.sftp_listener import SftpListener
53
54
  ckan.results = from csvpath.managers.integrations.ckan.ckan_listener import CkanListener
@@ -68,7 +69,7 @@ password = tinpenny
68
69
 
69
70
  [sql]
70
71
  dialect = mysql
71
- connection_string = mysql://csvpath:hangzhou@192.168.66.1/csvpath
72
+ connection_string = mysql://csvpath:password1@192.168.66.1/csvpath
72
73
 
73
74
  [sqlite]
74
75
  db = archive/csvpath.db
@@ -81,7 +82,7 @@ port = SFTPPLUS_PORT
81
82
  admin_username = SFTPPLUS_ADMIN_USERNAME
82
83
  admin_password = SFTPPLUS_ADMIN_PASSWORD
83
84
  api_url = https://localhost:10020/json
84
- scripts_dir =
85
+ scripts_dir =
85
86
  execute_timeout = 300
86
87
 
87
88
  [ckan]
@@ -96,5 +97,5 @@ timeout = 5
96
97
  verify = False
97
98
 
98
99
  [slack]
99
- webhook_url =
100
+ webhook_url =
100
101
 
@@ -824,7 +824,15 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
824
824
  if self.csvpaths is None:
825
825
  return data
826
826
  name = self._get_name(data)
827
- path = self.csvpaths.file_manager.get_named_file(name)
827
+ #
828
+ # this will blow up frequently when name is an actual path. ie name == path
829
+ # below. since we want file manager to be discriminating we have to catch
830
+ # the error and reset the name
831
+ #
832
+ try:
833
+ path = self.csvpaths.file_manager.get_named_file(name)
834
+ except ValueError:
835
+ path = name
828
836
  if path is None:
829
837
  return data
830
838
  if path == name:
@@ -295,6 +295,14 @@ class FileManager:
295
295
  # this feels like the better sig.
296
296
  #
297
297
  def has_named_file(self, name: NamedFileName) -> bool:
298
+ #
299
+ # cannot be a reference or part of a reference. has to just
300
+ # be the simple name of the named file.
301
+ #
302
+ self.legal_name(name)
303
+ #
304
+ # the home should exist if the named file exists.
305
+ #
298
306
  p = self.named_file_home(name)
299
307
  nos = self.nos
300
308
  nos.path = p
@@ -310,11 +318,19 @@ class FileManager:
310
318
 
311
319
  def remove_named_file(self, name: NamedFileName) -> None:
312
320
  """@private"""
321
+ #
322
+ # cannot delete any specific files. this is for the named_file
323
+ # as a whole. the named_file is immutable, so this is all-or-nothing
324
+ # and we expect it to happen rarely in a production env.
325
+ #
326
+ self.legal_name(name)
313
327
  p = os.path.join(self.named_files_dir, name)
314
328
  nos = self.nos
315
329
  nos.path = p
316
330
  if nos.exists():
317
331
  nos.remove()
332
+ return True
333
+ return False
318
334
 
319
335
  def remove_all_named_files(self) -> None:
320
336
  """@private"""
@@ -351,6 +367,20 @@ class FileManager:
351
367
  if self.csvpaths.ecoms.do_i_raise():
352
368
  raise
353
369
 
370
+ def legal_name(self, name:str) -> None:
371
+ if name is None:
372
+ raise ValueError("Name cannot be None")
373
+ if name.strip() == "":
374
+ raise ValueError("Name cannot be empty")
375
+ if name.find("/") > -1 or name.find("\\") > -1:
376
+ raise ValueError(f"Not a legal name: {name}. Path seperators are not allowed.")
377
+ if name.find(".") > -1:
378
+ raise ValueError(f"Not a legal name: {name}. Periods are not allowed.")
379
+ if name.find("$") > -1:
380
+ raise ValueError(f"Not a legal name: {name}. Dollarsigns are not allowed.")
381
+ if name.find("#") > -1:
382
+ raise ValueError(f"Not a legal name: {name}. Hashmarks are not allowed.")
383
+
354
384
  #
355
385
  # if name is provided all files selected will be registered under the same name in
356
386
  # the order they are found; which is likely not deterministic. template, if any, is
@@ -364,8 +394,12 @@ class FileManager:
364
394
  def add_named_files_from_dir(
365
395
  self, dirname: str, *, name=None, template: str = None, recurse=True
366
396
  ):
367
- if dirname is None or dirname.strip() == "":
368
- raise ValueError("Dirname cannot be None or empty")
397
+ #
398
+ # legal_name handled at add_named_file
399
+ #
400
+ #self.legal_name(name)
401
+ #if dirname is None or dirname.strip() == "":
402
+ # raise ValueError("Dirname cannot be None or empty")
369
403
  #
370
404
  # need to support adding all files from directory under the same name. preferably
371
405
  # in order of file created time, if possible.
@@ -405,8 +439,9 @@ class FileManager:
405
439
  def add_named_file(
406
440
  self, *, name: NamedFileName, path: str, template: str = None
407
441
  ) -> None:
408
- if name is None or name.strip() == "":
409
- raise ValueError("Name cannot be None or empty")
442
+ self.legal_name(name)
443
+ #if name is None or name.strip() == "":
444
+ # raise ValueError("Name cannot be None or empty")
410
445
  if path is None or path.strip() == "":
411
446
  raise ValueError("Path cannot be None or empty")
412
447
  if template is not None:
@@ -71,8 +71,6 @@ class Config:
71
71
 
72
72
  def __init__(self, *, load=True):
73
73
  self.load = load
74
- self._cache_dir_path = None
75
- self._function_imports = None
76
74
  self._additional_listeners = None
77
75
  self._csvpath_file_extensions = None
78
76
  self._csv_file_extensions = None
@@ -83,12 +81,11 @@ class Config:
83
81
  self._log_file = None
84
82
  self._log_files_to_keep = None
85
83
  self._log_file_size = None
86
- self._archive_path = None
87
- self._transfer_root = None
88
- self._inputs_files_path = None
89
- self._inputs_csvpaths_path = None
90
84
  self._config = RawConfigParser()
91
85
  self.log_file_handler = None
86
+ #
87
+ # if env is set it wins out over anything else.
88
+ #
92
89
  self._configpath = environ.get(Config.CSVPATH_CONFIG_FILE_ENV)
93
90
  if self._configpath is None:
94
91
  self._configpath = Config.CONFIG
@@ -116,19 +113,34 @@ class Config:
116
113
  def config_path(self) -> str:
117
114
  return self._configpath
118
115
 
116
+ @property
117
+ def sections(self) -> list[str]:
118
+ return self._config.sections()
119
+
119
120
  def get(self, *, section: str, name: str, default=None):
120
121
  return self._get(section, name, default)
121
122
 
122
123
  def _get(self, section: str, name: str, default=None):
124
+ #
125
+ # TODO: we should swap all uppercase values for env var values if we find a
126
+ # matching env var. same as we do for metadata values
127
+ #
123
128
  if self._config is None:
124
129
  raise ConfigurationException("No config object available")
125
130
  try:
126
131
  s = self._config[section][name]
127
132
  ret = None
128
- if s.find(",") > -1:
133
+ if s and isinstance(s, str) and s.find(",") > -1:
129
134
  ret = [s.strip() for s in s.split(",")]
130
- else:
135
+ elif isinstance(s, str):
131
136
  ret = s.strip()
137
+ else:
138
+ ret = s
139
+
140
+ if ret and isinstance(ret, str) and ret.isupper():
141
+ v2 = os.getenv(ret)
142
+ if v2 is not None:
143
+ ret = v2.strip()
132
144
  return ret
133
145
  except KeyError:
134
146
  if self.csvpath_log_level == LogLevels.DEBUG:
@@ -137,6 +149,11 @@ class Config:
137
149
  )
138
150
  return default
139
151
 
152
+ def _set(self, section, key, value) -> None:
153
+ if isinstance( value, list ):
154
+ value = ",".join(value)
155
+ self._config.set(section, key, value)
156
+
140
157
  #
141
158
  # adds the value to the internal configparser object. doesn't save.
142
159
  # does a refresh to make sure any lists or other interpreted values
@@ -172,15 +189,11 @@ class Config:
172
189
  os.makedirs(directory)
173
190
  with open(self._configpath, "w", encoding="utf-8") as file:
174
191
  c = f"""
175
- [csvpath_files]
176
- extensions = txt, csvpath, csvpaths
177
-
178
- [csv_files]
179
- extensions = txt, csv, tsv, dat, tab, psv, ssv
192
+ [extensions]
193
+ csvpath_files = csvpath, csvpaths
194
+ csv_files = txt, csv, tsv, dat, tab, psv, ssv
180
195
 
181
196
  [errors]
182
- csvpath = collect, fail, print
183
- csvpaths = raise, collect
184
197
  use_format = full
185
198
  pattern = {{time}}:{{file}}:{{line}}:{{paths}}:{{instance}}:{{chain}}: {{message}}
186
199
 
@@ -189,7 +202,7 @@ csvpath = info
189
202
  csvpaths = info
190
203
  log_file = logs{os.sep}csvpath.log
191
204
  log_files_to_keep = 100
192
- log_file_size = 52428800
205
+ log_file_size = 50000000
193
206
  # file or rotating
194
207
  handler = file
195
208
 
@@ -314,7 +327,19 @@ shell = /bin/bash
314
327
 
315
328
 
316
329
  """
330
+
317
331
  file.write(c)
332
+ #
333
+ # writing a new config means we want to immediately load it?
334
+ # possibly not.
335
+ #
336
+ self._assure_logs_path()
337
+ self._assure_archive_path()
338
+ self._assure_transfer_root()
339
+ self._assure_inputs_files_path()
340
+ self._assure_cache_path()
341
+ self._assure_inputs_csvpaths_path()
342
+
318
343
  print(f"Created a default config file at {directory} with name {name}.")
319
344
  print("If you want your config to be somewhere else remember to")
320
345
  print("update the path in the default config.ini")
@@ -391,15 +416,18 @@ shell = /bin/bash
391
416
  if uc and uc.strip().lower() == "no":
392
417
  return
393
418
  if self.load:
394
- if self.cache_dir_path is None or self.cache_dir_path.strip() == "":
395
- self.cache_dir_path = "cache"
396
- if self.cache_dir_path.find("://") > -1:
419
+ p = self._get("cache", "path", "cache")
420
+ if p:
421
+ p = p.strip()
422
+ if p == "":
423
+ self._set("cache", "use_cache", "no")
424
+ return
425
+ if p.find("://") > -1:
397
426
  raise ConfigurationException(
398
- f"Cache dir must be on the local drive, not {self.cache_dir_path}"
427
+ f"Cache dir must be on the local drive, not {p}"
399
428
  )
400
- exists = path.exists(self.cache_dir_path)
401
- if not exists:
402
- os.makedirs(self.cache_dir_path)
429
+ if not os.path.exists(p):
430
+ os.makedirs(p)
403
431
 
404
432
  def _assure_config_file_path(self) -> None:
405
433
  if self.load:
@@ -424,42 +452,33 @@ shell = /bin/bash
424
452
  # file, it just gathers and translates settings for external use.
425
453
  #
426
454
  def refresh(self) -> None:
427
- self.csvpath_file_extensions = self._get(
428
- Sections.CSVPATH_FILES.value, "extensions"
429
- )
430
- self.csv_file_extensions = self._get(Sections.CSV_FILES.value, "extensions")
431
-
432
- self.csvpath_errors_policy = self._get(Sections.ERRORS.value, "csvpath")
433
- self.csvpaths_errors_policy = self._get(Sections.ERRORS.value, "csvpaths")
455
+ #
456
+ # the sections: csv_files and csvpath_files are deprecated in favor of
457
+ # a single extensions section with csv_files and csvpath_files as keys.
458
+ # is is a simpler way to go and will UI better. the old way can hang about
459
+ # for a release or two, but should be retired soon.
460
+ #
461
+ #
462
+ # file extensions will reload themselves as long as we clear them
463
+ #
464
+ self.csvpath_file_extensions = None
465
+ self.csv_file_extensions = None
466
+ #
467
+ #
468
+ #
469
+ self.csvpath_errors_policy = self._get(Sections.ERRORS.value, "csvpath", ["raise", "print", "stop", "fail", "collect"])
470
+ self.csvpaths_errors_policy = self._get(Sections.ERRORS.value, "csvpaths", ["raise", "print", "stop", "fail", "collect"])
434
471
 
435
472
  self.csvpath_log_level = self._get(Sections.LOGGING.value, "csvpath")
436
473
  self.csvpaths_log_level = self._get(Sections.LOGGING.value, "csvpaths")
437
474
 
438
475
  self.log_file = self._get(Sections.LOGGING.value, LogFile.LOG_FILE.value)
439
476
  self.log_files_to_keep = self._get(
440
- Sections.LOGGING.value, LogFile.LOG_FILES_TO_KEEP.value
477
+ Sections.LOGGING.value, LogFile.LOG_FILES_TO_KEEP.value, 10
441
478
  )
442
479
  self.log_file_size = self._get(
443
- Sections.LOGGING.value, LogFile.LOG_FILE_SIZE.value
480
+ Sections.LOGGING.value, LogFile.LOG_FILE_SIZE.value, 12800000
444
481
  )
445
- # path to external functions list. external functions are very optional.
446
- # not blowing up when absent seems reasonable.
447
- try:
448
- self.function_imports = self._get(Sections.FUNCTIONS.value, "imports")
449
- except Exception:
450
- print(
451
- "WARNING: config cannot load [functions][imports] from {self.configpath}"
452
- )
453
- pass
454
- # likewise caching.
455
- try:
456
- self.cache_dir_path = self._get(Sections.CACHE.value, "path")
457
- except Exception:
458
- print("WARNING: config cannot load [cache][path] from {self.configpath}")
459
- pass
460
- #
461
- # reload if another config path is set
462
- #
463
482
  path = self._get("config", "path")
464
483
  if path:
465
484
  path = path.strip().lower()
@@ -471,23 +490,6 @@ shell = /bin/bash
471
490
 
472
491
  def validate_config(self) -> None:
473
492
  #
474
- # files
475
- #
476
- if (
477
- self.csvpath_file_extensions is None
478
- or not isinstance(self.csvpath_file_extensions, list)
479
- or not len(self.csvpath_file_extensions) > 0
480
- ):
481
- raise ConfigurationException(
482
- f"CsvPath file extensions are wrong: {self.csvpath_file_extensions}"
483
- )
484
- if (
485
- self.csv_file_extensions is None
486
- or not isinstance(self.csv_file_extensions, list)
487
- or not len(self.csv_file_extensions) > 0
488
- ):
489
- raise ConfigurationException("CSV file extensions are wrong")
490
- #
491
493
  # error policies
492
494
  #
493
495
  if (
@@ -582,11 +584,11 @@ shell = /bin/bash
582
584
 
583
585
  @property
584
586
  def cache_dir_path(self) -> str:
585
- return self._cache_dir_path
587
+ return self._get("cache", "path")
586
588
 
587
589
  @cache_dir_path.setter
588
590
  def cache_dir_path(self, p) -> None:
589
- self._cache_dir_path = p
591
+ self._set("cache", "path", p )
590
592
 
591
593
  def halt_on_unmatched_file_fingerprints(self) -> bool:
592
594
  houf = self._get("inputs", "on_unmatched_file_fingerprints")
@@ -598,29 +600,19 @@ shell = /bin/bash
598
600
 
599
601
  @property
600
602
  def transfer_root(self) -> str:
601
- if self._transfer_root is None:
602
- self._transfer_root = self._get("results", "transfers")
603
- if self._transfer_root is None:
604
- self._transfer_root = "transfers"
605
- self.add_to_config("results", "transfers", "transfers")
606
- return self._transfer_root
603
+ return self._get("results", "transfers", "transfers")
607
604
 
608
605
  @transfer_root.setter
609
606
  def transfer_root(self, p) -> None:
610
- self._transfer_root = p
607
+ self._set("results", "transfers", p)
611
608
 
612
609
  @property
613
610
  def archive_path(self) -> str:
614
- if self._archive_path is None:
615
- self._archive_path = self._get("results", "archive")
616
- if self._archive_path is None:
617
- self._archive_path = "archive"
618
- self.add_to_config("results", "archive", "archive")
619
- return self._archive_path
611
+ return self._get("results", "archive", "archive")
620
612
 
621
613
  @archive_path.setter
622
614
  def archive_path(self, p) -> None:
623
- self._archive_path = p
615
+ self._set("results", "archive", p)
624
616
 
625
617
  @property
626
618
  def archive_name(self) -> str:
@@ -631,40 +623,40 @@ shell = /bin/bash
631
623
 
632
624
  @property
633
625
  def inputs_files_path(self) -> str:
634
- if self._inputs_files_path is None:
635
- self._inputs_files_path = self._get("inputs", "files")
636
- if self._inputs_files_path is None:
637
- self._inputs_files_path = "inputs"
638
- self.add_to_config("inputs", "files", f"inputs{os.sep}named_files")
639
- return self._inputs_files_path
626
+ return self._get("inputs", "files", f"inputs{os.sep}named_files")
640
627
 
641
628
  @inputs_files_path.setter
642
629
  def inputs_files_path(self, p) -> None:
643
- self._inputs_files_path = p
630
+ self._set("inputs", "files", p)
644
631
 
645
632
  @property
646
633
  def inputs_csvpaths_path(self) -> str:
647
- if self._inputs_csvpaths_path is None:
648
- self._inputs_csvpaths_path = self._get("inputs", "csvpaths")
649
- if self._inputs_csvpaths_path is None:
650
- self._inputs_csvpaths_path = "inputs"
651
- self.add_to_config("inputs", "csvpaths", f"inputs{os.sep}named_paths")
652
- return self._inputs_csvpaths_path
634
+ return self._get("inputs", "csvpaths", f"inputs{os.sep}named_paths")
653
635
 
654
636
  @inputs_csvpaths_path.setter
655
637
  def inputs_csvpaths_path(self, p) -> None:
656
- self._inputs_csvpaths_path = p
638
+ self._set("inputs", "csvpaths", p)
657
639
 
658
640
  @property
659
641
  def function_imports(self) -> str:
660
- return self._function_imports
642
+ return self._get(Sections.FUNCTIONS.value, "imports", "imports")
661
643
 
662
644
  @function_imports.setter
663
645
  def function_imports(self, path: str) -> None:
664
- self._function_imports = path
646
+ self._set( Sections.FUNCTIONS.value, "imports", path)
665
647
 
666
648
  @property
667
649
  def csvpath_file_extensions(self) -> list[str]:
650
+ if self._csvpath_file_extensions is None:
651
+ cs = self._get("extensions", "csvpath_files")
652
+ if not cs or len(cs) == 0:
653
+ #
654
+ # the old way
655
+ #
656
+ cs = self._get(Sections.CSVPATH_FILES.value, "extensions")
657
+ if not cs or len(cs) == 0:
658
+ cs = ["csvpath","csvpaths"]
659
+ self._csvpath_file_extensions = cs
668
660
  return self._csvpath_file_extensions
669
661
 
670
662
  @csvpath_file_extensions.setter
@@ -675,6 +667,16 @@ shell = /bin/bash
675
667
 
676
668
  @property
677
669
  def csv_file_extensions(self) -> list[str]:
670
+ if self._csv_file_extensions is None:
671
+ cs = self._get("extensions", "csv_files")
672
+ if not cs or len(cs) == 0:
673
+ #
674
+ # the old way
675
+ #
676
+ cs = self._get(Sections.CSV_FILES.value, "extensions")
677
+ if not cs or len(cs) == 0:
678
+ cs = ["csv","xlsx"]
679
+ self._csv_file_extensions = cs
678
680
  return self._csv_file_extensions
679
681
 
680
682
  @csv_file_extensions.setter
@@ -729,22 +731,37 @@ shell = /bin/bash
729
731
 
730
732
  @property
731
733
  def log_files_to_keep(self) -> int:
732
- return self._log_files_to_keep
734
+ fs = self._get(Sections.LOGGING.value, LogFile.LOG_FILES_TO_KEEP.value, 10)
735
+ try:
736
+ fs = int(fs)
737
+ except ValueError:
738
+ return 10
739
+ return fs
733
740
 
734
741
  @log_files_to_keep.setter
735
742
  def log_files_to_keep(self, i: int) -> None:
736
743
  try:
737
- self._log_files_to_keep = int(i)
738
- except (TypeError, ValueError):
739
- raise ConfigurationException("Error in log_files_to_keep config")
744
+ i = int(i)
745
+ except (ValueError, TypeError):
746
+ i = 10
747
+ self._set(Sections.LOGGING.value, LogFile.LOG_FILES_TO_KEEP.value, i)
740
748
 
741
749
  @property
742
750
  def log_file_size(self) -> int:
743
- return self._log_file_size
751
+ fs = self._get(Sections.LOGGING.value, LogFile.LOG_FILE_SIZE.value, 12800000)
752
+ try:
753
+ fs = int(fs)
754
+ except ValueError:
755
+ fs = 12800000
756
+ return fs
744
757
 
745
758
  @log_file_size.setter
746
759
  def log_file_size(self, i: int) -> None:
747
760
  try:
748
- self._log_file_size = int(i)
761
+ i = int(i)
749
762
  except (TypeError, ValueError):
750
- raise ConfigurationException("Error in log_files_size config")
763
+ i = 12800000
764
+ self._set(Sections.LOGGING.value, LogFile.LOG_FILE_SIZE.value, i)
765
+
766
+
767
+
@@ -88,12 +88,8 @@ class Nos:
88
88
  return self.do.dir_exists()
89
89
 
90
90
  def physical_dirs(self) -> bool:
91
- """True if dirs may exist.
92
- False if there is no concept of dirs
93
- that are independent from objects.
94
- Cloud objects stores like S3 are the
95
- latter.
96
- """
91
+ """True if dirs can exist independently. False if there is no concept of dirs
92
+ that are independent from objects. Cloud objects stores like S3 are the latter."""
97
93
  return self.do.physical_dirs()
98
94
 
99
95
  def rename(self, new_path: str) -> None:
@@ -108,9 +104,6 @@ class Nos:
108
104
  def makedir(self) -> None:
109
105
  self.do.makedir()
110
106
 
111
- #
112
- # listdir should be assumed to be unordered.
113
- #
114
107
  def listdir(
115
108
  self,
116
109
  *,
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "csvpath"
3
- version = "0.0.537"
3
+ version = "0.0.538"
4
4
  description = "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
  authors = ["David Kershaw <dk107dk@hotmail.com>"]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes