csvpath 0.0.496__tar.gz → 0.0.498__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 (276) hide show
  1. {csvpath-0.0.496 → csvpath-0.0.498}/PKG-INFO +6 -4
  2. {csvpath-0.0.496 → csvpath-0.0.498}/config/config.ini +6 -0
  3. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/csvpath.py +6 -23
  4. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/csvpaths.py +147 -54
  5. csvpath-0.0.498/csvpath/managers/files/file_cacher.py +50 -0
  6. csvpath-0.0.498/csvpath/managers/files/file_listener_ol.py +27 -0
  7. csvpath-0.0.498/csvpath/managers/files/file_manager.py +265 -0
  8. csvpath-0.0.498/csvpath/managers/files/file_metadata.py +22 -0
  9. csvpath-0.0.498/csvpath/managers/files/file_registrar.py +145 -0
  10. csvpath-0.0.498/csvpath/managers/listener.py +16 -0
  11. csvpath-0.0.498/csvpath/managers/metadata.py +142 -0
  12. csvpath-0.0.498/csvpath/managers/ol/event.py +185 -0
  13. csvpath-0.0.498/csvpath/managers/ol/event_result.py +207 -0
  14. csvpath-0.0.498/csvpath/managers/ol/job.py +166 -0
  15. csvpath-0.0.498/csvpath/managers/ol/run.py +97 -0
  16. csvpath-0.0.498/csvpath/managers/ol/run_state.py +56 -0
  17. csvpath-0.0.498/csvpath/managers/paths/paths_listener_ol.py +27 -0
  18. {csvpath-0.0.496/csvpath/managers → csvpath-0.0.498/csvpath/managers/paths}/paths_manager.py +140 -154
  19. csvpath-0.0.498/csvpath/managers/paths/paths_metadata.py +13 -0
  20. csvpath-0.0.498/csvpath/managers/paths/paths_registrar.py +123 -0
  21. csvpath-0.0.498/csvpath/managers/registrar.py +60 -0
  22. {csvpath-0.0.496/csvpath/managers → csvpath-0.0.498/csvpath/managers/results}/result.py +72 -29
  23. csvpath-0.0.498/csvpath/managers/results/result_listener_ol.py +27 -0
  24. csvpath-0.0.498/csvpath/managers/results/result_metadata.py +116 -0
  25. csvpath-0.0.498/csvpath/managers/results/result_registrar.py +247 -0
  26. {csvpath-0.0.496/csvpath/managers → csvpath-0.0.498/csvpath/managers/results}/result_serializer.py +11 -3
  27. csvpath-0.0.498/csvpath/managers/results/results_listener_ol.py +28 -0
  28. {csvpath-0.0.496/csvpath/managers → csvpath-0.0.498/csvpath/managers/results}/results_manager.py +119 -144
  29. csvpath-0.0.498/csvpath/managers/results/results_metadata.py +40 -0
  30. csvpath-0.0.498/csvpath/managers/results/results_registrar.py +169 -0
  31. csvpath-0.0.498/csvpath/managers/run/run_listener_ol.py +30 -0
  32. csvpath-0.0.498/csvpath/managers/run/run_listener_stdout.py +15 -0
  33. csvpath-0.0.498/csvpath/managers/run/run_metadata.py +10 -0
  34. csvpath-0.0.498/csvpath/managers/run/run_registrar.py +51 -0
  35. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/dates/now.py +2 -2
  36. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/replace.py +0 -1
  37. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/expression_utility.py +1 -1
  38. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/source_mode.py +2 -1
  39. csvpath-0.0.498/csvpath/util/class_loader.py +26 -0
  40. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/config.py +33 -5
  41. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/error.py +3 -3
  42. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/file_readers.py +2 -0
  43. {csvpath-0.0.496/csvpath/managers → csvpath-0.0.498/csvpath/util}/line_spooler.py +3 -5
  44. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/metadata_parser.py +3 -1
  45. {csvpath-0.0.496 → csvpath-0.0.498}/pyproject.toml +11 -6
  46. csvpath-0.0.496/csvpath/managers/file_manager.py +0 -239
  47. csvpath-0.0.496/csvpath/managers/file_registrar.py +0 -203
  48. csvpath-0.0.496/csvpath/managers/paths_registrar.py +0 -115
  49. csvpath-0.0.496/csvpath/managers/result_registrar.py +0 -129
  50. csvpath-0.0.496/csvpath/managers/results_registrar.py +0 -69
  51. csvpath-0.0.496/csvpath/util/csvpaths_registrar.py +0 -99
  52. {csvpath-0.0.496 → csvpath-0.0.498}/LICENSE +0 -0
  53. {csvpath-0.0.496 → csvpath-0.0.498}/README.md +0 -0
  54. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/__init__.py +0 -0
  55. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/cli/__init__.py +0 -0
  56. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/cli/cli.py +0 -0
  57. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/cli/drill_down.py +0 -0
  58. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/managers/__init__.py +0 -0
  59. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/__init__.py +0 -0
  60. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/__init__.py +0 -0
  61. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/args.py +0 -0
  62. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/all.py +0 -0
  63. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/andf.py +0 -0
  64. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/any.py +0 -0
  65. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/between.py +0 -0
  66. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/empty.py +0 -0
  67. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/exists.py +0 -0
  68. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/inf.py +0 -0
  69. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/no.py +0 -0
  70. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/notf.py +0 -0
  71. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/orf.py +0 -0
  72. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/boolean/yes.py +0 -0
  73. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/count.py +0 -0
  74. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  75. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/count_headers.py +0 -0
  76. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/count_lines.py +0 -0
  77. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/count_scans.py +0 -0
  78. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/counter.py +0 -0
  79. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/every.py +0 -0
  80. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/has_matches.py +0 -0
  81. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/increment.py +0 -0
  82. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/tally.py +0 -0
  83. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/counting/total_lines.py +0 -0
  84. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/function.py +0 -0
  85. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/function_factory.py +0 -0
  86. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/function_finder.py +0 -0
  87. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/function_focus.py +0 -0
  88. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/append.py +0 -0
  89. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/collect.py +0 -0
  90. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  91. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/end.py +0 -0
  92. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/header_name.py +0 -0
  93. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  94. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/headers.py +0 -0
  95. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/mismatch.py +0 -0
  96. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  97. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/advance.py +0 -0
  98. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/after_blank.py +0 -0
  99. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/dups.py +0 -0
  100. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/first.py +0 -0
  101. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/first_line.py +0 -0
  102. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/last.py +0 -0
  103. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/lines/stop.py +0 -0
  104. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/above.py +0 -0
  105. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/add.py +0 -0
  106. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/divide.py +0 -0
  107. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/equals.py +0 -0
  108. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/intf.py +0 -0
  109. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/mod.py +0 -0
  110. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/multiply.py +0 -0
  111. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/round.py +0 -0
  112. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/subtotal.py +0 -0
  113. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/subtract.py +0 -0
  114. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/math/sum.py +0 -0
  115. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  116. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/misc/importf.py +0 -0
  117. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/misc/random.py +0 -0
  118. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/print/jinjaf.py +0 -0
  119. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/print/print_line.py +0 -0
  120. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/print/print_queue.py +0 -0
  121. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/print/printf.py +0 -0
  122. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/print/table.py +0 -0
  123. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/stats/minf.py +0 -0
  124. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/stats/percent.py +0 -0
  125. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  126. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/stats/stdev.py +0 -0
  127. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/concat.py +0 -0
  128. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/length.py +0 -0
  129. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/lower.py +0 -0
  130. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/metaphone.py +0 -0
  131. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/regex.py +0 -0
  132. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/starts_with.py +0 -0
  133. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/strip.py +0 -0
  134. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/substring.py +0 -0
  135. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/strings/upper.py +0 -0
  136. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/testing/debug.py +0 -0
  137. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/__init__.py +0 -0
  138. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/boolean.py +0 -0
  139. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/datef.py +0 -0
  140. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/decimal.py +0 -0
  141. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/nonef.py +0 -0
  142. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/string.py +0 -0
  143. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/types/type.py +0 -0
  144. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/validity/fail.py +0 -0
  145. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/validity/failed.py +0 -0
  146. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/validity/line.py +0 -0
  147. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/variables/get.py +0 -0
  148. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/variables/pushpop.py +0 -0
  149. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/variables/put.py +0 -0
  150. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/variables/track.py +0 -0
  151. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/functions/variables/variables.py +0 -0
  152. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/lark_parser.py +0 -0
  153. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/lark_transformer.py +0 -0
  154. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/matcher.py +0 -0
  155. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/__init__.py +0 -0
  156. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/equality.py +0 -0
  157. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/expression.py +0 -0
  158. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/header.py +0 -0
  159. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/matchable.py +0 -0
  160. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/qualified.py +0 -0
  161. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/reference.py +0 -0
  162. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/term.py +0 -0
  163. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/productions/variable.py +0 -0
  164. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/exceptions.py +0 -0
  165. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/expression_encoder.py +0 -0
  166. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/lark_print_parser.py +0 -0
  167. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/print_parser.py +0 -0
  168. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/matching/util/runtime_data_collector.py +0 -0
  169. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/explain_mode.py +0 -0
  170. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/files_mode.py +0 -0
  171. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/logic_mode.py +0 -0
  172. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/mode_controller.py +0 -0
  173. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/print_mode.py +0 -0
  174. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/return_mode.py +0 -0
  175. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/run_mode.py +0 -0
  176. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/transfer_mode.py +0 -0
  177. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/unmatched_mode.py +0 -0
  178. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/modes/validation_mode.py +0 -0
  179. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/__init__.py +0 -0
  180. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/exceptions.py +0 -0
  181. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/parser.out +0 -0
  182. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/parsetab.py +0 -0
  183. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/scanner.py +0 -0
  184. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/scanning/scanning_lexer.py +0 -0
  185. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/cache.py +0 -0
  186. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/config_exception.py +0 -0
  187. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/exceptions.py +0 -0
  188. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/last_line_stats.py +0 -0
  189. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/line_counter.py +0 -0
  190. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/line_monitor.py +0 -0
  191. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/log_utility.py +0 -0
  192. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/pandas_data_reader.py +0 -0
  193. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/printer.py +0 -0
  194. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/reference_parser.py +0 -0
  195. {csvpath-0.0.496 → csvpath-0.0.498}/csvpath/util/s3_data_reader.py +0 -0
  196. {csvpath-0.0.496 → csvpath-0.0.498}/docs/asbool.md +0 -0
  197. {csvpath-0.0.496 → csvpath-0.0.498}/docs/assignment.md +0 -0
  198. {csvpath-0.0.496 → csvpath-0.0.498}/docs/comments.md +0 -0
  199. {csvpath-0.0.496 → csvpath-0.0.498}/docs/config.md +0 -0
  200. {csvpath-0.0.496 → csvpath-0.0.498}/docs/examples.md +0 -0
  201. {csvpath-0.0.496 → csvpath-0.0.498}/docs/files.md +0 -0
  202. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/above.md +0 -0
  203. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/advance.md +0 -0
  204. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/after_blank.md +0 -0
  205. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/all.md +0 -0
  206. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/andor.md +0 -0
  207. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/any.md +0 -0
  208. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/average.md +0 -0
  209. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/between.md +0 -0
  210. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/collect.md +0 -0
  211. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/correlate.md +0 -0
  212. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/count.md +0 -0
  213. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/count_bytes.md +0 -0
  214. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/count_headers.md +0 -0
  215. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/counter.md +0 -0
  216. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/date.md +0 -0
  217. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/empty.md +0 -0
  218. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/empty_stack.md +0 -0
  219. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/end.md +0 -0
  220. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/every.md +0 -0
  221. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/fail.md +0 -0
  222. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/fingerprint.md +0 -0
  223. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/first.md +0 -0
  224. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/get.md +0 -0
  225. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/has_dups.md +0 -0
  226. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/has_matches.md +0 -0
  227. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/header.md +0 -0
  228. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/header_name.md +0 -0
  229. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/header_names_mismatch.md +0 -0
  230. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/implementing_functions.md +0 -0
  231. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/import.md +0 -0
  232. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/in.md +0 -0
  233. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/increment.md +0 -0
  234. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/intf.md +0 -0
  235. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/jinja.md +0 -0
  236. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/last.md +0 -0
  237. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/line.md +0 -0
  238. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/line_number.md +0 -0
  239. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/max.md +0 -0
  240. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/metaphone.md +0 -0
  241. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/mismatch.md +0 -0
  242. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/no.md +0 -0
  243. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/not.md +0 -0
  244. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/now.md +0 -0
  245. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/percent_unique.md +0 -0
  246. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/pop.md +0 -0
  247. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/print.md +0 -0
  248. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/print_line.md +0 -0
  249. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/print_queue.md +0 -0
  250. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/random.md +0 -0
  251. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/regex.md +0 -0
  252. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/replace.md +0 -0
  253. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/reset_headers.md +0 -0
  254. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/stdev.md +0 -0
  255. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/stop.md +0 -0
  256. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/string_functions.md +0 -0
  257. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/subtotal.md +0 -0
  258. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/subtract.md +0 -0
  259. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/sum.md +0 -0
  260. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/tally.md +0 -0
  261. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/total_lines.md +0 -0
  262. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/track.md +0 -0
  263. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/types.md +0 -0
  264. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/variables.md +0 -0
  265. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions/variables_and_headers.md +0 -0
  266. {csvpath-0.0.496 → csvpath-0.0.498}/docs/functions.md +0 -0
  267. {csvpath-0.0.496 → csvpath-0.0.498}/docs/grammar.md +0 -0
  268. {csvpath-0.0.496 → csvpath-0.0.498}/docs/headers.md +0 -0
  269. {csvpath-0.0.496 → csvpath-0.0.498}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  270. {csvpath-0.0.496 → csvpath-0.0.498}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  271. {csvpath-0.0.496 → csvpath-0.0.498}/docs/paths.md +0 -0
  272. {csvpath-0.0.496 → csvpath-0.0.498}/docs/printing.md +0 -0
  273. {csvpath-0.0.496 → csvpath-0.0.498}/docs/qualifiers.md +0 -0
  274. {csvpath-0.0.496 → csvpath-0.0.498}/docs/references.md +0 -0
  275. {csvpath-0.0.496 → csvpath-0.0.498}/docs/terms.md +0 -0
  276. {csvpath-0.0.496 → csvpath-0.0.498}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.496
3
+ Version: 0.0.498
4
4
  Summary: A declarative language for validating CSV, Excel, and other tabular data files
5
5
  Author: David Kershaw
6
6
  Author-email: dk107dk@hotmail.com
@@ -25,16 +25,18 @@ Classifier: Topic :: Utilities
25
25
  Provides-Extra: pandas
26
26
  Provides-Extra: smartopen
27
27
  Requires-Dist: bullet (>=2.2.0,<3.0.0)
28
- Requires-Dist: inflect (>=7.3.1,<8.0.0)
28
+ Requires-Dist: inflect (>=7.4.0,<8.0.0)
29
29
  Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
30
30
  Requires-Dist: lark (>=1.2.2,<2.0.0)
31
+ Requires-Dist: marquez-python (>=0.50.0,<0.51.0)
31
32
  Requires-Dist: metaphone (>=0.6,<0.7)
32
- Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "pandas"
33
+ Requires-Dist: openlineage-python (>=1.25.0,<2.0.0)
33
34
  Requires-Dist: ply (>=3.11,<4.0)
34
35
  Requires-Dist: pylightxl (>=1.61,<2.0)
35
36
  Requires-Dist: pytest (>=8.3.3,<9.0.0)
36
37
  Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
37
- Requires-Dist: smart-open[s3] (>=7.0.5,<8.0.0) ; extra == "smartopen"
38
+ Requires-Dist: pytz (>=2024.2,<2025.0)
39
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
38
40
  Requires-Dist: tabulate (>=0.9.0,<0.10.0)
39
41
  Project-URL: Csvpath.org, https://www.csvpath.org
40
42
  Project-URL: Github, https://github.com/csvpath/csvpath.git
@@ -24,8 +24,14 @@ path = cache
24
24
  [functions]
25
25
  imports = config/functions.imports
26
26
 
27
+ [listeners]
28
+
29
+ [marquez]
30
+ base_url = http://localhost:5000
31
+
27
32
  [results]
28
33
  archive = archive
34
+ transfers = transfers
29
35
 
30
36
  [inputs]
31
37
  files = inputs/named_files
@@ -5,7 +5,7 @@ import csv
5
5
  import time
6
6
  import os
7
7
  import hashlib
8
- from datetime import datetime
8
+ from datetime import datetime, timezone
9
9
  from typing import List, Dict, Any
10
10
  from collections.abc import Iterator
11
11
  from abc import ABC, abstractmethod
@@ -28,7 +28,7 @@ from .util.exceptions import (
28
28
  from .matching.util.exceptions import MatchException
29
29
  from csvpath.util.printer import Printer
30
30
  from csvpath.util.file_readers import DataFileReader
31
- from csvpath.managers.line_spooler import LineSpooler, ListLineSpooler
31
+ from csvpath.util.line_spooler import LineSpooler, ListLineSpooler
32
32
  from csvpath.modes.mode_controller import ModeController
33
33
 
34
34
 
@@ -271,7 +271,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
271
271
  # _function_times_value collects the time a function spends doing its to_value()
272
272
  #
273
273
  self._function_times_value = {}
274
- self._created_at = datetime.now()
274
+ self._created_at = datetime.now(timezone.utc)
275
275
  self._run_started_at = None
276
276
  self._collecting = False
277
277
  #
@@ -681,23 +681,6 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
681
681
  def transfers(self) -> list[tuple[str, str]]:
682
682
  return self.modes.transfer_mode.transfers
683
683
 
684
- """
685
- def update_arg_validation_mode_if(self) -> None:
686
- if self.metadata and "validation-mode" in self.metadata:
687
- # sets arg validation reporting. one or more or none of:
688
- # - print
689
- # - log
690
- # - raise
691
- #
692
- validation_mode = f"{self.metadata['validation-mode']}".strip()
693
- if validation_mode:
694
- self.set_validation_error_handling(validation_mode)
695
- self.logger.info(
696
- "Setting 'validation-mode': %s",
697
- self.metadata["validation-mode"],
698
- )
699
- """
700
-
701
684
  @property
702
685
  def all_expected_files(self) -> list[str]:
703
686
  return self.modes.files_mode.all_expected_files
@@ -1099,7 +1082,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
1099
1082
  last_line = self.matcher.line
1100
1083
  self.line_monitor.next_line(last_line=last_line, data=line)
1101
1084
  if self.line_monitor.physical_line_number == 0:
1102
- self._run_started_at = datetime.now()
1085
+ self._run_started_at = datetime.now(timezone.utc)
1103
1086
 
1104
1087
  def _consider_line(self, line): # pylint: disable=R0912, R0911
1105
1088
  # re: R0912: this method has already been refactored but maybe
@@ -1234,10 +1217,10 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
1234
1217
  )
1235
1218
  return -1
1236
1219
  if self.csvpaths:
1237
- self.line_monitor = self.csvpaths.file_manager.get_new_line_monitor(
1220
+ self.line_monitor = self.csvpaths.file_manager.cacher.get_new_line_monitor(
1238
1221
  self.scanner.filename
1239
1222
  )
1240
- self.headers = self.csvpaths.file_manager.get_original_headers(
1223
+ self.headers = self.csvpaths.file_manager.cacher.get_original_headers(
1241
1224
  self.scanner.filename
1242
1225
  )
1243
1226
  else:
@@ -5,18 +5,16 @@ from abc import ABC, abstractmethod
5
5
  from typing import List, Any
6
6
  import csv
7
7
  import traceback
8
- from datetime import datetime
8
+ from datetime import datetime, timezone
9
9
  from .util.error import ErrorHandler, ErrorCollector, Error
10
10
  from .util.config import Config
11
11
  from .util.log_utility import LogUtility
12
12
  from .util.metadata_parser import MetadataParser
13
13
  from .util.exceptions import InputException, CsvPathsException
14
- from .util.csvpaths_registrar import CsvPathsRegistrar, CsvPathsFilesystemRegistrar
15
- from .managers.paths_manager import PathsManager
16
- from .managers.file_manager import FileManager
17
- from .managers.results_manager import ResultsManager
18
- from .managers.results_registrar import ResultsRegistrar
19
- from .managers.result import Result
14
+ from .managers.paths.paths_manager import PathsManager
15
+ from .managers.files.file_manager import FileManager
16
+ from .managers.results.results_manager import ResultsManager
17
+ from .managers.results.result import Result
20
18
  from . import CsvPath
21
19
 
22
20
 
@@ -38,7 +36,7 @@ class CsvPathsPublic(ABC):
38
36
 
39
37
  @abstractmethod
40
38
  def collect_paths(self, *, pathsname, filename) -> None: # pragma: no cover
41
- """Sequentially does a CsvPath.collect() on filename for every named path"""
39
+ """Sequentially does a CsvPath.collect() on filename for every named path. lines are collected into results."""
42
40
 
43
41
  @abstractmethod
44
42
  def fast_forward_paths(self, *, pathsname, filename) -> None: # pragma: no cover
@@ -150,8 +148,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
150
148
  self._skip_all = False
151
149
  self._advance_all = 0
152
150
  self._current_run_time = None
153
- self._csvpaths_registrars = []
154
- self._csvpaths_registrars.append(CsvPathsFilesystemRegistrar(self))
155
151
  self._run_time_str = None
156
152
 
157
153
  def run_time_str(self, pathsname=None) -> str:
@@ -168,7 +164,7 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
168
164
  @property
169
165
  def current_run_time(self) -> datetime:
170
166
  if self._current_run_time is None:
171
- self._current_run_time = datetime.now()
167
+ self._current_run_time = datetime.now(timezone.utc)
172
168
  return self._current_run_time
173
169
 
174
170
  def clear_run_coordination(self) -> None:
@@ -209,15 +205,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
209
205
  def advance_all(self, lines: int) -> None: # pragma: no cover
210
206
  self._advance_all = lines
211
207
 
212
- @property
213
- def csvpaths_registrars(self) -> list[CsvPathsRegistrar]:
214
- if self._csvpaths_registrars is None:
215
- self._csvpaths_registrars = []
216
- return self._csvpaths_registrars
217
-
218
- def add_csvpaths_registrar(self, creg) -> None:
219
- self.csvpaths_registrars.append(creg)
220
-
221
208
  @property
222
209
  def errors(self) -> List[Error]: # pylint: disable=C0116
223
210
  return self._errors
@@ -253,6 +240,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
253
240
  )
254
241
  crt = self.run_time_str(pathsname)
255
242
  results = []
243
+ #
244
+ # run starts here
245
+ #
246
+ self.results_manager.start_run(
247
+ run_dir=crt, pathsname=pathsname, filename=filename
248
+ )
249
+ #
250
+ #
251
+ #
256
252
  for i, path in enumerate(paths):
257
253
  csvpath = self.csvpath()
258
254
  result = Result(
@@ -266,7 +262,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
266
262
  # casting a broad net because if "raise" not in the error policy we
267
263
  # want to never fail during a run
268
264
  try:
269
- self.results_manager.add_named_result(result)
270
265
  self._load_csvpath(
271
266
  csvpath=csvpath,
272
267
  path=path,
@@ -274,6 +269,11 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
274
269
  pathsname=pathsname,
275
270
  filename=filename,
276
271
  )
272
+ #
273
+ # the add has to come after _load_csvpath because we need the identity or index
274
+ # to be stable and the identity is found in load, if it exists.
275
+ #
276
+ self.results_manager.add_named_result(result)
277
277
  lines = result.lines
278
278
  self.logger.debug("Collecting lines using a %s", type(lines))
279
279
  csvpath.collect(lines=lines)
@@ -299,10 +299,12 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
299
299
  raise e
300
300
  self.results_manager.save(result)
301
301
  results.append(result)
302
- rr = ResultsRegistrar(
303
- csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
302
+ #
303
+ # run ends here
304
+ #
305
+ self.results_manager.complete_run(
306
+ run_dir=crt, pathsname=pathsname, results=results
304
307
  )
305
- rr.write_manifest()
306
308
  #
307
309
  # update/write run manifests here
308
310
  # - validity (are all paths valid)
@@ -316,10 +318,22 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
316
318
  )
317
319
 
318
320
  def _load_csvpath(
319
- self, *, csvpath: CsvPath, path: str, file: str, pathsname: str = None, filename
321
+ self,
322
+ *,
323
+ csvpath: CsvPath,
324
+ path: str,
325
+ file: str,
326
+ pathsname: str = None,
327
+ filename,
328
+ by_line: bool = False,
320
329
  ) -> None:
321
330
  # file is the physical file (+/- if preceding mode) filename is the named-file name
322
331
  self.logger.debug("Beginning to load csvpath %s with file %s", path, file)
332
+ #
333
+ # by_line==True means we are starting a run that is breadth-first ultimately using
334
+ # next_by_line(). by_line runs cannot be source-mode preceding and have different
335
+ # semantics around csvpaths influencing one another.
336
+ #
323
337
  # we strip comments from above the path so we need to extract them first
324
338
  path = MetadataParser(self).extract_metadata(instance=csvpath, csvpath=path)
325
339
  identity = csvpath.identity
@@ -327,9 +341,24 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
327
341
  # update the settings using the metadata fields we just collected
328
342
  csvpath.update_settings_from_metadata()
329
343
  #
330
- # this next line is triggering a write to the inputs dir
344
+ # if we have a reference, resolve it. we may not actually use the file
345
+ # if we're in source-mode: preceding, but that doesn't matter from the
346
+ # pov of the reference.
347
+ #
348
+ if filename.startswith("$"):
349
+ self.logger.debug(
350
+ "File name is a reference: %s. Replacing the path passed in with the reffed data file path.",
351
+ filename,
352
+ )
353
+ file = self.results_manager.data_file_for_reference(filename)
354
+ #
355
+ #
331
356
  #
332
357
  if csvpath.data_from_preceding is True:
358
+ if by_line is True:
359
+ raise CsvPathsException(
360
+ "Breadth-first runs do not support source-mode preceding because each line of data flows through each csvpath in order already"
361
+ )
333
362
  #
334
363
  # we are in source-mode: preceding
335
364
  # that means we ignore the original data file path and
@@ -338,6 +367,16 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
338
367
  # saved data.
339
368
  #
340
369
  # find the preceding csvpath in the named-paths
370
+ #
371
+ # we may be in a file reference like: $sourcemode.csvpaths.source2:from. if so
372
+ # we just need the named-paths name.
373
+ #
374
+ if pathsname.startswith("$"):
375
+ self.logger.debug(
376
+ "Named-paths name is a reference: %s. Stripping it down to just the actual named-paths name.",
377
+ pathsname,
378
+ )
379
+ pathsname = pathsname[1 : pathsname.find(".")]
341
380
  result = self.results_manager.get_last_named_result(
342
381
  name=pathsname, before=csvpath.identity
343
382
  )
@@ -351,24 +390,23 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
351
390
  csvpath.identity,
352
391
  file,
353
392
  )
393
+ else:
394
+ self.logger.warning(
395
+ "Cannot find a preceding data file to use for csvpath identified as %s running in source-mode",
396
+ csvpath.identity,
397
+ )
354
398
  f = path.find("[")
355
399
  self.logger.debug("Csvpath matching part starts at char # %s", f)
356
400
  apath = f"${file}{path[f:]}"
357
401
  self.logger.info("Parsing csvpath %s", apath)
358
402
  csvpath.parse(apath)
359
403
  #
360
- # ready to run. time to register the run.
404
+ # ready to run. time to register the run. this is separate from
405
+ # the run_register.py (ResultsRegister) event
406
+ #
407
+ # crt = self.run_time_str(pathsname)
408
+ # fingerprint = self.file_manager.get_fingerprint_for_name(filename)
361
409
  #
362
- crt = self.run_time_str(pathsname)
363
- fingerprint = self.file_manager.get_fingerprint_for_name(filename)
364
- for _ in self.csvpaths_registrars:
365
- _.update_manifest(
366
- csvpath=csvpath,
367
- filepath=file,
368
- instancepath=crt,
369
- fingerprint=fingerprint,
370
- identity=identity,
371
- )
372
410
  self.logger.debug("Done loading csvpath")
373
411
 
374
412
  def fast_forward_paths(self, *, pathsname, filename):
@@ -383,6 +421,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
383
421
  filename,
384
422
  )
385
423
  crt = self.run_time_str(pathsname)
424
+ #
425
+ # run starts here
426
+ #
427
+ self.results_manager.start_run(
428
+ run_dir=crt, pathsname=pathsname, filename=filename
429
+ )
430
+ #
431
+ #
432
+ #
386
433
  results = []
387
434
  for i, path in enumerate(paths):
388
435
  csvpath = self.csvpath()
@@ -396,7 +443,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
396
443
  run_dir=crt,
397
444
  )
398
445
  try:
399
- self.results_manager.add_named_result(result)
400
446
  self._load_csvpath(
401
447
  csvpath=csvpath,
402
448
  path=path,
@@ -404,6 +450,11 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
404
450
  pathsname=pathsname,
405
451
  filename=filename,
406
452
  )
453
+ #
454
+ # the add has to come after _load_csvpath because we need the identity or index
455
+ # to be stable and the identity is found in load, if it exists.
456
+ #
457
+ self.results_manager.add_named_result(result)
407
458
  self.logger.info(
408
459
  "Parsed csvpath %s pointed at %s and starting to fast-forward",
409
460
  i,
@@ -425,10 +476,12 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
425
476
  raise e
426
477
  self.results_manager.save(result)
427
478
  results.append(result)
428
- rr = ResultsRegistrar(
429
- csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
479
+ #
480
+ # run ends here
481
+ #
482
+ self.results_manager.complete_run(
483
+ run_dir=crt, pathsname=pathsname, results=results
430
484
  )
431
- rr.write_manifest()
432
485
  self.clear_run_coordination()
433
486
  self.logger.info(
434
487
  "Completed fast_forward_paths %s with %s paths", pathsname, len(paths)
@@ -444,6 +497,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
444
497
  self.clean(paths=pathsname)
445
498
  self.logger.info("Beginning next_paths with %s paths", len(paths))
446
499
  crt = self.run_time_str(pathsname)
500
+ #
501
+ # run starts here
502
+ #
503
+ self.results_manager.start_run(
504
+ run_dir=crt, pathsname=pathsname, filename=filename
505
+ )
506
+ #
507
+ #
508
+ #
447
509
  results = []
448
510
  for i, path in enumerate(paths):
449
511
  if self._skip_all:
@@ -478,7 +540,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
478
540
  )
479
541
  csvpath.is_valid = False
480
542
  try:
481
- self.results_manager.add_named_result(result)
482
543
  self._load_csvpath(
483
544
  csvpath=csvpath,
484
545
  path=path,
@@ -486,13 +547,22 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
486
547
  pathsname=pathsname,
487
548
  filename=filename,
488
549
  )
550
+ #
551
+ # the add has to come after _load_csvpath because we need the identity or index
552
+ # to be stable and the identity is found in load, if it exists.
553
+ #
554
+ self.results_manager.add_named_result(result)
489
555
  for line in csvpath.next():
490
- line.append(result)
556
+ #
557
+ # removed dec 1. why was this? it doesn't seem to make sense and
558
+ # removing it doesn't break any unit tests. was it a mistake?
559
+ #
560
+ # line.append(result)
491
561
  if collect:
492
562
  result.append(line)
493
563
  result.unmatched = csvpath.unmatched
494
564
  yield line
495
- except Exception as ex: # pylint: disable=W0718
565
+ except Exception as ex:
496
566
  ex.trace = traceback.format_exc()
497
567
  ex.source = self
498
568
  try:
@@ -502,12 +572,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
502
572
  except Exception as e:
503
573
  self.results_manager.save(result)
504
574
  raise e
575
+
505
576
  self.results_manager.save(result)
506
577
  results.append(result)
507
- rr = ResultsRegistrar(
508
- csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
578
+ #
579
+ # run ends here
580
+ #
581
+ self.results_manager.complete_run(
582
+ run_dir=crt, pathsname=pathsname, results=results
509
583
  )
510
- rr.write_manifest()
511
584
  self.clear_run_coordination()
512
585
 
513
586
  # =============== breadth first processing ================
@@ -590,6 +663,10 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
590
663
  filename=filename,
591
664
  pathsname=pathsname,
592
665
  )
666
+ #
667
+ # prep has to come after _load_csvpath_objects because we need the identity or
668
+ # indexes to be stable and the identity is found in the load, if it exists.
669
+ #
593
670
  self._prep_csvpath_results(
594
671
  csvpath_objects=csvpath_objects, filename=filename, pathsname=pathsname
595
672
  )
@@ -725,13 +802,13 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
725
802
  results.append(result)
726
803
  result.unmatched = r[0].unmatched
727
804
  self.results_manager.save(result)
728
- rr = ResultsRegistrar(
729
- csvpaths=self,
730
- run_dir=results[0].run_dir,
731
- pathsname=pathsname,
732
- results=results,
805
+
806
+ #
807
+ # run ends here
808
+ #
809
+ self.results_manager.complete_run(
810
+ run_dir=results[0].run_dir, pathsname=pathsname, results=results
733
811
  )
734
- rr.write_manifest()
735
812
  self.clear_run_coordination()
736
813
 
737
814
  def _load_csvpath_objects(
@@ -754,9 +831,11 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
754
831
  file=named_file,
755
832
  filename=filename,
756
833
  pathsname=pathsname,
834
+ by_line=True,
757
835
  )
758
836
  if csvpath.data_from_preceding is True:
759
- self.logger.warning(
837
+ # this exception raise may be redundant, but I'm leaving it for now for good measure.
838
+ raise CsvPathsException(
760
839
  "Csvpath identified as {csvpath.identity} is set to use preceding data, but CsvPaths's by_line methods do not permit that"
761
840
  )
762
841
  csvpath_objects.append([csvpath, []])
@@ -773,6 +852,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
773
852
 
774
853
  def _prep_csvpath_results(self, *, csvpath_objects, filename, pathsname):
775
854
  crt = self.run_time_str(pathsname)
855
+ #
856
+ # run starts here
857
+ #
858
+ self.results_manager.start_run(
859
+ run_dir=crt, pathsname=pathsname, filename=filename
860
+ )
861
+ #
862
+ #
863
+ #
776
864
  for i, csvpath in enumerate(csvpath_objects):
777
865
  try:
778
866
  #
@@ -787,8 +875,13 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
787
875
  run_index=i,
788
876
  run_time=self.current_run_time,
789
877
  run_dir=crt,
878
+ by_line=True,
790
879
  )
791
880
  csvpath[1] = result
881
+ #
882
+ # the add has to come after _load_csvpath because we need the identity or index
883
+ # to be stable and the identity is found in load, if it exists.
884
+ #
792
885
  self.results_manager.add_named_result(result)
793
886
  except Exception as ex: # pylint: disable=W0718
794
887
  ex.trace = traceback.format_exc()
@@ -0,0 +1,50 @@
1
+ import os
2
+ from typing import Dict, List, Tuple
3
+ from csvpath.util.line_counter import LineCounter
4
+ from csvpath.util.line_monitor import LineMonitor
5
+ from csvpath.util.cache import Cache
6
+ from csvpath.util.exceptions import InputException, FileException
7
+
8
+
9
+ class FileCacher:
10
+ def __init__(self, csvpaths=None):
11
+ self.csvpaths = csvpaths
12
+ self.cache = Cache(self.csvpaths)
13
+ self.pathed_lines_and_headers = {}
14
+
15
+ def get_new_line_monitor(self, filename: str) -> LineMonitor:
16
+ if filename not in self.pathed_lines_and_headers:
17
+ self._find_lines_and_headers(filename)
18
+ lm = self.pathed_lines_and_headers[filename][0]
19
+ lm = lm.copy()
20
+ return lm
21
+
22
+ def get_original_headers(self, filename: str) -> List[str]:
23
+ if filename not in self.pathed_lines_and_headers:
24
+ self._find_lines_and_headers(filename)
25
+ return self.pathed_lines_and_headers[filename][1][:]
26
+
27
+ def _find_lines_and_headers(self, filename: str) -> None:
28
+ lm, headers = self._cached_lines_and_headers(filename)
29
+ if lm is None or headers is None:
30
+ lc = LineCounter(self.csvpaths)
31
+ lm, headers = lc.get_lines_and_headers(filename)
32
+ self._cache_lines_and_headers(filename, lm, headers)
33
+ self.pathed_lines_and_headers[filename] = (lm, headers)
34
+
35
+ def _cached_lines_and_headers(self, filename: str) -> Tuple[LineMonitor, List[str]]:
36
+ lm = LineMonitor()
37
+ json = self.cache.cached_text(filename, "json")
38
+ if json is not None and not json.strip() == "":
39
+ lm.load(json)
40
+ else:
41
+ return (None, None)
42
+ headers = self.cache.cached_text(filename, "csv")
43
+ return (lm, headers)
44
+
45
+ def _cache_lines_and_headers(
46
+ self, filename, lm: LineMonitor, headers: List[str]
47
+ ) -> None:
48
+ jstr = lm.dump()
49
+ self.cache.cache_text(filename, "json", jstr)
50
+ self.cache.cache_text(filename, "csv", ",".join(headers))
@@ -0,0 +1,27 @@
1
+ from openlineage.client import OpenLineageClient
2
+
3
+ from ..metadata import Metadata
4
+ from ..listener import Listener
5
+ from ..ol.event import EventBuilder
6
+ from ..ol.job import JobBuilder
7
+
8
+
9
+ class OpenLineageFileListener(Listener):
10
+ def __init__(self, config=None):
11
+ super().__init__(config)
12
+ self.ol_client = None
13
+
14
+ def metadata_update(self, mdata: Metadata) -> None:
15
+ if self.ol_client is None:
16
+ client_url = self.config._get("marquez", "base_url")
17
+ if client_url is None:
18
+ print(
19
+ "WARNING: OpenLineage listeners are live but there is no Marquez API URL"
20
+ )
21
+ return
22
+ # client_url = "http://localhost:5000"
23
+ self.ol_client = OpenLineageClient(url=client_url)
24
+
25
+ es = EventBuilder().build(mdata)
26
+ for e in es:
27
+ self.ol_client.emit(e)