csvpath 0.0.522__tar.gz → 0.0.524__tar.gz

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