castor-extractor 0.24.10__tar.gz → 0.24.13__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 (428) hide show
  1. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/CHANGELOG.md +12 -0
  2. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/PKG-INFO +21 -4
  3. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/README.md +5 -2
  4. castor_extractor-0.24.13/castor_extractor/commands/extract_strategy.py +26 -0
  5. castor_extractor-0.24.13/castor_extractor/visualization/strategy/__init__.py +3 -0
  6. castor_extractor-0.24.13/castor_extractor/visualization/strategy/assets.py +14 -0
  7. castor_extractor-0.24.13/castor_extractor/visualization/strategy/client/__init__.py +2 -0
  8. castor_extractor-0.24.13/castor_extractor/visualization/strategy/client/client.py +313 -0
  9. castor_extractor-0.24.13/castor_extractor/visualization/strategy/client/credentials.py +38 -0
  10. castor_extractor-0.24.13/castor_extractor/visualization/strategy/extract.py +43 -0
  11. castor_extractor-0.24.13/castor_extractor/warehouse/redshift/queries/view_ddl.sql +33 -0
  12. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/pyproject.toml +6 -2
  13. castor_extractor-0.24.10/castor_extractor/warehouse/redshift/queries/view_ddl.sql +0 -19
  14. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/Dockerfile +0 -0
  15. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/DockerfileUsage.md +0 -0
  16. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/LICENCE +0 -0
  17. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/__init__.py +0 -0
  18. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/__init__.py +0 -0
  19. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_bigquery.py +0 -0
  20. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_confluence.py +0 -0
  21. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_databricks.py +0 -0
  22. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_domo.py +0 -0
  23. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_looker.py +0 -0
  24. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_looker_studio.py +0 -0
  25. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_metabase_api.py +0 -0
  26. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_metabase_db.py +0 -0
  27. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_mode.py +0 -0
  28. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_mysql.py +0 -0
  29. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_notion.py +0 -0
  30. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_postgres.py +0 -0
  31. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_powerbi.py +0 -0
  32. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_qlik.py +0 -0
  33. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_redshift.py +0 -0
  34. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_salesforce.py +0 -0
  35. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_salesforce_reporting.py +0 -0
  36. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_sigma.py +0 -0
  37. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_snowflake.py +0 -0
  38. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_sqlserver.py +0 -0
  39. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_tableau.py +0 -0
  40. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/extract_thoughtspot.py +0 -0
  41. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/file_check.py +0 -0
  42. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/commands/upload.py +0 -0
  43. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/__init__.py +0 -0
  44. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/column.py +0 -0
  45. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/column_test.py +0 -0
  46. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/constants.py +0 -0
  47. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/enums.py +0 -0
  48. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/file.py +0 -0
  49. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/file_test.py +0 -0
  50. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/file_test_users.csv +0 -0
  51. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/file_test_users_valid.csv +0 -0
  52. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/templates/__init__.py +0 -0
  53. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/file_checker/templates/generic_warehouse.py +0 -0
  54. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/__init__.py +0 -0
  55. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/__init__.py +0 -0
  56. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/assets.py +0 -0
  57. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/client/__init__.py +0 -0
  58. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/client/client.py +0 -0
  59. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/client/credentials.py +0 -0
  60. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/client/endpoints.py +0 -0
  61. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/client/pagination.py +0 -0
  62. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/confluence/extract.py +0 -0
  63. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/__init__.py +0 -0
  64. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/assets.py +0 -0
  65. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/__init__.py +0 -0
  66. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/client.py +0 -0
  67. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/client_test.py +0 -0
  68. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/constants.py +0 -0
  69. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/credentials.py +0 -0
  70. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/endpoints.py +0 -0
  71. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/client/pagination.py +0 -0
  72. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/knowledge/notion/extract.py +0 -0
  73. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/logger.py +0 -0
  74. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/__init__.py +0 -0
  75. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/__init__.py +0 -0
  76. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/assets.py +0 -0
  77. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/client/__init__.py +0 -0
  78. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/client/client.py +0 -0
  79. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/client/credentials.py +0 -0
  80. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/client/endpoints.py +0 -0
  81. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/quality/soda/client/pagination.py +0 -0
  82. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/__init__.py +0 -0
  83. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/__init__.py +0 -0
  84. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/assets.py +0 -0
  85. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/__init__.py +0 -0
  86. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/client.py +0 -0
  87. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/credentials.py +0 -0
  88. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/endpoint.py +0 -0
  89. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/type.py +0 -0
  90. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/utils.py +0 -0
  91. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/transformation/coalesce/client/utils_test.py +0 -0
  92. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/types.py +0 -0
  93. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/__init__.py +0 -0
  94. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/constant.py +0 -0
  95. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/env.py +0 -0
  96. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/env_test.py +0 -0
  97. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/settings.py +0 -0
  98. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/upload.py +0 -0
  99. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/upload_test.py +0 -0
  100. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/uploader/utils.py +0 -0
  101. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/__init__.py +0 -0
  102. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/argument_parser.py +0 -0
  103. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/argument_parser_test.py +0 -0
  104. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/batch.py +0 -0
  105. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/batch_test.py +0 -0
  106. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/__init__.py +0 -0
  107. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/abstract.py +0 -0
  108. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/__init__.py +0 -0
  109. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/auth.py +0 -0
  110. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/auth_test.py +0 -0
  111. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/client.py +0 -0
  112. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/client_test.py +0 -0
  113. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/pagination.py +0 -0
  114. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/pagination_test.py +0 -0
  115. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/safe_request.py +0 -0
  116. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/safe_request_test.py +0 -0
  117. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/utils.py +0 -0
  118. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/api/utils_test.py +0 -0
  119. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/postgres.py +0 -0
  120. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/query.py +0 -0
  121. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/uri.py +0 -0
  122. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/client/uri_test.py +0 -0
  123. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/collection.py +0 -0
  124. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/collection_test.py +0 -0
  125. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/constants.py +0 -0
  126. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/dbt/__init__.py +0 -0
  127. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/dbt/assets.py +0 -0
  128. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/dbt/client.py +0 -0
  129. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/dbt/client_test.py +0 -0
  130. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/dbt/credentials.py +0 -0
  131. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/deprecate.py +0 -0
  132. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/env.py +0 -0
  133. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/files.py +0 -0
  134. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/files_test.py +0 -0
  135. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/formatter.py +0 -0
  136. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/formatter_test.csv +0 -0
  137. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/formatter_test.json +0 -0
  138. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/formatter_test.py +0 -0
  139. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/json_stream_write.py +0 -0
  140. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/load.py +0 -0
  141. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/object.py +0 -0
  142. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/object_test.py +0 -0
  143. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/pager/__init__.py +0 -0
  144. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/pager/pager.py +0 -0
  145. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/pager/pager_on_id.py +0 -0
  146. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/pager/pager_on_id_test.py +0 -0
  147. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/pager/pager_test.py +0 -0
  148. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/retry.py +0 -0
  149. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/retry_test.py +0 -0
  150. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/safe.py +0 -0
  151. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/safe_test.py +0 -0
  152. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/__init__.py +0 -0
  153. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/client.py +0 -0
  154. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/client_test.py +0 -0
  155. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/constants.py +0 -0
  156. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/credentials.py +0 -0
  157. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/credentials_test.py +0 -0
  158. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/salesforce/pagination.py +0 -0
  159. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/store.py +0 -0
  160. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/string.py +0 -0
  161. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/string_test.py +0 -0
  162. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/time.py +0 -0
  163. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/time_test.py +0 -0
  164. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/type.py +0 -0
  165. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/validation.py +0 -0
  166. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/validation_test.py +0 -0
  167. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/utils/write.py +0 -0
  168. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/__init__.py +0 -0
  169. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/__init__.py +0 -0
  170. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/assets.py +0 -0
  171. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/__init__.py +0 -0
  172. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/client.py +0 -0
  173. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/credentials.py +0 -0
  174. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/endpoints.py +0 -0
  175. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/pagination.py +0 -0
  176. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/client/pagination_test.py +0 -0
  177. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/domo/extract.py +0 -0
  178. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/__init__.py +0 -0
  179. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/__init__.py +0 -0
  180. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/client.py +0 -0
  181. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/client_test.py +0 -0
  182. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/constants.py +0 -0
  183. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/credentials.py +0 -0
  184. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/extraction_parameters.py +0 -0
  185. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/sdk.py +0 -0
  186. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/sdk_test.py +0 -0
  187. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/api/utils.py +0 -0
  188. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/assets.py +0 -0
  189. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/constant.py +0 -0
  190. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/constants.py +0 -0
  191. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/extract.py +0 -0
  192. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/fields.py +0 -0
  193. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/fields_test.py +0 -0
  194. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker/multithreading.py +0 -0
  195. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/__init__.py +0 -0
  196. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/assets.py +0 -0
  197. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/__init__.py +0 -0
  198. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/admin_sdk_client.py +0 -0
  199. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/client.py +0 -0
  200. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/credentials.py +0 -0
  201. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/endpoints.py +0 -0
  202. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/enums.py +0 -0
  203. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/looker_studio_api_client.py +0 -0
  204. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/pagination.py +0 -0
  205. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/queries/query.sql +0 -0
  206. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/client/scopes.py +0 -0
  207. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/looker_studio/extract.py +0 -0
  208. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/__init__.py +0 -0
  209. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/assets.py +0 -0
  210. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/__init__.py +0 -0
  211. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/api/__init__.py +0 -0
  212. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/api/client.py +0 -0
  213. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/api/client_test.py +0 -0
  214. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/api/credentials.py +0 -0
  215. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/__init__.py +0 -0
  216. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/client.py +0 -0
  217. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/credentials.py +0 -0
  218. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/.sqlfluff +0 -0
  219. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/base_url.sql +0 -0
  220. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/card.sql +0 -0
  221. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/collection.sql +0 -0
  222. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/dashboard.sql +0 -0
  223. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/dashboard_cards.sql +0 -0
  224. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/database.sql +0 -0
  225. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/table.sql +0 -0
  226. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/db/queries/user.sql +0 -0
  227. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/decryption.py +0 -0
  228. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/decryption_test.py +0 -0
  229. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/client/shared.py +0 -0
  230. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/errors.py +0 -0
  231. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/extract.py +0 -0
  232. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/metabase/types.py +0 -0
  233. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/__init__.py +0 -0
  234. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/assets.py +0 -0
  235. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/__init__.py +0 -0
  236. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/client.py +0 -0
  237. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/client_test.json +0 -0
  238. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/client_test.py +0 -0
  239. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/constants.py +0 -0
  240. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/client/credentials.py +0 -0
  241. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/errors.py +0 -0
  242. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/mode/extract.py +0 -0
  243. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/__init__.py +0 -0
  244. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/assets.py +0 -0
  245. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/__init__.py +0 -0
  246. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/authentication.py +0 -0
  247. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/client.py +0 -0
  248. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/client_test.py +0 -0
  249. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/constants.py +0 -0
  250. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/credentials.py +0 -0
  251. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/credentials_test.py +0 -0
  252. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/endpoints.py +0 -0
  253. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/client/pagination.py +0 -0
  254. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/powerbi/extract.py +0 -0
  255. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/__init__.py +0 -0
  256. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/assets.py +0 -0
  257. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/__init__.py +0 -0
  258. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/constants.py +0 -0
  259. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/__init__.py +0 -0
  260. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/client.py +0 -0
  261. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/constants.py +0 -0
  262. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/credentials.py +0 -0
  263. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/error.py +0 -0
  264. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/error_test.py +0 -0
  265. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/json_rpc.py +0 -0
  266. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/json_rpc_test.py +0 -0
  267. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/engine/websocket.py +0 -0
  268. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/master.py +0 -0
  269. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/rest.py +0 -0
  270. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/client/rest_test.py +0 -0
  271. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/qlik/extract.py +0 -0
  272. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/__init__.py +0 -0
  273. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/assets.py +0 -0
  274. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/client/__init__.py +0 -0
  275. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/client/rest.py +0 -0
  276. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/client/soql.py +0 -0
  277. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/salesforce_reporting/extract.py +0 -0
  278. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/__init__.py +0 -0
  279. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/assets.py +0 -0
  280. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/client/__init__.py +0 -0
  281. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/client/client.py +0 -0
  282. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/client/credentials.py +0 -0
  283. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/client/endpoints.py +0 -0
  284. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/client/pagination.py +0 -0
  285. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/sigma/extract.py +0 -0
  286. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/__init__.py +0 -0
  287. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/assets.py +0 -0
  288. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/__init__.py +0 -0
  289. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/client.py +0 -0
  290. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/client_metadata_api.py +0 -0
  291. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/client_metadata_api_test.py +0 -0
  292. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/client_rest_api.py +0 -0
  293. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/client_tsc.py +0 -0
  294. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/credentials.py +0 -0
  295. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/errors.py +0 -0
  296. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/gql_queries.py +0 -0
  297. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/client/rest_fields.py +0 -0
  298. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/constants.py +0 -0
  299. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/tableau/extract.py +0 -0
  300. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/__init__.py +0 -0
  301. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/assets.py +0 -0
  302. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/client/__init__.py +0 -0
  303. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/client/client.py +0 -0
  304. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/client/credentials.py +0 -0
  305. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/client/endpoints.py +0 -0
  306. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/client/pagination.py +0 -0
  307. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/visualization/thoughtspot/extract.py +0 -0
  308. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/__init__.py +0 -0
  309. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/__init__.py +0 -0
  310. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/asset.py +0 -0
  311. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/asset_test.py +0 -0
  312. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/extract.py +0 -0
  313. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/query.py +0 -0
  314. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/time_filter.py +0 -0
  315. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/abstract/time_filter_test.py +0 -0
  316. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/__init__.py +0 -0
  317. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/client.py +0 -0
  318. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/client_test.py +0 -0
  319. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/credentials.py +0 -0
  320. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/extract.py +0 -0
  321. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/.sqlfluff +0 -0
  322. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/column.sql +0 -0
  323. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/cte/sharded.sql +0 -0
  324. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/database.sql +0 -0
  325. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/query.sql +0 -0
  326. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/schema.sql +0 -0
  327. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/table.sql +0 -0
  328. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/table_with_tags.sql +0 -0
  329. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/user.sql +0 -0
  330. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/queries/view_ddl.sql +0 -0
  331. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/query.py +0 -0
  332. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/bigquery/types.py +0 -0
  333. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/__init__.py +0 -0
  334. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/api_client.py +0 -0
  335. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/api_client_test.py +0 -0
  336. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/client.py +0 -0
  337. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/client_test.py +0 -0
  338. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/credentials.py +0 -0
  339. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/endpoints.py +0 -0
  340. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/enums.py +0 -0
  341. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/extract.py +0 -0
  342. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/format.py +0 -0
  343. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/format_test.py +0 -0
  344. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/lineage.py +0 -0
  345. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/lineage_test.py +0 -0
  346. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/pagination.py +0 -0
  347. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/sql_client.py +0 -0
  348. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/types.py +0 -0
  349. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/utils.py +0 -0
  350. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/databricks/utils_test.py +0 -0
  351. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/__init__.py +0 -0
  352. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/client.py +0 -0
  353. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/client_test.py +0 -0
  354. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/extract.py +0 -0
  355. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/.sqlfluff +0 -0
  356. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/column.sql +0 -0
  357. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/database.sql +0 -0
  358. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/query.sql +0 -0
  359. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/schema.sql +0 -0
  360. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/table.sql +0 -0
  361. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/user.sql +0 -0
  362. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/queries/view_ddl.sql +0 -0
  363. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/mysql/query.py +0 -0
  364. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/__init__.py +0 -0
  365. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/extract.py +0 -0
  366. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/.sqlfluff +0 -0
  367. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/column.sql +0 -0
  368. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/database.sql +0 -0
  369. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/group.sql +0 -0
  370. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/schema.sql +0 -0
  371. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/table.sql +0 -0
  372. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/queries/user.sql +0 -0
  373. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/postgres/query.py +0 -0
  374. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/__init__.py +0 -0
  375. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/client.py +0 -0
  376. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/client_test.py +0 -0
  377. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/extract.py +0 -0
  378. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/extract_test.py +0 -0
  379. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/.sqlfluff +0 -0
  380. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/column.sql +0 -0
  381. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/database.sql +0 -0
  382. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/group.sql +0 -0
  383. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/query.sql +0 -0
  384. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/query_serverless.sql +0 -0
  385. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/schema.sql +0 -0
  386. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/table.sql +0 -0
  387. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/table_freshness.sql +0 -0
  388. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/queries/user.sql +0 -0
  389. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/redshift/query.py +0 -0
  390. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/__init__.py +0 -0
  391. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/client.py +0 -0
  392. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/constants.py +0 -0
  393. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/extract.py +0 -0
  394. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/format.py +0 -0
  395. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/format_test.py +0 -0
  396. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/pagination.py +0 -0
  397. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/salesforce/soql.py +0 -0
  398. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/__init__.py +0 -0
  399. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/client.py +0 -0
  400. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/client_test.py +0 -0
  401. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/credentials.py +0 -0
  402. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/credentials_test.py +0 -0
  403. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/extract.py +0 -0
  404. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/.sqlfluff +0 -0
  405. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/column.sql +0 -0
  406. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/column_lineage.sql +0 -0
  407. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/database.sql +0 -0
  408. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/function.sql +0 -0
  409. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/grant_to_role.sql +0 -0
  410. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/grant_to_user.sql +0 -0
  411. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/query.sql +0 -0
  412. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/role.sql +0 -0
  413. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/schema.sql +0 -0
  414. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/table.sql +0 -0
  415. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/user.sql +0 -0
  416. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/queries/view_ddl.sql +0 -0
  417. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/snowflake/query.py +0 -0
  418. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/__init__.py +0 -0
  419. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/client.py +0 -0
  420. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/extract.py +0 -0
  421. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/.sqlfluff +0 -0
  422. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/column.sql +0 -0
  423. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/database.sql +0 -0
  424. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/schema.sql +0 -0
  425. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/table.sql +0 -0
  426. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/queries/user.sql +0 -0
  427. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/sqlserver/query.py +0 -0
  428. {castor_extractor-0.24.10 → castor_extractor-0.24.13}/castor_extractor/warehouse/synapse/queries/column.sql +0 -0
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.13 - 2025-05-05
4
+
5
+ * Rollback cloud-storage version as it's not compatible with Keboola
6
+
7
+ ## 0.24.12 - 2025-05-05
8
+
9
+ * Redshift - fix query definition of materialized views
10
+
11
+ ## 0.24.11 - 2025-05-05
12
+
13
+ * add support for Strategy (formerly MicroStrategy)
14
+
3
15
  ## 0.24.10 - 2025-04-30
4
16
 
5
17
  * Tableau - skip warnings instead of raising an error
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: castor-extractor
3
- Version: 0.24.10
3
+ Version: 0.24.13
4
4
  Summary: Extract your metadata assets.
5
5
  Home-page: https://www.castordoc.com/
6
6
  License: EULA
@@ -28,6 +28,7 @@ Provides-Extra: qlik
28
28
  Provides-Extra: redshift
29
29
  Provides-Extra: snowflake
30
30
  Provides-Extra: sqlserver
31
+ Provides-Extra: strategy
31
32
  Provides-Extra: tableau
32
33
  Requires-Dist: cryptography (>=43.0.0,<44.0.0) ; extra == "snowflake"
33
34
  Requires-Dist: databricks-sql-connector (==3.6.0) ; extra == "databricks" or extra == "all"
@@ -35,11 +36,12 @@ Requires-Dist: google-api-core (>=2.1.1,<3.0.0)
35
36
  Requires-Dist: google-api-python-client (>=2.121.0,<3.0.0) ; extra == "lookerstudio" or extra == "all"
36
37
  Requires-Dist: google-auth (>=2,<3)
37
38
  Requires-Dist: google-cloud-core (>=2.1.0,<3.0.0)
38
- Requires-Dist: google-cloud-storage (>=3.1.0,<4.0.0)
39
+ Requires-Dist: google-cloud-storage (>=2,<3)
39
40
  Requires-Dist: google-resumable-media (>=2.0.3,<3.0.0)
40
41
  Requires-Dist: googleapis-common-protos (>=1.53.0,<2.0.0)
41
42
  Requires-Dist: looker-sdk (>=25.0.0,<26.0.0) ; extra == "looker" or extra == "all"
42
43
  Requires-Dist: msal (>=1.20.0,<2.0.0) ; extra == "powerbi" or extra == "all"
44
+ Requires-Dist: mstrio-py (>=11.5.3.101,<12.0.0.0) ; (python_version >= "3.10") and (extra == "strategy" or extra == "all")
43
45
  Requires-Dist: numpy (<2) ; extra == "bigquery" or extra == "databricks" or extra == "all"
44
46
  Requires-Dist: numpy (>=1.26) ; (python_version >= "3.12" and python_version < "3.13") and (extra == "bigquery" or extra == "databricks" or extra == "all")
45
47
  Requires-Dist: pandas (>=2.1) ; (python_version >= "3.12" and python_version < "3.13") and (extra == "databricks" or extra == "all")
@@ -103,6 +105,8 @@ It also embeds utilities to help you push your metadata to Castor:
103
105
  Requirements: **python3.9+**
104
106
  <img src="https://upload.wikimedia.org/wikipedia/commons/c/c3/Python-logo-notext.svg" width=20 />
105
107
 
108
+ **Note:** The Strategy command requires **python3.10+**. All other modules work with python3.9+.
109
+
106
110
  ### Create castor-env
107
111
 
108
112
  We advise to create a dedicated [Python environment](https://docs.python.org/3/library/venv.html).
@@ -181,6 +185,7 @@ pip install castor-extractor[postgres]
181
185
  pip install castor-extractor[redshift]
182
186
  pip install castor-extractor[snowflake]
183
187
  pip install castor-extractor[sqlserver]
188
+ pip install castor-extractor[strategy]
184
189
  pip install castor-extractor[tableau]
185
190
  ```
186
191
 
@@ -204,12 +209,24 @@ export CASTOR_OUTPUT_DIRECTORY="/tmp/castor"
204
209
 
205
210
  ## Contact
206
211
 
207
- For any questions or bug report, contact us at [support@castordoc.com](mailto:support@castordoc.com)
212
+ For any questions or bug report, contact us at [support@coalesce.io](mailto:support@coalesce.io)
208
213
 
209
- [Castor](https://castordoc.com) helps you find, understand, use your data assets
214
+ [Catalog from Coalesce](https://castordoc.com) helps you find, understand, use your data assets
210
215
 
211
216
  # Changelog
212
217
 
218
+ ## 0.24.13 - 2025-05-05
219
+
220
+ * Rollback cloud-storage version as it's not compatible with Keboola
221
+
222
+ ## 0.24.12 - 2025-05-05
223
+
224
+ * Redshift - fix query definition of materialized views
225
+
226
+ ## 0.24.11 - 2025-05-05
227
+
228
+ * add support for Strategy (formerly MicroStrategy)
229
+
213
230
  ## 0.24.10 - 2025-04-30
214
231
 
215
232
  * Tableau - skip warnings instead of raising an error
@@ -37,6 +37,8 @@ It also embeds utilities to help you push your metadata to Castor:
37
37
  Requirements: **python3.9+**
38
38
  <img src="https://upload.wikimedia.org/wikipedia/commons/c/c3/Python-logo-notext.svg" width=20 />
39
39
 
40
+ **Note:** The Strategy command requires **python3.10+**. All other modules work with python3.9+.
41
+
40
42
  ### Create castor-env
41
43
 
42
44
  We advise to create a dedicated [Python environment](https://docs.python.org/3/library/venv.html).
@@ -115,6 +117,7 @@ pip install castor-extractor[postgres]
115
117
  pip install castor-extractor[redshift]
116
118
  pip install castor-extractor[snowflake]
117
119
  pip install castor-extractor[sqlserver]
120
+ pip install castor-extractor[strategy]
118
121
  pip install castor-extractor[tableau]
119
122
  ```
120
123
 
@@ -138,6 +141,6 @@ export CASTOR_OUTPUT_DIRECTORY="/tmp/castor"
138
141
 
139
142
  ## Contact
140
143
 
141
- For any questions or bug report, contact us at [support@castordoc.com](mailto:support@castordoc.com)
144
+ For any questions or bug report, contact us at [support@coalesce.io](mailto:support@coalesce.io)
142
145
 
143
- [Castor](https://castordoc.com) helps you find, understand, use your data assets
146
+ [Catalog from Coalesce](https://castordoc.com) helps you find, understand, use your data assets
@@ -0,0 +1,26 @@
1
+ import logging
2
+ from argparse import ArgumentParser
3
+
4
+ from castor_extractor.utils import parse_filled_arguments # type: ignore
5
+ from castor_extractor.visualization import strategy # type: ignore
6
+
7
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
8
+
9
+
10
+ def main():
11
+ parser = ArgumentParser()
12
+
13
+ parser.add_argument("-u", "--username", help="Strategy username")
14
+ parser.add_argument("-p", "--password", help="Strategy password")
15
+ parser.add_argument("-b", "--base-url", help="Strategy instance URL")
16
+ parser.add_argument("-o", "--output", help="Directory to write to")
17
+
18
+ parser.add_argument(
19
+ "-i",
20
+ "--project-ids",
21
+ nargs="*",
22
+ help="Optional list of project IDs",
23
+ default=None,
24
+ )
25
+
26
+ strategy.extract_all(**parse_filled_arguments(parser))
@@ -0,0 +1,3 @@
1
+ from .assets import StrategyAsset
2
+ from .client import StrategyClient, StrategyCredentials
3
+ from .extract import extract_all
@@ -0,0 +1,14 @@
1
+ from ...types import ExternalAsset
2
+
3
+
4
+ class StrategyAsset(ExternalAsset):
5
+ """Strategy assets that can be extracted"""
6
+
7
+ ATTRIBUTE = "attribute"
8
+ CUBE = "cube"
9
+ DASHBOARD = "dashboard"
10
+ DOCUMENT = "document"
11
+ FACT = "fact"
12
+ METRIC = "metric"
13
+ REPORT = "report"
14
+ USER = "user"
@@ -0,0 +1,2 @@
1
+ from .client import StrategyClient
2
+ from .credentials import StrategyCredentials
@@ -0,0 +1,313 @@
1
+ import logging
2
+ from collections.abc import Iterator
3
+ from enum import Enum
4
+ from typing import Any, Callable, Optional
5
+ from urllib.parse import urlparse
6
+
7
+ from mstrio.connection import Connection # type: ignore
8
+ from mstrio.helpers import IServerError # type: ignore
9
+ from mstrio.modeling import ( # type: ignore
10
+ list_attributes,
11
+ list_facts,
12
+ list_metrics,
13
+ )
14
+ from mstrio.project_objects import ( # type: ignore
15
+ Report,
16
+ list_dashboards,
17
+ list_documents,
18
+ list_olap_cubes,
19
+ list_reports,
20
+ )
21
+ from mstrio.server import Environment # type: ignore
22
+ from mstrio.types import ObjectSubTypes, ObjectTypes # type: ignore
23
+ from mstrio.users_and_groups import User, list_users # type: ignore
24
+ from mstrio.utils.entity import Entity # type: ignore
25
+ from mstrio.utils.helper import is_dashboard # type: ignore
26
+ from pydantic import BaseModel, ConfigDict
27
+
28
+ from ..assets import StrategyAsset
29
+ from .credentials import StrategyCredentials
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+ _BATCH_SIZE: int = 100
34
+
35
+
36
+ class URLTemplates(Enum):
37
+ DASHBOARD = (
38
+ "https://{hostname}/MicroStrategyLibrarySTD/app/{project_id}/{id_}"
39
+ )
40
+ DOCUMENT = "https://{hostname}/MicroStrategy/servlet/mstrWeb?documentID={id_}&projectID={project_id}"
41
+ REPORT = "https://{hostname}/MicroStrategy/servlet/mstrWeb?reportID={id_}&projectID={project_id}"
42
+ FOLDER = "https://{hostname}/MicroStrategy/servlet/mstrWeb?folderID={id_}&projectID={project_id}"
43
+
44
+
45
+ def _is_dashboard(entity: Entity) -> bool:
46
+ """
47
+ Returns True if the entity is a Dashboard. They can only be distinguished
48
+ from Documents by checking the `view_media` property.
49
+ """
50
+ is_type_document = entity.type == ObjectTypes.DOCUMENT_DEFINITION
51
+ return is_type_document and is_dashboard(entity.view_media)
52
+
53
+
54
+ def _is_report(entity: Entity) -> bool:
55
+ """
56
+ Returns True if the entity is a Report. Cubes share the same type as Reports,
57
+ so the subtype must be checked.
58
+ """
59
+ is_type_report = entity.type == ObjectTypes.REPORT_DEFINITION
60
+ is_subtype_cube = entity.subtype == ObjectSubTypes.OLAP_CUBE.value
61
+ return is_type_report and not is_subtype_cube
62
+
63
+
64
+ def _safe_get_attribute(entity: Entity, attribute: str) -> Optional[str]:
65
+ """
66
+ Some properties may raise an error. Example: retrieving a Report's `sql` fails if the Report has not been published.
67
+ This safely returns the attribute value, or None if the retrieval fails.
68
+ """
69
+ try:
70
+ value = getattr(entity, attribute)
71
+ except IServerError as e:
72
+ logger.error(f"Could not get {attribute} for entity {entity.id}: {e}")
73
+ value = None
74
+ return value
75
+
76
+
77
+ class Dependency(BaseModel):
78
+ id: str
79
+ name: str
80
+ subtype: int
81
+ type: int
82
+
83
+ model_config = ConfigDict(extra="ignore")
84
+
85
+
86
+ def _list_dependencies(entity: Entity) -> list[dict]:
87
+ """Lists the entity's dependencies, keeping only relevant fields."""
88
+ dependencies: list[dict] = []
89
+
90
+ offset = 0
91
+ while True:
92
+ batch = entity.list_dependencies(offset=offset, limit=_BATCH_SIZE)
93
+ dependencies.extend(batch)
94
+ if len(batch) < _BATCH_SIZE:
95
+ break
96
+ offset += _BATCH_SIZE
97
+
98
+ return [
99
+ Dependency(**dependency).model_dump() for dependency in dependencies
100
+ ]
101
+
102
+
103
+ def _level_1_folder_id(folders: list[dict]) -> str:
104
+ """Searches for the first enclosing folder and returns its ID."""
105
+ for folder in folders:
106
+ if folder["level"] == 1:
107
+ return folder["id"]
108
+
109
+ raise ValueError("No level 1 folder found")
110
+
111
+
112
+ class StrategyClient:
113
+ """Connect to Strategy through mstrio-py and fetch main assets."""
114
+
115
+ def __init__(self, credentials: StrategyCredentials):
116
+ self.base_url = credentials.base_url
117
+ self.connection = Connection(
118
+ base_url=self.base_url,
119
+ username=credentials.username,
120
+ password=credentials.password,
121
+ )
122
+
123
+ self.hostname = urlparse(self.base_url).hostname
124
+
125
+ if credentials.project_ids:
126
+ self.project_ids = credentials.project_ids
127
+ else:
128
+ env = Environment(connection=self.connection)
129
+ self.project_ids = [project.id for project in env.list_projects()]
130
+
131
+ def close(self):
132
+ self.connection.close()
133
+
134
+ def _url(self, entity: Entity) -> str:
135
+ """
136
+ Formats the right URL.
137
+ * Dashboards : viewed in MicroStrategy
138
+ * Reports and Documents : viewed in MicroStrategy Web
139
+ * other (i.e. Cubes): the URL leads to the folder in MicroStrategy Web
140
+ """
141
+ if _is_dashboard(entity):
142
+ id_ = entity.id
143
+ template = URLTemplates.DASHBOARD
144
+
145
+ elif entity.type == ObjectTypes.DOCUMENT_DEFINITION:
146
+ id_ = entity.id
147
+ template = URLTemplates.DOCUMENT
148
+
149
+ elif _is_report(entity):
150
+ id_ = entity.id
151
+ template = URLTemplates.REPORT
152
+
153
+ else:
154
+ # default to folder URL
155
+ id_ = _level_1_folder_id(entity.ancestors)
156
+ template = URLTemplates.FOLDER
157
+
158
+ return template.value.format(
159
+ hostname=self.hostname,
160
+ id_=id_,
161
+ project_id=entity.project_id,
162
+ )
163
+
164
+ def _common_entity_properties(
165
+ self,
166
+ entity: Entity,
167
+ with_url: bool = True,
168
+ with_description: bool = True,
169
+ ) -> dict:
170
+ """
171
+ Returns the entity's properties, including its dependencies
172
+ and optional URL and/or description.
173
+ """
174
+ dependencies = _list_dependencies(entity)
175
+ owner_id = entity.owner.id if isinstance(entity.owner, User) else None
176
+ properties = {
177
+ "dependencies": dependencies,
178
+ "id": entity.id,
179
+ "location": entity.location,
180
+ "name": entity.name,
181
+ "owner_id": owner_id,
182
+ "subtype": entity.subtype,
183
+ "type": entity.type.value,
184
+ }
185
+
186
+ if with_url:
187
+ properties["url"] = self._url(entity)
188
+
189
+ if with_description:
190
+ properties["description"] = _safe_get_attribute(
191
+ entity, "description"
192
+ )
193
+
194
+ return properties
195
+
196
+ def _report_properties(self, report: Report) -> dict[str, Any]:
197
+ """
198
+ Report properties contain an optional SQL source query. Due to a typing
199
+ bug in the mstrio package, the typing must be ignored.
200
+ """
201
+ properties = self._common_entity_properties(report) # type: ignore
202
+ properties["url"] = self._url(report) # type: ignore
203
+ properties["sql"] = _safe_get_attribute(report, "sql") # type: ignore
204
+ return properties
205
+
206
+ @staticmethod
207
+ def _user_properties(user: User) -> dict[str, Any]:
208
+ return {
209
+ "id": user.id,
210
+ "name": user.name,
211
+ "username": user.username,
212
+ "email": user.default_email_address,
213
+ }
214
+
215
+ def _fetch_entities(
216
+ self,
217
+ extract_callback: Callable,
218
+ with_url: bool = True,
219
+ with_description: bool = True,
220
+ custom_property_extractor: Optional[Callable] = None,
221
+ ) -> Iterator[dict[str, Any]]:
222
+ """
223
+ Yields all entities across all projects using the given retrieval function from the mstrio package.
224
+ """
225
+ for project_id in self.project_ids:
226
+ self.connection.select_project(project_id=project_id)
227
+
228
+ entities = extract_callback(connection=self.connection)
229
+
230
+ for entity in entities:
231
+ try:
232
+ if custom_property_extractor:
233
+ yield custom_property_extractor(entity)
234
+ else:
235
+ yield self._common_entity_properties(
236
+ entity,
237
+ with_url=with_url,
238
+ with_description=with_description,
239
+ )
240
+ except IServerError as e:
241
+ logger.error(
242
+ f"Could not fetch attributes for entity {entity.id}: {e}"
243
+ )
244
+
245
+ def _fetch_attributes(self) -> Iterator[dict[str, Any]]:
246
+ return self._fetch_entities(
247
+ list_attributes,
248
+ with_url=False,
249
+ )
250
+
251
+ def _fetch_cubes(self) -> Iterator[dict[str, Any]]:
252
+ return self._fetch_entities(list_olap_cubes)
253
+
254
+ def _fetch_dashboards(self) -> Iterator[dict[str, Any]]:
255
+ return self._fetch_entities(list_dashboards)
256
+
257
+ def _fetch_documents(self) -> Iterator[dict[str, Any]]:
258
+ return self._fetch_entities(list_documents)
259
+
260
+ def _fetch_facts(self) -> Iterator[dict[str, Any]]:
261
+ """Yields all facts. Descriptions are not needed for this entity type."""
262
+ return self._fetch_entities(
263
+ list_facts,
264
+ with_url=False,
265
+ with_description=False,
266
+ )
267
+
268
+ def _fetch_metrics(self) -> Iterator[dict[str, Any]]:
269
+ return self._fetch_entities(
270
+ list_metrics,
271
+ with_url=False,
272
+ )
273
+
274
+ def _fetch_reports(self) -> Iterator[dict[str, Any]]:
275
+ return self._fetch_entities(
276
+ list_reports,
277
+ custom_property_extractor=self._report_properties,
278
+ )
279
+
280
+ def _fetch_users(self) -> Iterator[dict[str, Any]]:
281
+ return self._fetch_entities(
282
+ list_users,
283
+ custom_property_extractor=self._user_properties,
284
+ )
285
+
286
+ def fetch(self, asset: StrategyAsset):
287
+ """Fetch the given asset type from Strategy"""
288
+ if asset == StrategyAsset.ATTRIBUTE:
289
+ yield from self._fetch_attributes()
290
+
291
+ elif asset == StrategyAsset.CUBE:
292
+ yield from self._fetch_cubes()
293
+
294
+ elif asset == StrategyAsset.DASHBOARD:
295
+ yield from self._fetch_dashboards()
296
+
297
+ elif asset == StrategyAsset.DOCUMENT:
298
+ yield from self._fetch_documents()
299
+
300
+ elif asset == StrategyAsset.FACT:
301
+ yield from self._fetch_facts()
302
+
303
+ elif asset == StrategyAsset.METRIC:
304
+ yield from self._fetch_metrics()
305
+
306
+ elif asset == StrategyAsset.REPORT:
307
+ yield from self._fetch_reports()
308
+
309
+ elif asset == StrategyAsset.USER:
310
+ yield from self._fetch_users()
311
+
312
+ else:
313
+ raise NotImplementedError(f"Asset type {asset} not implemented yet")
@@ -0,0 +1,38 @@
1
+ from typing import Any, Optional
2
+
3
+ from pydantic import Field, field_validator
4
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
+
6
+ STRATEGY_ENV_PREFIX = "CATALOG_STRATEGY_"
7
+
8
+
9
+ class StrategyCredentials(BaseSettings):
10
+ model_config = SettingsConfigDict(
11
+ env_prefix=STRATEGY_ENV_PREFIX,
12
+ extra="ignore",
13
+ populate_by_name=True,
14
+ )
15
+
16
+ base_url: str
17
+ password: str = Field(repr=False)
18
+ username: str
19
+
20
+ project_ids: Optional[list[str]] = None
21
+
22
+ @field_validator("project_ids", mode="before")
23
+ @classmethod
24
+ def _check_project_ids(cls, project_ids: Any) -> Optional[list[str]]:
25
+ """
26
+ The project IDs are optional and can be either a list of strings
27
+ or single string with project IDs separated by commas.
28
+ """
29
+ if project_ids is None:
30
+ return None
31
+
32
+ if isinstance(project_ids, str):
33
+ return [item.strip() for item in project_ids.split(",")]
34
+
35
+ if isinstance(project_ids, list):
36
+ return project_ids
37
+
38
+ raise ValueError(f"Unexpected type for project_id: {type(project_ids)}")
@@ -0,0 +1,43 @@
1
+ import logging
2
+ from collections.abc import Iterable
3
+ from typing import Union
4
+
5
+ from ...utils import (
6
+ OUTPUT_DIR,
7
+ current_timestamp,
8
+ deep_serialize,
9
+ from_env,
10
+ get_output_filename,
11
+ write_json,
12
+ write_summary,
13
+ )
14
+ from .assets import StrategyAsset
15
+ from .client import StrategyClient, StrategyCredentials
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def iterate_all_data(
21
+ client: StrategyClient,
22
+ ) -> Iterable[tuple[str, Union[list, dict]]]:
23
+ """Iterate over the extracted data from Strategy"""
24
+
25
+ for asset in StrategyAsset:
26
+ logger.info(f"Extracting {asset.value.upper()} from REST API")
27
+ data = client.fetch(asset)
28
+ yield asset.name.lower(), list(deep_serialize(data))
29
+
30
+
31
+ def extract_all(**kwargs) -> None:
32
+ _output_directory = kwargs.get("output") or from_env(OUTPUT_DIR)
33
+ credentials = StrategyCredentials(**kwargs)
34
+
35
+ client = StrategyClient(credentials=credentials)
36
+ ts = current_timestamp()
37
+
38
+ for key, data in iterate_all_data(client):
39
+ filename = get_output_filename(key, _output_directory, ts)
40
+ write_json(filename, data)
41
+
42
+ client.close()
43
+ write_summary(_output_directory, ts)
@@ -0,0 +1,33 @@
1
+ /*
2
+ This query was inspired from this thread:
3
+ https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_view_ddl.sql
4
+
5
+ Notable differences:
6
+ * There is no "--DROP" statement/comment here
7
+ * Left-trimming the view definition is necessary to capture "CREATE" statements starting with whitespaces or line breaks.
8
+ */
9
+
10
+ SELECT
11
+ CURRENT_DATABASE() AS database_name,
12
+ n.nspname AS schema_name,
13
+ c.relname AS view_name,
14
+ CASE
15
+ WHEN c.relnatts > 0 THEN
16
+ CASE
17
+ STRPOS(LOWER(LTRIM(pg_get_viewdef(c.oid, TRUE), '\t\r\n ')), 'create')
18
+ WHEN 1 THEN '' -- CREATE statement already present
19
+ ELSE -- No CREATE statement present, so no materialized view anyway
20
+ 'CREATE OR REPLACE VIEW ' || QUOTE_IDENT(n.nspname) || '.' || QUOTE_IDENT(c.relname) || ' AS\n'
21
+ END
22
+ || COALESCE(pg_get_viewdef(c.oid, TRUE), '')
23
+ ELSE COALESCE(pg_get_viewdef(c.oid, TRUE), '')
24
+ END AS view_definition
25
+ FROM
26
+ pg_catalog.pg_class AS c
27
+ INNER JOIN
28
+ pg_catalog.pg_namespace AS n
29
+ ON c.relnamespace = n.oid
30
+ WHERE
31
+ TRUE
32
+ AND relkind = 'v'
33
+ AND n.nspname NOT IN ('information_schema', 'pg_catalog');
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.2"]
3
3
 
4
4
  [tool.poetry]
5
5
  name = "castor-extractor"
6
- version = "0.24.10"
6
+ version = "0.24.13"
7
7
  description = "Extract your metadata assets."
8
8
  authors = ["Castor <support@castordoc.com>"]
9
9
  license = "EULA"
@@ -32,11 +32,12 @@ google-api-core = ">=2.1.1, <3.0.0"
32
32
  google-api-python-client = {version = "^2.121.0", optional = true}
33
33
  google-auth = "^2"
34
34
  google-cloud-core = ">=2.1.0, <3.0.0"
35
- google-cloud-storage = "^3.1.0"
35
+ google-cloud-storage = "^2"
36
36
  google-resumable-media = "^2.0.3"
37
37
  googleapis-common-protos = "^1.53.0"
38
38
  looker-sdk = { version = "^25.0.0", optional = true }
39
39
  msal = { version = "^1.20.0", optional = true }
40
+ mstrio-py = { version = "^11.5.3.101", python = ">=3.10", optional = true }
40
41
  numpy = [ # Subdependency of pyarrow. As numpy add 3.12 in 1.26. And poetry doesn't manage it well.
41
42
  { version = ">=1.26", python = "~3.12", optional = true },
42
43
  { version = "<2", optional = true }, # https://github.com/numpy/numpy/issues/26710 -> pandas isn't compatible with numpy 2
@@ -87,12 +88,14 @@ snowflake = [
87
88
  "cryptography",
88
89
  ]
89
90
  sqlserver = ["pymssql"]
91
+ strategy = ["mstrio-py"]
90
92
  tableau = ["tableauserverclient"]
91
93
  all = [
92
94
  "databricks-sql-connector",
93
95
  "google-api-python-client",
94
96
  "looker-sdk",
95
97
  "msal",
98
+ "mstrio-py",
96
99
  "numpy",
97
100
  "pandas",
98
101
  "psycopg2-binary",
@@ -137,6 +140,7 @@ castor-extract-salesforce-viz = "castor_extractor.commands.extract_salesforce_re
137
140
  castor-extract-sigma = "castor_extractor.commands.extract_sigma:main"
138
141
  castor-extract-snowflake = "castor_extractor.commands.extract_snowflake:main"
139
142
  castor-extract-sqlserver = "castor_extractor.commands.extract_sqlserver:main"
143
+ castor-extract-strategy = "castor_extractor.commands.extract_strategy:main"
140
144
  castor-extract-tableau = "castor_extractor.commands.extract_tableau:main"
141
145
  castor-extract-thoughtspot = "castor_extractor.commands.extract_thoughtspot:main"
142
146
  castor-file-check = "castor_extractor.commands.file_check:main"
@@ -1,19 +0,0 @@
1
- -- This query was inspired from this thread:
2
- -- https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_view_ddl.sql
3
- SELECT
4
- CURRENT_DATABASE() AS database_name,
5
- n.nspname AS schema_name,
6
- c.relname AS view_name,
7
- CASE
8
- WHEN c.relnatts > 0 THEN 'CREATE OR REPLACE VIEW ' + QUOTE_IDENT(n.nspname) + '.' + QUOTE_IDENT(c.relname) + ' AS\n' + COALESCE(pg_get_viewdef(c.oid, TRUE), '')
9
- ELSE COALESCE(pg_get_viewdef(c.oid, TRUE), '')
10
- END AS view_definition
11
- FROM
12
- pg_catalog.pg_class AS c
13
- INNER JOIN
14
- pg_catalog.pg_namespace AS n
15
- ON c.relnamespace = n.oid
16
- WHERE
17
- TRUE
18
- AND relkind = 'v'
19
- AND n.nspname NOT IN ('information_schema', 'pg_catalog');