castor-extractor 0.17.4__tar.gz → 0.18.2__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.

Potentially problematic release.


This version of castor-extractor might be problematic. Click here for more details.

Files changed (407) hide show
  1. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/CHANGELOG.md +16 -0
  2. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/PKG-INFO +9 -9
  3. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_metabase_api.py +2 -1
  4. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_metabase_db.py +3 -1
  5. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_mode.py +2 -3
  6. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/__init__.py +2 -1
  7. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/collection.py +8 -0
  8. castor_extractor-0.18.2/castor_extractor/utils/safe_request.py +57 -0
  9. castor_extractor-0.18.2/castor_extractor/utils/safe_request_test.py +77 -0
  10. castor_extractor-0.18.2/castor_extractor/utils/salesforce/__init__.py +2 -0
  11. castor_extractor-0.18.2/castor_extractor/utils/salesforce/constants.py +2 -0
  12. castor_extractor-0.18.2/castor_extractor/utils/salesforce/credentials.py +42 -0
  13. castor_extractor-0.18.2/castor_extractor/visualization/domo/__init__.py +3 -0
  14. castor_extractor-0.18.2/castor_extractor/visualization/domo/client/__init__.py +2 -0
  15. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/client/client.py +37 -52
  16. castor_extractor-0.18.2/castor_extractor/visualization/domo/client/credentials.py +31 -0
  17. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/extract.py +6 -12
  18. castor_extractor-0.18.2/castor_extractor/visualization/looker/__init__.py +8 -0
  19. castor_extractor-0.18.2/castor_extractor/visualization/looker/api/__init__.py +4 -0
  20. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/client.py +6 -4
  21. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/client_test.py +5 -3
  22. castor_extractor-0.18.2/castor_extractor/visualization/looker/api/credentials.py +33 -0
  23. castor_extractor-0.18.2/castor_extractor/visualization/looker/api/extraction_parameters.py +38 -0
  24. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/sdk.py +2 -28
  25. castor_extractor-0.18.2/castor_extractor/visualization/looker/constant.py +8 -0
  26. castor_extractor-0.18.2/castor_extractor/visualization/looker/constants.py +17 -0
  27. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/extract.py +30 -29
  28. castor_extractor-0.18.2/castor_extractor/visualization/metabase/__init__.py +8 -0
  29. castor_extractor-0.18.2/castor_extractor/visualization/metabase/client/__init__.py +2 -0
  30. castor_extractor-0.18.2/castor_extractor/visualization/metabase/client/api/__init__.py +2 -0
  31. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/api/client.py +8 -14
  32. castor_extractor-0.18.2/castor_extractor/visualization/metabase/client/api/credentials.py +18 -0
  33. castor_extractor-0.18.2/castor_extractor/visualization/metabase/client/db/__init__.py +2 -0
  34. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/client.py +13 -34
  35. castor_extractor-0.18.2/castor_extractor/visualization/metabase/client/db/credentials.py +26 -0
  36. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/errors.py +5 -3
  37. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/extract.py +1 -1
  38. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/__init__.py +1 -1
  39. castor_extractor-0.18.2/castor_extractor/visualization/mode/client/__init__.py +2 -0
  40. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/client/client.py +9 -12
  41. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/client/client_test.py +3 -3
  42. castor_extractor-0.18.2/castor_extractor/visualization/mode/client/credentials.py +24 -0
  43. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/extract.py +5 -3
  44. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/__init__.py +1 -1
  45. castor_extractor-0.18.2/castor_extractor/visualization/powerbi/client/__init__.py +3 -0
  46. castor_extractor-0.18.2/castor_extractor/visualization/powerbi/client/credentials.py +28 -0
  47. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/credentials_test.py +12 -4
  48. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/rest.py +2 -2
  49. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/rest_test.py +2 -2
  50. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/extract.py +2 -2
  51. castor_extractor-0.18.2/castor_extractor/visualization/qlik/__init__.py +7 -0
  52. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/__init__.py +1 -0
  53. castor_extractor-0.18.2/castor_extractor/visualization/qlik/client/engine/__init__.py +2 -0
  54. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/client.py +5 -6
  55. castor_extractor-0.18.2/castor_extractor/visualization/qlik/client/engine/credentials.py +26 -0
  56. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/master.py +5 -11
  57. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/rest.py +4 -4
  58. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/rest_test.py +6 -2
  59. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/extract.py +4 -8
  60. castor_extractor-0.18.2/castor_extractor/visualization/sigma/__init__.py +3 -0
  61. castor_extractor-0.18.2/castor_extractor/visualization/sigma/client/__init__.py +2 -0
  62. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/client/client.py +5 -4
  63. castor_extractor-0.18.2/castor_extractor/visualization/sigma/client/credentials.py +19 -0
  64. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/extract.py +4 -8
  65. castor_extractor-0.18.2/castor_extractor/visualization/tableau_revamp/client/credentials.py +57 -0
  66. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/column.sql +0 -5
  67. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/extract.py +2 -2
  68. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/column.sql +0 -1
  69. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/column.sql +0 -1
  70. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/pyproject.toml +16 -14
  71. castor_extractor-0.17.4/castor_extractor/utils/salesforce/__init__.py +0 -3
  72. castor_extractor-0.17.4/castor_extractor/utils/salesforce/constants.py +0 -13
  73. castor_extractor-0.17.4/castor_extractor/utils/salesforce/credentials.py +0 -65
  74. castor_extractor-0.17.4/castor_extractor/visualization/domo/__init__.py +0 -3
  75. castor_extractor-0.17.4/castor_extractor/visualization/domo/client/__init__.py +0 -2
  76. castor_extractor-0.17.4/castor_extractor/visualization/domo/client/client_test.py +0 -60
  77. castor_extractor-0.17.4/castor_extractor/visualization/domo/client/credentials.py +0 -44
  78. castor_extractor-0.17.4/castor_extractor/visualization/domo/constants.py +0 -6
  79. castor_extractor-0.17.4/castor_extractor/visualization/looker/__init__.py +0 -3
  80. castor_extractor-0.17.4/castor_extractor/visualization/looker/api/__init__.py +0 -3
  81. castor_extractor-0.17.4/castor_extractor/visualization/looker/constant.py +0 -33
  82. castor_extractor-0.17.4/castor_extractor/visualization/looker/env.py +0 -48
  83. castor_extractor-0.17.4/castor_extractor/visualization/looker/parameters.py +0 -78
  84. castor_extractor-0.17.4/castor_extractor/visualization/metabase/__init__.py +0 -3
  85. castor_extractor-0.17.4/castor_extractor/visualization/metabase/client/__init__.py +0 -2
  86. castor_extractor-0.17.4/castor_extractor/visualization/metabase/client/api/__init__.py +0 -1
  87. castor_extractor-0.17.4/castor_extractor/visualization/metabase/client/api/credentials.py +0 -45
  88. castor_extractor-0.17.4/castor_extractor/visualization/metabase/client/db/__init__.py +0 -1
  89. castor_extractor-0.17.4/castor_extractor/visualization/metabase/client/db/credentials.py +0 -80
  90. castor_extractor-0.17.4/castor_extractor/visualization/mode/client/__init__.py +0 -1
  91. castor_extractor-0.17.4/castor_extractor/visualization/mode/client/credentials.py +0 -57
  92. castor_extractor-0.17.4/castor_extractor/visualization/powerbi/client/__init__.py +0 -2
  93. castor_extractor-0.17.4/castor_extractor/visualization/powerbi/client/credentials.py +0 -20
  94. castor_extractor-0.17.4/castor_extractor/visualization/qlik/__init__.py +0 -3
  95. castor_extractor-0.17.4/castor_extractor/visualization/qlik/client/engine/__init__.py +0 -1
  96. castor_extractor-0.17.4/castor_extractor/visualization/qlik/constants.py +0 -3
  97. castor_extractor-0.17.4/castor_extractor/visualization/sigma/__init__.py +0 -3
  98. castor_extractor-0.17.4/castor_extractor/visualization/sigma/client/__init__.py +0 -2
  99. castor_extractor-0.17.4/castor_extractor/visualization/sigma/client/credentials.py +0 -35
  100. castor_extractor-0.17.4/castor_extractor/visualization/sigma/constants.py +0 -4
  101. castor_extractor-0.17.4/castor_extractor/visualization/tableau_revamp/client/credentials.py +0 -104
  102. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/Dockerfile +0 -0
  103. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/LICENCE +0 -0
  104. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/README.md +0 -0
  105. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/__init__.py +0 -0
  106. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/__init__.py +0 -0
  107. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_bigquery.py +0 -0
  108. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_databricks.py +0 -0
  109. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_domo.py +0 -0
  110. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_looker.py +0 -0
  111. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_mysql.py +0 -0
  112. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_postgres.py +0 -0
  113. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_powerbi.py +0 -0
  114. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_qlik.py +0 -0
  115. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_redshift.py +0 -0
  116. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_salesforce.py +0 -0
  117. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_salesforce_reporting.py +0 -0
  118. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_sigma.py +0 -0
  119. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_snowflake.py +0 -0
  120. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_sqlserver.py +0 -0
  121. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/extract_tableau.py +0 -0
  122. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/file_check.py +0 -0
  123. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/commands/upload.py +0 -0
  124. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/__init__.py +0 -0
  125. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/column.py +0 -0
  126. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/column_test.py +0 -0
  127. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/constants.py +0 -0
  128. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/enums.py +0 -0
  129. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/file.py +0 -0
  130. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/file_test.py +0 -0
  131. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/file_test_users.csv +0 -0
  132. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/file_test_users_valid.csv +0 -0
  133. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/templates/__init__.py +0 -0
  134. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/file_checker/templates/generic_warehouse.py +0 -0
  135. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/logger.py +0 -0
  136. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/types.py +0 -0
  137. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/__init__.py +0 -0
  138. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/constant.py +0 -0
  139. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/env.py +0 -0
  140. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/env_test.py +0 -0
  141. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/upload.py +0 -0
  142. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/upload_test.py +0 -0
  143. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/uploader/utils.py +0 -0
  144. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/__init__.py +0 -0
  145. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/abstract.py +0 -0
  146. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/api.py +0 -0
  147. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/api_test.py +0 -0
  148. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/postgres.py +0 -0
  149. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/query.py +0 -0
  150. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/uri.py +0 -0
  151. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/client/uri_test.py +0 -0
  152. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/collection_test.py +0 -0
  153. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/constants.py +0 -0
  154. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/dbt/__init__.py +0 -0
  155. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/dbt/assets.py +0 -0
  156. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/dbt/client.py +0 -0
  157. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/dbt/client_test.py +0 -0
  158. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/dbt/credentials.py +0 -0
  159. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/deprecate.py +0 -0
  160. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/env.py +0 -0
  161. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/files.py +0 -0
  162. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/files_test.py +0 -0
  163. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/formatter.py +0 -0
  164. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/formatter_test.csv +0 -0
  165. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/formatter_test.json +0 -0
  166. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/formatter_test.py +0 -0
  167. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/json_stream_write.py +0 -0
  168. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/load.py +0 -0
  169. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/object.py +0 -0
  170. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/object_test.py +0 -0
  171. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/__init__.py +0 -0
  172. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager.py +0 -0
  173. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager_on_id.py +0 -0
  174. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager_on_id_test.py +0 -0
  175. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager_on_token.py +0 -0
  176. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager_on_token_test.py +0 -0
  177. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/pager/pager_test.py +0 -0
  178. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/retry.py +0 -0
  179. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/retry_test.py +0 -0
  180. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/safe.py +0 -0
  181. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/safe_test.py +0 -0
  182. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/salesforce/client.py +0 -0
  183. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/salesforce/client_test.py +0 -0
  184. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/salesforce/credentials_test.py +0 -0
  185. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/store.py +0 -0
  186. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/string.py +0 -0
  187. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/string_test.py +0 -0
  188. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/time.py +0 -0
  189. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/time_test.py +0 -0
  190. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/type.py +0 -0
  191. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/validation.py +0 -0
  192. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/validation_test.py +0 -0
  193. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/utils/write.py +0 -0
  194. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/__init__.py +0 -0
  195. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/assets.py +0 -0
  196. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/client/endpoints.py +0 -0
  197. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/client/pagination.py +0 -0
  198. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/domo/client/pagination_test.py +0 -0
  199. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/constants.py +0 -0
  200. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/sdk_test.py +0 -0
  201. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/api/utils.py +0 -0
  202. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/assets.py +0 -0
  203. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/fields.py +0 -0
  204. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/fields_test.py +0 -0
  205. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/looker/multithreading.py +0 -0
  206. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/assets.py +0 -0
  207. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/api/client_test.py +0 -0
  208. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/.sqlfluff +0 -0
  209. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/base_url.sql +0 -0
  210. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/card.sql +0 -0
  211. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/collection.sql +0 -0
  212. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/dashboard.sql +0 -0
  213. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/dashboard_cards.sql +0 -0
  214. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/database.sql +0 -0
  215. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/table.sql +0 -0
  216. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/db/queries/user.sql +0 -0
  217. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/decryption.py +0 -0
  218. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/decryption_test.py +0 -0
  219. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/client/shared.py +0 -0
  220. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/metabase/types.py +0 -0
  221. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/assets.py +0 -0
  222. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/client/client_test.json +0 -0
  223. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/client/constants.py +0 -0
  224. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/mode/errors.py +0 -0
  225. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/assets.py +0 -0
  226. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/constants.py +0 -0
  227. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/utils.py +0 -0
  228. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/powerbi/client/utils_test.py +0 -0
  229. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/assets.py +0 -0
  230. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/constants.py +0 -0
  231. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/constants.py +0 -0
  232. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/error.py +0 -0
  233. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/error_test.py +0 -0
  234. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/json_rpc.py +0 -0
  235. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/json_rpc_test.py +0 -0
  236. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/qlik/client/engine/websocket.py +0 -0
  237. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/__init__.py +0 -0
  238. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/assets.py +0 -0
  239. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/client/__init__.py +0 -0
  240. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/client/rest.py +0 -0
  241. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/client/soql.py +0 -0
  242. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/salesforce_reporting/extract.py +0 -0
  243. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/assets.py +0 -0
  244. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/client/client_test.py +0 -0
  245. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/client/endpoints.py +0 -0
  246. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/sigma/client/pagination.py +0 -0
  247. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/__init__.py +0 -0
  248. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/assets.py +0 -0
  249. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/__init__.py +0 -0
  250. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/client.py +0 -0
  251. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/client_utils.py +0 -0
  252. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/credentials.py +0 -0
  253. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/project.py +0 -0
  254. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/client/safe_mode.py +0 -0
  255. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/constants.py +0 -0
  256. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/errors.py +0 -0
  257. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/extract.py +0 -0
  258. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/gql_fields.py +0 -0
  259. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/__init__.py +0 -0
  260. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/__init__.py +0 -0
  261. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_1_get.json +0 -0
  262. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_2_get.json +0 -0
  263. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/auth.xml +0 -0
  264. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/project_get.xml +0 -0
  265. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/user_get.xml +0 -0
  266. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/view_get_usage.xml +0 -0
  267. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/workbook_get.xml +0 -0
  268. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/graphql/__init__.py +0 -0
  269. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/graphql/paginated_object_test.py +0 -0
  270. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/__init__.py +0 -0
  271. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/auth_test.py +0 -0
  272. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/credentials_test.py +0 -0
  273. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/projects_test.py +0 -0
  274. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/usages_test.py +0 -0
  275. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/users_test.py +0 -0
  276. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/rest_api/workbooks_test.py +0 -0
  277. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/utils/__init__.py +0 -0
  278. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tests/unit/utils/env_key.py +0 -0
  279. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/tsc_fields.py +0 -0
  280. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/types.py +0 -0
  281. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau/usage.py +0 -0
  282. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/__init__.py +0 -0
  283. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/assets.py +0 -0
  284. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/client/__init__.py +0 -0
  285. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/client/client.py +0 -0
  286. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/client/errors.py +0 -0
  287. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/client/gql_queries.py +0 -0
  288. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/client/tsc_fields.py +0 -0
  289. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/constants.py +0 -0
  290. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/visualization/tableau_revamp/extract.py +0 -0
  291. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/__init__.py +0 -0
  292. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/__init__.py +0 -0
  293. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/asset.py +0 -0
  294. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/asset_test.py +0 -0
  295. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/extract.py +0 -0
  296. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/query.py +0 -0
  297. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/time_filter.py +0 -0
  298. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/abstract/time_filter_test.py +0 -0
  299. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/__init__.py +0 -0
  300. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/client.py +0 -0
  301. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/client_test.py +0 -0
  302. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/credentials.py +0 -0
  303. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/extract.py +0 -0
  304. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/.sqlfluff +0 -0
  305. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/column.sql +0 -0
  306. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/cte/sharded.sql +0 -0
  307. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/database.sql +0 -0
  308. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/query.sql +0 -0
  309. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/schema.sql +0 -0
  310. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/table.sql +0 -0
  311. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/table_with_tags.sql +0 -0
  312. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/user.sql +0 -0
  313. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/queries/view_ddl.sql +0 -0
  314. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/query.py +0 -0
  315. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/bigquery/types.py +0 -0
  316. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/__init__.py +0 -0
  317. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/client.py +0 -0
  318. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/client_test.py +0 -0
  319. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/credentials.py +0 -0
  320. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/extract.py +0 -0
  321. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/format.py +0 -0
  322. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/format_test.py +0 -0
  323. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/test_constants.py +0 -0
  324. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/types.py +0 -0
  325. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/utils.py +0 -0
  326. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/databricks/utils_test.py +0 -0
  327. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/__init__.py +0 -0
  328. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/client.py +0 -0
  329. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/client_test.py +0 -0
  330. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/extract.py +0 -0
  331. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/.sqlfluff +0 -0
  332. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/column.sql +0 -0
  333. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/database.sql +0 -0
  334. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/query.sql +0 -0
  335. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/schema.sql +0 -0
  336. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/table.sql +0 -0
  337. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/user.sql +0 -0
  338. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/queries/view_ddl.sql +0 -0
  339. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/mysql/query.py +0 -0
  340. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/__init__.py +0 -0
  341. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/extract.py +0 -0
  342. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/.sqlfluff +0 -0
  343. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/column.sql +0 -0
  344. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/database.sql +0 -0
  345. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/group.sql +0 -0
  346. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/schema.sql +0 -0
  347. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/table.sql +0 -0
  348. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/queries/user.sql +0 -0
  349. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/postgres/query.py +0 -0
  350. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/__init__.py +0 -0
  351. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/client.py +0 -0
  352. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/client_test.py +0 -0
  353. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/extract.py +0 -0
  354. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/.sqlfluff +0 -0
  355. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/database.sql +0 -0
  356. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/group.sql +0 -0
  357. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/query.sql +0 -0
  358. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/schema.sql +0 -0
  359. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/table.sql +0 -0
  360. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/table_freshness.sql +0 -0
  361. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/user.sql +0 -0
  362. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/queries/view_ddl.sql +0 -0
  363. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/redshift/query.py +0 -0
  364. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/__init__.py +0 -0
  365. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/client.py +0 -0
  366. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/constants.py +0 -0
  367. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/format.py +0 -0
  368. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/format_test.py +0 -0
  369. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/salesforce/soql.py +0 -0
  370. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/__init__.py +0 -0
  371. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/client.py +0 -0
  372. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/client_test.py +0 -0
  373. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/credentials.py +0 -0
  374. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/credentials_test.py +0 -0
  375. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/extract.py +0 -0
  376. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/.sqlfluff +0 -0
  377. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/column_lineage.sql +0 -0
  378. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/database.sql +0 -0
  379. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/function.sql +0 -0
  380. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/grant_to_role.sql +0 -0
  381. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/grant_to_user.sql +0 -0
  382. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/query.sql +0 -0
  383. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/role.sql +0 -0
  384. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/schema.sql +0 -0
  385. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/table.sql +0 -0
  386. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/user.sql +0 -0
  387. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/queries/view_ddl.sql +0 -0
  388. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/snowflake/query.py +0 -0
  389. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/__init__.py +0 -0
  390. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/client.py +0 -0
  391. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/extract.py +0 -0
  392. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/.sqlfluff +0 -0
  393. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/column.sql +0 -0
  394. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/database.sql +0 -0
  395. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/schema.sql +0 -0
  396. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/table.sql +0 -0
  397. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/queries/user.sql +0 -0
  398. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/sqlserver/query.py +0 -0
  399. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/__init__.py +0 -0
  400. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/extract.py +0 -0
  401. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/.sqlfluff +0 -0
  402. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/database.sql +0 -0
  403. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/query.sql +0 -0
  404. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/schema.sql +0 -0
  405. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/table.sql +0 -0
  406. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/user.sql +0 -0
  407. {castor_extractor-0.17.4 → castor_extractor-0.18.2}/castor_extractor/warehouse/synapse/queries/view_ddl.sql +0 -0
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.18.2 - 2024-07-08
4
+
5
+ * Added StatusCode handling to SafeMode
6
+
7
+ ## 0.18.1 - 2024-07-04
8
+
9
+ * Bump dependencies: numpy, setuptools, tableauserverclient
10
+
11
+ ## 0.18.0 - 2024-07-03
12
+
13
+ * Dashboarding technologies : Reworked credentials using Pydantic
14
+
15
+ ## 0.17.5 - 2024-07-03
16
+
17
+ * Snowflake, Synapse, Redshift: Remove default_value from the extracted column
18
+
3
19
  ## 0.17.4 - 2024-07-03
4
20
 
5
21
  * Sigma: Add `input-table`, `pivot-table` and `viz` in the list of supported **Elements**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: castor-extractor
3
- Version: 0.17.4
3
+ Version: 0.18.2
4
4
  Summary: Extract your metadata assets.
5
5
  Home-page: https://www.castordoc.com/
6
6
  License: EULA
@@ -37,13 +37,13 @@ Requires-Dist: google-cloud-core (>=2.1.0,<3.0.0)
37
37
  Requires-Dist: google-cloud-storage (>=2,<3)
38
38
  Requires-Dist: google-resumable-media (>=2.0.3,<3.0.0)
39
39
  Requires-Dist: googleapis-common-protos (>=1.53.0,<2.0.0)
40
- Requires-Dist: looker-sdk (>=23.0.0) ; extra == "looker" or extra == "all"
40
+ Requires-Dist: looker-sdk (>=23.0.0,<24.0.0) ; extra == "looker" or extra == "all"
41
41
  Requires-Dist: msal (>=1.20.0,<2.0.0) ; extra == "powerbi" or extra == "all"
42
- Requires-Dist: numpy (<1.25) ; python_version >= "3.8" and python_version < "3.9"
43
- Requires-Dist: numpy (>=1.26,<2) ; python_version >= "3.12" and python_version < "3.13"
44
- Requires-Dist: pandas (>=2,<2.2.0) ; python_version >= "3.9" and python_full_version <= "3.11.0"
45
- Requires-Dist: pandas (>=2.0,<2.1) ; python_version >= "3.8" and python_version < "3.9"
46
- Requires-Dist: pandas (>=2.1,<2.2.0) ; python_version >= "3.12" and python_version < "3.13"
42
+ Requires-Dist: numpy (<1.25) ; (python_version >= "3.8" and python_version < "3.9") and (extra == "bigquery" or extra == "databricks" or extra == "all")
43
+ Requires-Dist: numpy (<2) ; extra == "bigquery" or extra == "databricks" or extra == "all"
44
+ Requires-Dist: numpy (>=1.26) ; (python_version >= "3.12" and python_version < "3.13") and (extra == "bigquery" or extra == "databricks" or extra == "all")
45
+ Requires-Dist: pandas (<2.1) ; (python_version >= "3.8" and python_version < "3.9") and (extra == "databricks" or extra == "all")
46
+ Requires-Dist: pandas (>=2.1) ; (python_version >= "3.12" and python_version < "3.13") and (extra == "databricks" or extra == "all")
47
47
  Requires-Dist: psycopg2-binary (>=2.0.0,<3.0.0) ; extra == "metabase" or extra == "postgres" or extra == "redshift" or extra == "all"
48
48
  Requires-Dist: pycryptodome (>=3.0.0,<4.0.0) ; extra == "metabase" or extra == "all"
49
49
  Requires-Dist: pydantic (>=2.6,<3.0)
@@ -52,13 +52,13 @@ Requires-Dist: pymssql (>=2.2.11,<3.0.0) ; extra == "sqlserver" or extra == "all
52
52
  Requires-Dist: pymysql[rsa] (>=1.1.0,<2.0.0) ; extra == "mysql" or extra == "all"
53
53
  Requires-Dist: python-dateutil (>=2.0.0,<=3.0.0)
54
54
  Requires-Dist: requests (>=2.0.0,<3.0.0)
55
- Requires-Dist: setuptools (>=69,<70)
55
+ Requires-Dist: setuptools (>=70,<71)
56
56
  Requires-Dist: snowflake-connector-python (>=3.4.0,<4.0.0) ; extra == "snowflake" or extra == "all"
57
57
  Requires-Dist: snowflake-sqlalchemy (!=1.2.5,<2.0.0) ; extra == "snowflake" or extra == "all"
58
58
  Requires-Dist: sqlalchemy (>=1.4,<1.5)
59
59
  Requires-Dist: sqlalchemy-bigquery[bqstorage] (>=1.0.0,<=2.0.0) ; extra == "bigquery" or extra == "all"
60
60
  Requires-Dist: sqlalchemy-redshift (>=0.8.14,<0.9.0) ; extra == "redshift" or extra == "all"
61
- Requires-Dist: tableauserverclient (==0.17.0) ; extra == "tableau" or extra == "all"
61
+ Requires-Dist: tableauserverclient (==0.25.0) ; extra == "tableau" or extra == "all"
62
62
  Requires-Dist: tqdm (>=4.0.0,<5.0.0)
63
63
  Requires-Dist: typing-extensions (>=4,<5)
64
64
  Requires-Dist: websocket-client (>=1,<2) ; extra == "qlik" or extra == "all"
@@ -17,11 +17,12 @@ def main():
17
17
 
18
18
  args = parser.parse_args()
19
19
 
20
- client = metabase.ApiClient(
20
+ credentials = metabase.MetabaseApiCredentials(
21
21
  base_url=args.base_url,
22
22
  user=args.username,
23
23
  password=args.password,
24
24
  )
25
+ client = metabase.ApiClient(credentials)
25
26
 
26
27
  metabase.extract_all(
27
28
  client,
@@ -35,7 +35,7 @@ def main():
35
35
 
36
36
  args = parser.parse_args()
37
37
 
38
- client = metabase.DbClient(
38
+ credentials = metabase.MetabaseDbCredentials(
39
39
  host=args.host,
40
40
  port=args.port,
41
41
  database=args.database,
@@ -46,6 +46,8 @@ def main():
46
46
  require_ssl=args.require_ssl,
47
47
  )
48
48
 
49
+ client = metabase.DbClient(credentials)
50
+
49
51
  metabase.extract_all(
50
52
  client,
51
53
  output_directory=args.output,
@@ -25,8 +25,7 @@ def main():
25
25
  parser.add_argument("-o", "--output", help="Directory to write to")
26
26
 
27
27
  args = parser.parse_args()
28
-
29
- client = mode.Client(
28
+ credentials = mode.Credentials(
30
29
  host=args.host,
31
30
  workspace=args.workspace,
32
31
  token=args.token,
@@ -34,6 +33,6 @@ def main():
34
33
  )
35
34
 
36
35
  mode.extract_all(
37
- client,
36
+ credentials,
38
37
  output_directory=args.output,
39
38
  )
@@ -5,7 +5,7 @@ from .client import (
5
5
  SqlalchemyClient,
6
6
  uri_encode,
7
7
  )
8
- from .collection import group_by, mapping_from_rows
8
+ from .collection import empty_iterator, group_by, mapping_from_rows
9
9
  from .constants import OUTPUT_DIR
10
10
  from .deprecate import deprecate_python
11
11
  from .env import from_env
@@ -23,6 +23,7 @@ from .pager import (
23
23
  )
24
24
  from .retry import RetryStrategy, retry
25
25
  from .safe import SafeMode, safe_mode
26
+ from .safe_request import RequestSafeMode, ResponseJson, handle_response
26
27
  from .store import AbstractStorage, LocalStorage
27
28
  from .string import decode_when_bytes, string_to_tuple
28
29
  from .time import (
@@ -44,3 +44,11 @@ def mapping_from_rows(rows: List[Dict], key: Any, value: Any) -> Dict:
44
44
  mapping[mapping_key] = mapping_value
45
45
 
46
46
  return mapping
47
+
48
+
49
+ def empty_iterator():
50
+ """
51
+ Utils to return empty iterator, mainly used for viz transformers
52
+ Remark: missing return type is on purpose, it breaks the typing
53
+ """
54
+ return iter([])
@@ -0,0 +1,57 @@
1
+ import logging
2
+ from typing import List, Tuple, Union
3
+
4
+ from requests import HTTPError, Response
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ ResponseJson = Union[dict, List[dict]]
9
+
10
+
11
+ class RequestSafeMode:
12
+ """
13
+ RequestSafeMode class to parameterize what should be done if response
14
+ raises due to the status code.
15
+
16
+ Attributes:
17
+ self.status_codes: tuple of status codes that will be caught
18
+ self.errors_caught : list of errors caught
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ max_errors: Union[int, float] = 0,
24
+ status_codes: Tuple[int, ...] = (),
25
+ ):
26
+ self.max_errors = max_errors
27
+ self.status_codes: List[int] = list(status_codes)
28
+ self.status_codes_caught: List[int] = []
29
+
30
+ def catch_response(self, exception: HTTPError, status_code: int):
31
+ if int(status_code) not in self.status_codes:
32
+ raise exception
33
+
34
+ self.status_codes_caught.append(int(status_code))
35
+
36
+ @property
37
+ def should_raise(self) -> bool:
38
+ return len(self.status_codes_caught) > self.max_errors
39
+
40
+
41
+ def handle_response(
42
+ response: Response, safe_mode: RequestSafeMode
43
+ ) -> ResponseJson:
44
+ """
45
+ Util to handle a HTTP Response based on the response status code and the
46
+ safe mode used
47
+ """
48
+ try:
49
+ response.raise_for_status()
50
+ except HTTPError as e:
51
+ safe_mode.catch_response(e, response.status_code)
52
+ if safe_mode.should_raise:
53
+ raise e
54
+ logger.error(f"Safe mode : skip request with error {e}")
55
+ logger.debug(e, exc_info=True)
56
+ return {}
57
+ return response.json()
@@ -0,0 +1,77 @@
1
+ import io
2
+ from http import HTTPStatus
3
+
4
+ import pytest
5
+ from requests import HTTPError, Response
6
+
7
+ from .safe_request import RequestSafeMode, handle_response
8
+
9
+
10
+ def mock_response(status_code: int):
11
+ response = Response()
12
+ response.status_code = status_code
13
+ response.raw = io.BytesIO(b'[{"data": "working"}]')
14
+ return response
15
+
16
+
17
+ def test_http_error_with_no_safe_mode():
18
+ safe_params = RequestSafeMode() # Caught
19
+
20
+ with pytest.raises(HTTPError):
21
+ handle_response(mock_response(HTTPStatus.FORBIDDEN), safe_params)
22
+
23
+
24
+ def test_http_error_with_no_status_code():
25
+ safe_params = RequestSafeMode(2) # Caught
26
+
27
+ with pytest.raises(HTTPError):
28
+ handle_response(mock_response(HTTPStatus.FORBIDDEN), safe_params)
29
+
30
+
31
+ def test_http_error_with_status_code():
32
+ safe_params = RequestSafeMode(2, (HTTPStatus.FORBIDDEN,)) # Caught
33
+
34
+ def call():
35
+ return handle_response(mock_response(HTTPStatus.FORBIDDEN), safe_params)
36
+
37
+ assert call() == {}
38
+ assert call() == {}
39
+
40
+ with pytest.raises(HTTPError):
41
+ call()
42
+
43
+
44
+ def test_http_error_with_multiple_status_code():
45
+ safe_params = RequestSafeMode(
46
+ 2, (HTTPStatus.NOT_FOUND, HTTPStatus.FORBIDDEN)
47
+ ) # Caught
48
+
49
+ def call():
50
+ return handle_response(mock_response(HTTPStatus.FORBIDDEN), safe_params)
51
+
52
+ def call_2():
53
+ return handle_response(mock_response(HTTPStatus.NOT_FOUND), safe_params)
54
+
55
+ assert call() == {}
56
+ assert call_2() == {}
57
+ with pytest.raises(HTTPError): # 3 failed calls > retries
58
+ call()
59
+
60
+
61
+ def test_http_error_with_wrong_status_code():
62
+ safe_params = RequestSafeMode(2, (HTTPStatus.NOT_FOUND,)) # Wrong Status
63
+
64
+ def call():
65
+ handle_response(mock_response(HTTPStatus.BAD_REQUEST), safe_params)
66
+
67
+ with pytest.raises(HTTPError):
68
+ call()
69
+
70
+
71
+ def test_http_error_with_return():
72
+ safe_params = RequestSafeMode(2, (HTTPStatus.NOT_FOUND,)) # Wrong Status
73
+
74
+ def call():
75
+ return handle_response(mock_response(HTTPStatus.OK), safe_params)
76
+
77
+ assert call() == [{"data": "working"}]
@@ -0,0 +1,2 @@
1
+ from .client import SalesforceBaseClient
2
+ from .credentials import SalesforceCredentials
@@ -0,0 +1,2 @@
1
+ DEFAULT_API_VERSION = 59.0
2
+ DEFAULT_PAGINATION_LIMIT = 100
@@ -0,0 +1,42 @@
1
+ from typing import Dict
2
+
3
+ from pydantic import Field
4
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
+
6
+ CASTOR_ENV_PREFIX = "CASTOR_SALESFORCE_"
7
+
8
+
9
+ class SalesforceCredentials(BaseSettings):
10
+ """
11
+ Class to handle Salesforce rest API permissions
12
+ """
13
+
14
+ model_config = SettingsConfigDict(
15
+ env_prefix=CASTOR_ENV_PREFIX,
16
+ extra="ignore",
17
+ populate_by_name=True,
18
+ )
19
+
20
+ base_url: str
21
+ client_id: str
22
+ client_secret: str = Field(repr=False)
23
+ password: str = Field(repr=False)
24
+ security_token: str = Field(repr=False)
25
+ username: str
26
+
27
+ @property
28
+ def password_token(self) -> str:
29
+ """Generates the password for authentication"""
30
+ return self.password + self.security_token
31
+
32
+ def token_request_payload(self) -> Dict[str, str]:
33
+ """
34
+ Params to post to the API in order to retrieve the authentication token
35
+ """
36
+ return {
37
+ "grant_type": "password",
38
+ "client_id": self.client_id,
39
+ "client_secret": self.client_secret,
40
+ "username": self.username,
41
+ "password": self.password_token,
42
+ }
@@ -0,0 +1,3 @@
1
+ from .assets import DomoAsset
2
+ from .client import DomoClient, DomoCredentials
3
+ from .extract import extract_all
@@ -0,0 +1,2 @@
1
+ from .client import DomoClient
2
+ from .credentials import DomoCredentials
@@ -1,11 +1,21 @@
1
1
  import logging
2
2
  from datetime import datetime, timedelta
3
3
  from http import HTTPStatus
4
- from typing import Iterator, List, Optional, Set, Tuple
4
+ from typing import Iterator, List, Optional, Set
5
5
 
6
6
  import requests
7
7
 
8
- from ....utils import at_midnight, current_date, past_date, retry, timestamp_ms
8
+ from ....utils import (
9
+ RequestSafeMode,
10
+ ResponseJson,
11
+ at_midnight,
12
+ current_date,
13
+ empty_iterator,
14
+ handle_response,
15
+ past_date,
16
+ retry,
17
+ timestamp_ms,
18
+ )
9
19
  from ..assets import DomoAsset
10
20
  from .credentials import DomoCredentials
11
21
  from .endpoints import Endpoint, EndpointFactory
@@ -17,11 +27,17 @@ DOMO_PUBLIC_URL = "https://api.domo.com"
17
27
  DEFAULT_TIMEOUT = 120
18
28
  TOKEN_EXPIRATION_SECONDS = timedelta(seconds=3000) # auth token lasts 1 hour
19
29
 
30
+
31
+ # Safe Mode
32
+ VOLUME_IGNORED = 10
20
33
  IGNORED_ERROR_CODES = (
21
34
  HTTPStatus.BAD_REQUEST,
22
35
  HTTPStatus.NOT_FOUND,
23
36
  )
24
- ERROR_TPL = "Request failed with status code {status_code} and reason {reason}"
37
+ DOMO_SAFE_MODE = RequestSafeMode(
38
+ max_errors=VOLUME_IGNORED,
39
+ status_codes=IGNORED_ERROR_CODES,
40
+ )
25
41
 
26
42
  _RETRY_EXCEPTIONS = [
27
43
  requests.exceptions.ConnectTimeout,
@@ -33,40 +49,17 @@ _RETRY_BASE_MS = 10 * 60 * 1000 # 10 minutes
33
49
  logger = logging.getLogger(__name__)
34
50
 
35
51
 
36
- def _handle_response(response: requests.Response) -> requests.Response:
37
- response.raise_for_status()
38
- return response
39
-
40
-
41
- def _ignore_or_raise(
42
- error: requests.RequestException,
43
- ignore_error_codes: Optional[Tuple[int, ...]],
44
- ) -> dict:
45
- """
46
- Raises the error unless the response status code is in the ignored error
47
- codes list.
48
- """
49
- if not ignore_error_codes:
50
- raise error
51
-
52
- response = error.response
53
- if response is None:
54
- raise error
55
-
56
- if response.status_code in ignore_error_codes:
57
- logger.warning(error)
58
- return {}
59
-
60
- raise error
61
-
62
-
63
52
  class DomoClient:
64
53
  """
65
54
  Connect to Domo API and fetch main assets.
66
55
  https://developer.domo.com/portal/8ba9aedad3679-ap-is#platform-oauth-apis
67
56
  """
68
57
 
69
- def __init__(self, credentials: DomoCredentials):
58
+ def __init__(
59
+ self,
60
+ credentials: DomoCredentials,
61
+ safe_mode: Optional[RequestSafeMode] = None,
62
+ ):
70
63
  self._authentication = credentials.authentication
71
64
  self._bearer_headers: Optional[dict] = None
72
65
  self._session = requests.session()
@@ -76,6 +69,7 @@ class DomoClient:
76
69
  self._timeout = DEFAULT_TIMEOUT
77
70
  self.base_url = credentials.base_url
78
71
  self.cloud_id = credentials.cloud_id
72
+ self.safe_mode = safe_mode or DOMO_SAFE_MODE
79
73
 
80
74
  def _token_expired(self) -> bool:
81
75
  token_lifetime = datetime.now() - self._token_creation_time
@@ -95,7 +89,8 @@ class DomoClient:
95
89
  auth=basic_authentication,
96
90
  timeout=self._timeout,
97
91
  )
98
- result = _handle_response(response).json()
92
+ response.raise_for_status()
93
+ result = response.json()
99
94
 
100
95
  bearer_token = result["access_token"]
101
96
  self._bearer_headers = {"authorization": f"Bearer {bearer_token}"}
@@ -113,7 +108,7 @@ class DomoClient:
113
108
  endpoint: Endpoint,
114
109
  params: Optional[dict] = None,
115
110
  asset_id: Optional[str] = None,
116
- ) -> requests.Response:
111
+ ) -> ResponseJson:
117
112
  params = params if params else {}
118
113
  is_private = endpoint.is_private
119
114
  headers = self._private_headers if is_private else self._bearer_auth()
@@ -125,27 +120,16 @@ class DomoClient:
125
120
  timeout=self._timeout,
126
121
  )
127
122
 
128
- if response.status_code != HTTPStatus.OK:
129
- logger.warning(
130
- ERROR_TPL.format(
131
- status_code=response.status_code,
132
- reason=response.reason,
133
- )
134
- )
135
- return response
123
+ return handle_response(response, self.safe_mode)
136
124
 
137
125
  def _get_element(
138
126
  self,
139
127
  endpoint: Endpoint,
140
128
  params: Optional[dict] = None,
141
129
  asset_id: Optional[str] = None,
142
- ignore_error_codes: Optional[Tuple[int, ...]] = None,
143
130
  ) -> dict:
144
131
  """Used when the response only contains one element"""
145
- try:
146
- return self._get(endpoint, params, asset_id).json()
147
- except requests.RequestException as error:
148
- return _ignore_or_raise(error, ignore_error_codes)
132
+ return self._get(endpoint, params, asset_id)
149
133
 
150
134
  def _get_many(
151
135
  self,
@@ -154,7 +138,7 @@ class DomoClient:
154
138
  asset_id: Optional[str] = None,
155
139
  ) -> List[dict]:
156
140
  """Used when the response contains multiple elements"""
157
- return self._get(endpoint, params, asset_id).json()
141
+ return self._get(endpoint, params, asset_id)
158
142
 
159
143
  def _get_paginated(self, endpoint: Endpoint) -> List[dict]:
160
144
  """Used when the response is paginated and need iterations"""
@@ -172,10 +156,7 @@ class DomoClient:
172
156
 
173
157
  def _datasources(self, page_id: str) -> RawData:
174
158
  endpoint = self._endpoint_factory.page_content(page_id)
175
- page_content = self._get_element(
176
- endpoint,
177
- ignore_error_codes=IGNORED_ERROR_CODES,
178
- )
159
+ page_content = self._get_element(endpoint)
179
160
  processed: set[str] = set()
180
161
  for card in page_content.get("cards", []):
181
162
  for datasource in card["datasources"]:
@@ -196,7 +177,7 @@ class DomoClient:
196
177
  ) -> Iterator[dict]:
197
178
  """Recursively fetch pages while building the folder architecture"""
198
179
  if not page_tree:
199
- return []
180
+ return empty_iterator()
200
181
 
201
182
  for page in page_tree:
202
183
  page_id = page.get("id")
@@ -211,6 +192,10 @@ class DomoClient:
211
192
  self._endpoint_factory.pages,
212
193
  asset_id=page_id,
213
194
  )
195
+
196
+ if not detail:
197
+ continue
198
+
214
199
  datasources = self._datasources(page_id)
215
200
  yield {
216
201
  **detail,
@@ -0,0 +1,31 @@
1
+ from typing import Dict, Optional
2
+
3
+ from pydantic import Field, SecretStr
4
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
+ from requests.auth import HTTPBasicAuth
6
+
7
+ DOMO_ENV_PREFIX = "CASTOR_DOMO_"
8
+
9
+
10
+ class DomoCredentials(BaseSettings):
11
+ """Class to handle Domo rest API permissions"""
12
+
13
+ model_config = SettingsConfigDict(
14
+ env_prefix=DOMO_ENV_PREFIX,
15
+ extra="ignore",
16
+ populate_by_name=True,
17
+ )
18
+
19
+ api_token: str = Field(repr=False)
20
+ base_url: str
21
+ client_id: str
22
+ cloud_id: Optional[str] = Field(validation_alias="CLOUD_ID", default=None)
23
+ developer_token: str = Field(repr=False)
24
+
25
+ @property
26
+ def authentication(self) -> HTTPBasicAuth:
27
+ return HTTPBasicAuth(self.client_id, self.api_token)
28
+
29
+ @property
30
+ def private_headers(self) -> Dict[str, str]:
31
+ return {"X-DOMO-Developer-Token": self.developer_token}
@@ -12,7 +12,6 @@ from ...utils import (
12
12
  )
13
13
  from .assets import DomoAsset
14
14
  from .client import DomoClient, DomoCredentials
15
- from .constants import API_TOKEN, BASE_URL, CLIENT_ID, CLOUD_ID, DEVELOPER_TOKEN
16
15
 
17
16
  logger = logging.getLogger(__name__)
18
17
 
@@ -57,18 +56,13 @@ def extract_all(
57
56
  """
58
57
 
59
58
  _output_directory = output_directory or from_env(OUTPUT_DIR)
60
- _client_id = client_id or from_env(CLIENT_ID)
61
- _base_url = base_url or from_env(BASE_URL)
62
- _api_token = api_token or from_env(API_TOKEN)
63
- _developer_token = developer_token or from_env(DEVELOPER_TOKEN)
64
- _cloud_id = cloud_id or from_env(CLOUD_ID)
65
59
 
66
60
  credentials = DomoCredentials(
67
- base_url=_base_url,
68
- client_id=_client_id,
69
- api_token=_api_token,
70
- developer_token=_developer_token,
71
- cloud_id=_cloud_id,
61
+ base_url=base_url,
62
+ client_id=client_id,
63
+ api_token=api_token,
64
+ developer_token=developer_token,
65
+ cloud_id=cloud_id,
72
66
  )
73
67
  client = DomoClient(credentials=credentials)
74
68
 
@@ -78,4 +72,4 @@ def extract_all(
78
72
  filename = get_output_filename(key.name.lower(), _output_directory, ts)
79
73
  write_json(filename, data)
80
74
 
81
- write_summary(_output_directory, ts, base_url=_base_url)
75
+ write_summary(_output_directory, ts, base_url=credentials.base_url)
@@ -0,0 +1,8 @@
1
+ from .api import (
2
+ ApiClient,
3
+ ExtractionParameters,
4
+ LookerCredentials,
5
+ lookml_explore_names,
6
+ )
7
+ from .assets import LookerAsset
8
+ from .extract import extract_all, iterate_all_data
@@ -0,0 +1,4 @@
1
+ from .client import ApiClient
2
+ from .credentials import LookerCredentials
3
+ from .extraction_parameters import ExtractionParameters
4
+ from .utils import lookml_explore_names
@@ -22,7 +22,7 @@ from looker_sdk.sdk.api40.models import (
22
22
  from looker_sdk.sdk.constants import sdk_version
23
23
 
24
24
  from ....utils import Pager, PagerLogger, SafeMode, past_date, safe_mode
25
- from ..env import page_size
25
+ from ..constants import DEFAULT_LOOKER_PAGE_SIZE
26
26
  from ..fields import format_fields
27
27
  from .constants import (
28
28
  CONNECTION_FIELDS,
@@ -39,7 +39,8 @@ from .constants import (
39
39
  USER_FIELDS,
40
40
  USERS_ATTRIBUTES_FIELDS,
41
41
  )
42
- from .sdk import CastorApiSettings, Credentials, has_admin_permissions
42
+ from .credentials import LookerCredentials
43
+ from .sdk import CastorApiSettings, has_admin_permissions
43
44
 
44
45
  logger = logging.getLogger(__name__)
45
46
 
@@ -78,9 +79,10 @@ class ApiClient:
78
79
 
79
80
  def __init__(
80
81
  self,
81
- credentials: Credentials,
82
+ credentials: LookerCredentials,
82
83
  on_api_call: OnApiCall = lambda: None,
83
84
  safe_mode: Optional[SafeMode] = None,
85
+ page_size: int = DEFAULT_LOOKER_PAGE_SIZE,
84
86
  ):
85
87
  settings = CastorApiSettings(
86
88
  credentials=credentials, sdk_version=sdk_version
@@ -92,7 +94,7 @@ class ApiClient:
92
94
  self._sdk = sdk
93
95
  self._on_api_call = on_api_call
94
96
  self._logger = ApiPagerLogger(on_api_call)
95
- self.per_page = page_size()
97
+ self.per_page = page_size
96
98
  self._safe_mode = safe_mode
97
99
 
98
100
  def folders(self) -> List[Folder]:
@@ -2,9 +2,11 @@ import datetime
2
2
  from unittest.mock import patch
3
3
 
4
4
  import pytest
5
- from castor_extractor.visualization.looker import ( # type: ignore
5
+ from castor_extractor.visualization.looker.api.client import ( # type: ignore
6
6
  ApiClient,
7
- Credentials,
7
+ )
8
+ from castor_extractor.visualization.looker.api.credentials import ( # type: ignore
9
+ LookerCredentials,
8
10
  )
9
11
  from dateutil.utils import today
10
12
  from freezegun import freeze_time
@@ -13,7 +15,7 @@ from .client import _mondays
13
15
 
14
16
 
15
17
  def _credentials():
16
- return Credentials( # noqa: S106
18
+ return LookerCredentials( # noqa: S106
17
19
  base_url="base_url",
18
20
  client_id="client_id",
19
21
  client_secret="secret",