openmetadata-ingestion 1.2.5.1__py3-none-any.whl → 1.3.0.0__py3-none-any.whl

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 openmetadata-ingestion might be problematic. Click here for more details.

Files changed (826) hide show
  1. airflow_provider_openmetadata/lineage/runner.py +44 -5
  2. airflow_provider_openmetadata/lineage/status.py +1 -1
  3. metadata/antlr/split_listener.py +1 -4
  4. metadata/applications/auto_tagger.py +212 -0
  5. metadata/cli/app.py +47 -0
  6. metadata/cli/db_dump.py +6 -3
  7. metadata/clients/aws_client.py +4 -0
  8. metadata/clients/domo_client.py +0 -2
  9. metadata/cmd.py +24 -13
  10. metadata/data_insight/processor/reports/entity_report_data_processor.py +8 -2
  11. metadata/data_insight/processor/reports/web_analytic_report_data_processor.py +4 -0
  12. metadata/data_insight/source/metadata.py +11 -4
  13. metadata/data_quality/interface/sqlalchemy/databricks/test_suite_interface.py +29 -0
  14. metadata/data_quality/interface/sqlalchemy/snowflake/test_suite_interface.py +29 -0
  15. metadata/data_quality/interface/sqlalchemy/sqa_test_suite_interface.py +6 -6
  16. metadata/data_quality/interface/sqlalchemy/unity_catalog/test_suite_interface.py +35 -0
  17. metadata/data_quality/interface/test_suite_interface_factory.py +40 -0
  18. metadata/data_quality/processor/test_case_runner.py +17 -8
  19. metadata/data_quality/source/test_suite.py +8 -2
  20. metadata/data_quality/validations/base_test_handler.py +21 -17
  21. metadata/data_quality/validations/column/base/columnValueLengthsToBeBetween.py +38 -1
  22. metadata/data_quality/validations/column/base/columnValuesToBeBetween.py +36 -1
  23. metadata/data_quality/validations/column/base/columnValuesToBeInSet.py +27 -0
  24. metadata/data_quality/validations/column/base/columnValuesToBeNotInSet.py +27 -0
  25. metadata/data_quality/validations/column/base/columnValuesToBeNotNull.py +27 -0
  26. metadata/data_quality/validations/column/base/columnValuesToBeUnique.py +15 -0
  27. metadata/data_quality/validations/column/base/columnValuesToMatchRegex.py +27 -0
  28. metadata/data_quality/validations/column/base/columnValuesToNotMatchRegex.py +27 -0
  29. metadata/data_quality/validations/column/pandas/columnValueLengthsToBeBetween.py +23 -0
  30. metadata/data_quality/validations/column/pandas/columnValuesToBeBetween.py +23 -0
  31. metadata/data_quality/validations/column/pandas/columnValuesToBeInSet.py +11 -0
  32. metadata/data_quality/validations/column/pandas/columnValuesToBeNotInSet.py +11 -0
  33. metadata/data_quality/validations/column/pandas/columnValuesToBeNotNull.py +11 -0
  34. metadata/data_quality/validations/column/pandas/columnValuesToMatchRegex.py +11 -0
  35. metadata/data_quality/validations/column/pandas/columnValuesToNotMatchRegex.py +11 -0
  36. metadata/data_quality/validations/column/sqlalchemy/columnValueLengthsToBeBetween.py +27 -0
  37. metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeBetween.py +23 -0
  38. metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeInSet.py +11 -0
  39. metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeNotInSet.py +11 -0
  40. metadata/data_quality/validations/column/sqlalchemy/columnValuesToBeNotNull.py +11 -0
  41. metadata/data_quality/validations/column/sqlalchemy/columnValuesToMatchRegex.py +11 -0
  42. metadata/data_quality/validations/column/sqlalchemy/columnValuesToNotMatchRegex.py +11 -0
  43. metadata/data_quality/validations/mixins/pandas_validator_mixin.py +13 -2
  44. metadata/data_quality/validations/mixins/sqa_validator_mixin.py +40 -0
  45. metadata/examples/workflows/databricks.yaml +0 -1
  46. metadata/examples/workflows/mongodb.yaml +4 -2
  47. metadata/examples/workflows/mstr.yaml +24 -0
  48. metadata/examples/workflows/sas.yaml +28 -0
  49. metadata/examples/workflows/unity_catalog.yaml +27 -0
  50. metadata/examples/workflows/unity_catalog_lineage.yaml +18 -0
  51. metadata/examples/workflows/unity_catalog_usage.yaml +35 -0
  52. metadata/generated/antlr/EntityLinkLexer.py +391 -292
  53. metadata/generated/antlr/EntityLinkListener.py +12 -12
  54. metadata/generated/antlr/EntityLinkParser.py +228 -103
  55. metadata/generated/schema/analytics/__init__.py +1 -1
  56. metadata/generated/schema/analytics/basic.py +1 -1
  57. metadata/generated/schema/analytics/reportData.py +1 -1
  58. metadata/generated/schema/analytics/reportDataType/__init__.py +1 -1
  59. metadata/generated/schema/analytics/reportDataType/aggregatedCostAnalysisReportData.py +1 -1
  60. metadata/generated/schema/analytics/reportDataType/entityReportData.py +1 -1
  61. metadata/generated/schema/analytics/reportDataType/rawCostAnalysisReportData.py +1 -1
  62. metadata/generated/schema/analytics/reportDataType/webAnalyticEntityViewReportData.py +1 -1
  63. metadata/generated/schema/analytics/reportDataType/webAnalyticUserActivityReportData.py +1 -1
  64. metadata/generated/schema/analytics/webAnalyticEvent.py +1 -1
  65. metadata/generated/schema/analytics/webAnalyticEventData.py +1 -1
  66. metadata/generated/schema/analytics/webAnalyticEventType/__init__.py +1 -1
  67. metadata/generated/schema/analytics/webAnalyticEventType/customEvent.py +1 -1
  68. metadata/generated/schema/analytics/webAnalyticEventType/pageViewEvent.py +1 -1
  69. metadata/generated/schema/api/__init__.py +1 -1
  70. metadata/generated/schema/api/addGlossaryToAssetsRequest.py +1 -1
  71. metadata/generated/schema/api/analytics/__init__.py +1 -1
  72. metadata/generated/schema/api/analytics/createWebAnalyticEvent.py +1 -1
  73. metadata/generated/schema/api/automations/__init__.py +1 -1
  74. metadata/generated/schema/api/automations/createWorkflow.py +1 -1
  75. metadata/generated/schema/api/bulkAssets.py +1 -1
  76. metadata/generated/schema/api/classification/__init__.py +1 -1
  77. metadata/generated/schema/api/classification/createClassification.py +1 -1
  78. metadata/generated/schema/api/classification/createTag.py +1 -1
  79. metadata/generated/schema/api/classification/loadTags.py +1 -1
  80. metadata/generated/schema/api/createBot.py +2 -3
  81. metadata/generated/schema/api/createEventPublisherJob.py +1 -1
  82. metadata/generated/schema/api/createType.py +1 -1
  83. metadata/generated/schema/api/data/__init__.py +1 -1
  84. metadata/generated/schema/api/data/createChart.py +1 -1
  85. metadata/generated/schema/api/data/createContainer.py +2 -2
  86. metadata/generated/schema/api/data/createCustomProperty.py +2 -3
  87. metadata/generated/schema/api/data/createDashboard.py +1 -1
  88. metadata/generated/schema/api/data/createDashboardDataModel.py +1 -1
  89. metadata/generated/schema/api/data/createDatabase.py +2 -3
  90. metadata/generated/schema/api/data/createDatabaseSchema.py +2 -3
  91. metadata/generated/schema/api/data/createGlossary.py +2 -3
  92. metadata/generated/schema/api/data/createGlossaryTerm.py +2 -3
  93. metadata/generated/schema/api/data/createMlModel.py +1 -1
  94. metadata/generated/schema/api/data/createPipeline.py +2 -2
  95. metadata/generated/schema/api/data/createQuery.py +2 -2
  96. metadata/generated/schema/api/data/createSearchIndex.py +1 -1
  97. metadata/generated/schema/api/data/createStoredProcedure.py +2 -4
  98. metadata/generated/schema/api/data/createTable.py +2 -2
  99. metadata/generated/schema/api/data/createTableProfile.py +1 -1
  100. metadata/generated/schema/api/data/createTopic.py +1 -1
  101. metadata/generated/schema/api/data/loadGlossary.py +1 -1
  102. metadata/generated/schema/api/data/restoreEntity.py +1 -1
  103. metadata/generated/schema/api/dataInsight/__init__.py +1 -1
  104. metadata/generated/schema/api/dataInsight/createDataInsightChart.py +1 -1
  105. metadata/generated/schema/api/dataInsight/kpi/__init__.py +1 -1
  106. metadata/generated/schema/api/dataInsight/kpi/createKpiRequest.py +1 -1
  107. metadata/generated/schema/api/docStore/__init__.py +1 -1
  108. metadata/generated/schema/api/docStore/createDocument.py +1 -1
  109. metadata/generated/schema/api/domains/__init__.py +1 -1
  110. metadata/generated/schema/api/domains/createDataProduct.py +1 -1
  111. metadata/generated/schema/api/domains/createDomain.py +1 -1
  112. metadata/generated/schema/api/feed/__init__.py +1 -1
  113. metadata/generated/schema/api/feed/closeTask.py +8 -1
  114. metadata/generated/schema/api/feed/createPost.py +1 -1
  115. metadata/generated/schema/api/feed/createSuggestion.py +30 -0
  116. metadata/generated/schema/api/feed/createThread.py +1 -1
  117. metadata/generated/schema/api/feed/resolveTask.py +12 -1
  118. metadata/generated/schema/api/feed/threadCount.py +18 -14
  119. metadata/generated/schema/api/lineage/__init__.py +1 -1
  120. metadata/generated/schema/api/lineage/addLineage.py +1 -1
  121. metadata/generated/schema/api/openMetadataServerVersion.py +1 -1
  122. metadata/generated/schema/api/policies/__init__.py +1 -1
  123. metadata/generated/schema/api/policies/createPolicy.py +1 -1
  124. metadata/generated/schema/api/services/__init__.py +1 -1
  125. metadata/generated/schema/api/services/createDashboardService.py +1 -1
  126. metadata/generated/schema/api/services/createDatabaseService.py +1 -1
  127. metadata/generated/schema/api/services/createMessagingService.py +1 -1
  128. metadata/generated/schema/api/services/createMetadataService.py +1 -1
  129. metadata/generated/schema/api/services/createMlModelService.py +1 -1
  130. metadata/generated/schema/api/services/createPipelineService.py +1 -1
  131. metadata/generated/schema/api/services/createSearchService.py +1 -1
  132. metadata/generated/schema/api/services/createStorageService.py +1 -1
  133. metadata/generated/schema/api/services/ingestionPipelines/__init__.py +1 -1
  134. metadata/generated/schema/api/services/ingestionPipelines/createIngestionPipeline.py +1 -1
  135. metadata/generated/schema/api/setOwner.py +1 -1
  136. metadata/generated/schema/api/teams/__init__.py +1 -1
  137. metadata/generated/schema/api/teams/createPersona.py +1 -1
  138. metadata/generated/schema/api/teams/createRole.py +2 -3
  139. metadata/generated/schema/api/teams/createTeam.py +1 -1
  140. metadata/generated/schema/api/teams/createUser.py +2 -2
  141. metadata/generated/schema/api/tests/__init__.py +1 -1
  142. metadata/generated/schema/api/tests/createCustomMetric.py +4 -2
  143. metadata/generated/schema/api/tests/createLogicalTestCases.py +1 -1
  144. metadata/generated/schema/api/tests/createTestCase.py +4 -1
  145. metadata/generated/schema/api/tests/createTestCaseResolutionStatus.py +31 -0
  146. metadata/generated/schema/api/tests/createTestDefinition.py +1 -1
  147. metadata/generated/schema/api/tests/createTestSuite.py +1 -1
  148. metadata/generated/schema/api/voteRequest.py +1 -1
  149. metadata/generated/schema/auth/__init__.py +1 -1
  150. metadata/generated/schema/auth/basicAuth.py +1 -1
  151. metadata/generated/schema/auth/basicLoginRequest.py +1 -1
  152. metadata/generated/schema/auth/changePasswordRequest.py +1 -1
  153. metadata/generated/schema/auth/createPersonalToken.py +1 -1
  154. metadata/generated/schema/auth/emailRequest.py +1 -1
  155. metadata/generated/schema/auth/emailVerificationToken.py +1 -1
  156. metadata/generated/schema/auth/generateToken.py +1 -1
  157. metadata/generated/schema/auth/jwtAuth.py +1 -1
  158. metadata/generated/schema/auth/loginRequest.py +1 -1
  159. metadata/generated/schema/auth/logoutRequest.py +1 -1
  160. metadata/generated/schema/auth/passwordResetRequest.py +3 -3
  161. metadata/generated/schema/auth/passwordResetToken.py +1 -1
  162. metadata/generated/schema/auth/personalAccessToken.py +1 -1
  163. metadata/generated/schema/auth/refreshToken.py +1 -1
  164. metadata/generated/schema/auth/registrationRequest.py +2 -2
  165. metadata/generated/schema/auth/revokePersonalToken.py +1 -1
  166. metadata/generated/schema/auth/revokeToken.py +1 -1
  167. metadata/generated/schema/auth/serviceTokenEnum.py +1 -1
  168. metadata/generated/schema/auth/ssoAuth.py +1 -1
  169. metadata/generated/schema/auth/tokenRefreshRequest.py +1 -1
  170. metadata/generated/schema/configuration/__init__.py +1 -1
  171. metadata/generated/schema/configuration/appsPrivateConfiguration.py +28 -0
  172. metadata/generated/schema/configuration/authConfig.py +1 -1
  173. metadata/generated/schema/configuration/authenticationConfiguration.py +1 -1
  174. metadata/generated/schema/configuration/authorizerConfiguration.py +1 -1
  175. metadata/generated/schema/configuration/changeEventConfiguration.py +1 -1
  176. metadata/generated/schema/configuration/elasticSearchConfiguration.py +7 -1
  177. metadata/generated/schema/configuration/eventHandlerConfiguration.py +1 -1
  178. metadata/generated/schema/configuration/fernetConfiguration.py +1 -1
  179. metadata/generated/schema/configuration/jwtTokenConfiguration.py +1 -1
  180. metadata/generated/schema/configuration/kafkaEventConfiguration.py +1 -1
  181. metadata/generated/schema/configuration/ldapConfiguration.py +28 -2
  182. metadata/generated/schema/configuration/ldapTrustStoreConfig/__init__.py +1 -1
  183. metadata/generated/schema/configuration/ldapTrustStoreConfig/customTrustManagerConfig.py +1 -1
  184. metadata/generated/schema/configuration/ldapTrustStoreConfig/hostNameConfig.py +1 -1
  185. metadata/generated/schema/configuration/ldapTrustStoreConfig/jvmDefaultConfig.py +1 -1
  186. metadata/generated/schema/configuration/ldapTrustStoreConfig/trustAllConfig.py +1 -1
  187. metadata/generated/schema/configuration/ldapTrustStoreConfig/truststoreConfig.py +1 -1
  188. metadata/generated/schema/configuration/loginConfiguration.py +1 -1
  189. metadata/generated/schema/configuration/logoConfiguration.py +1 -1
  190. metadata/generated/schema/configuration/pipelineServiceClientConfiguration.py +1 -1
  191. metadata/generated/schema/configuration/slackAppConfiguration.py +1 -1
  192. metadata/generated/schema/configuration/taskNotificationConfiguration.py +1 -1
  193. metadata/generated/schema/configuration/testResultNotificationConfiguration.py +1 -1
  194. metadata/generated/schema/dataInsight/__init__.py +1 -1
  195. metadata/generated/schema/dataInsight/dataInsightChart.py +1 -1
  196. metadata/generated/schema/dataInsight/dataInsightChartResult.py +1 -1
  197. metadata/generated/schema/dataInsight/kpi/__init__.py +1 -1
  198. metadata/generated/schema/dataInsight/kpi/basic.py +1 -1
  199. metadata/generated/schema/dataInsight/kpi/kpi.py +1 -1
  200. metadata/generated/schema/dataInsight/type/__init__.py +1 -1
  201. metadata/generated/schema/dataInsight/type/aggregatedUnusedAssetsCount.py +1 -1
  202. metadata/generated/schema/dataInsight/type/aggregatedUnusedAssetsSize.py +1 -1
  203. metadata/generated/schema/dataInsight/type/aggregatedUsedVsUnusedAssetsCount.py +1 -1
  204. metadata/generated/schema/dataInsight/type/aggregatedUsedVsUnusedAssetsSize.py +1 -1
  205. metadata/generated/schema/dataInsight/type/dailyActiveUsers.py +1 -1
  206. metadata/generated/schema/dataInsight/type/mostActiveUsers.py +1 -1
  207. metadata/generated/schema/dataInsight/type/mostViewedEntities.py +1 -1
  208. metadata/generated/schema/dataInsight/type/pageViewsByEntities.py +1 -1
  209. metadata/generated/schema/dataInsight/type/percentageOfEntitiesWithDescriptionByType.py +1 -1
  210. metadata/generated/schema/dataInsight/type/percentageOfEntitiesWithOwnerByType.py +1 -1
  211. metadata/generated/schema/dataInsight/type/percentageOfServicesWithDescription.py +1 -1
  212. metadata/generated/schema/dataInsight/type/percentageOfServicesWithOwner.py +1 -1
  213. metadata/generated/schema/dataInsight/type/totalEntitiesByTier.py +1 -1
  214. metadata/generated/schema/dataInsight/type/totalEntitiesByType.py +1 -1
  215. metadata/generated/schema/dataInsight/type/unusedAssets.py +1 -1
  216. metadata/generated/schema/email/__init__.py +1 -1
  217. metadata/generated/schema/email/emailRequest.py +1 -1
  218. metadata/generated/schema/email/smtpSettings.py +1 -1
  219. metadata/generated/schema/entity/__init__.py +1 -1
  220. metadata/generated/schema/entity/applications/__init__.py +1 -1
  221. metadata/generated/schema/entity/applications/app.py +18 -4
  222. metadata/generated/schema/entity/applications/appRunRecord.py +1 -1
  223. metadata/generated/schema/entity/applications/configuration/__init__.py +1 -1
  224. metadata/generated/schema/entity/applications/configuration/applicationConfig.py +30 -0
  225. metadata/generated/schema/entity/{services/connections/database/mongoDB → applications/configuration/external}/__init__.py +1 -1
  226. metadata/generated/schema/entity/applications/configuration/external/autoTaggerAppConfig.py +28 -0
  227. metadata/generated/schema/entity/applications/configuration/external/metaPilotAppConfig.py +46 -0
  228. metadata/generated/schema/entity/applications/configuration/internal/__init__.py +3 -0
  229. metadata/generated/schema/entity/applications/configuration/internal/dataInsightsAppConfig.py +14 -0
  230. metadata/generated/schema/entity/applications/configuration/internal/dataInsightsReportAppConfig.py +27 -0
  231. metadata/generated/schema/entity/applications/configuration/{searchIndexingApp.py → internal/searchIndexingAppConfig.py} +13 -3
  232. metadata/generated/schema/entity/applications/configuration/private/external/__init__.py +3 -0
  233. metadata/generated/schema/entity/applications/configuration/private/external/metaPilotAppPrivateConfig.py +26 -0
  234. metadata/generated/schema/entity/applications/createAppRequest.py +1 -1
  235. metadata/generated/schema/entity/applications/jobStatus.py +3 -3
  236. metadata/generated/schema/entity/applications/liveExecutionContext.py +1 -1
  237. metadata/generated/schema/entity/applications/marketplace/__init__.py +1 -1
  238. metadata/generated/schema/entity/applications/marketplace/appMarketPlaceDefinition.py +12 -3
  239. metadata/generated/schema/entity/applications/marketplace/createAppMarketPlaceDefinitionReq.py +12 -3
  240. metadata/generated/schema/entity/applications/scheduledExecutionContext.py +1 -1
  241. metadata/generated/schema/entity/automations/__init__.py +1 -1
  242. metadata/generated/schema/entity/automations/testServiceConnection.py +2 -2
  243. metadata/generated/schema/entity/automations/workflow.py +1 -1
  244. metadata/generated/schema/entity/bot.py +2 -3
  245. metadata/generated/schema/entity/classification/__init__.py +1 -1
  246. metadata/generated/schema/entity/classification/classification.py +1 -1
  247. metadata/generated/schema/entity/classification/tag.py +2 -2
  248. metadata/generated/schema/entity/data/__init__.py +1 -1
  249. metadata/generated/schema/entity/data/chart.py +1 -1
  250. metadata/generated/schema/entity/data/container.py +4 -9
  251. metadata/generated/schema/entity/data/dashboard.py +1 -1
  252. metadata/generated/schema/entity/data/dashboardDataModel.py +1 -1
  253. metadata/generated/schema/entity/data/database.py +4 -8
  254. metadata/generated/schema/entity/data/databaseSchema.py +2 -8
  255. metadata/generated/schema/entity/data/glossary.py +1 -1
  256. metadata/generated/schema/entity/data/glossaryTerm.py +1 -1
  257. metadata/generated/schema/entity/data/metrics.py +1 -1
  258. metadata/generated/schema/entity/data/mlmodel.py +1 -1
  259. metadata/generated/schema/entity/data/pipeline.py +6 -9
  260. metadata/generated/schema/entity/data/query.py +2 -2
  261. metadata/generated/schema/entity/data/report.py +1 -1
  262. metadata/generated/schema/entity/data/searchIndex.py +1 -1
  263. metadata/generated/schema/entity/data/storedProcedure.py +3 -9
  264. metadata/generated/schema/entity/data/table.py +18 -12
  265. metadata/generated/schema/entity/data/topic.py +1 -1
  266. metadata/generated/schema/entity/docStore/__init__.py +1 -1
  267. metadata/generated/schema/entity/docStore/document.py +1 -1
  268. metadata/generated/schema/entity/domains/__init__.py +1 -1
  269. metadata/generated/schema/entity/domains/dataProduct.py +1 -1
  270. metadata/generated/schema/entity/domains/domain.py +1 -1
  271. metadata/generated/schema/entity/events/__init__.py +1 -1
  272. metadata/generated/schema/entity/events/webhook.py +6 -3
  273. metadata/generated/schema/entity/feed/__init__.py +1 -1
  274. metadata/generated/schema/entity/feed/suggestion.py +61 -0
  275. metadata/generated/schema/entity/feed/thread.py +6 -1
  276. metadata/generated/schema/entity/policies/__init__.py +1 -1
  277. metadata/generated/schema/entity/policies/accessControl/__init__.py +1 -1
  278. metadata/generated/schema/entity/policies/accessControl/resourceDescriptor.py +1 -1
  279. metadata/generated/schema/entity/policies/accessControl/resourcePermission.py +1 -1
  280. metadata/generated/schema/entity/policies/accessControl/rule.py +1 -1
  281. metadata/generated/schema/entity/policies/filters.py +2 -5
  282. metadata/generated/schema/entity/policies/policy.py +1 -1
  283. metadata/generated/schema/entity/services/__init__.py +1 -1
  284. metadata/generated/schema/entity/services/connections/__init__.py +1 -1
  285. metadata/generated/schema/entity/services/connections/common/__init__.py +1 -1
  286. metadata/generated/schema/entity/services/connections/common/sslCertPaths.py +1 -1
  287. metadata/generated/schema/entity/services/connections/common/sslCertValues.py +1 -1
  288. metadata/generated/schema/entity/services/connections/common/sslConfig.py +1 -1
  289. metadata/generated/schema/entity/services/connections/connectionBasicType.py +1 -1
  290. metadata/generated/schema/entity/services/connections/dashboard/__init__.py +1 -1
  291. metadata/generated/schema/entity/services/connections/dashboard/customDashboardConnection.py +1 -1
  292. metadata/generated/schema/entity/services/connections/dashboard/domoDashboardConnection.py +1 -1
  293. metadata/generated/schema/entity/services/connections/dashboard/lightdashConnection.py +1 -1
  294. metadata/generated/schema/entity/services/connections/dashboard/lookerConnection.py +1 -1
  295. metadata/generated/schema/entity/services/connections/dashboard/metabaseConnection.py +1 -1
  296. metadata/generated/schema/entity/services/connections/dashboard/modeConnection.py +1 -1
  297. metadata/generated/schema/entity/services/connections/dashboard/mstrConnection.py +46 -0
  298. metadata/generated/schema/entity/services/connections/dashboard/powerBIConnection.py +1 -1
  299. metadata/generated/schema/entity/services/connections/dashboard/qlikSenseConnection.py +2 -2
  300. metadata/generated/schema/entity/services/connections/dashboard/quickSightConnection.py +1 -1
  301. metadata/generated/schema/entity/services/connections/dashboard/redashConnection.py +1 -1
  302. metadata/generated/schema/entity/services/connections/dashboard/supersetConnection.py +1 -1
  303. metadata/generated/schema/entity/services/connections/dashboard/tableauConnection.py +1 -1
  304. metadata/generated/schema/entity/services/connections/database/__init__.py +1 -1
  305. metadata/generated/schema/entity/services/connections/database/athenaConnection.py +2 -2
  306. metadata/generated/schema/entity/services/connections/database/azureSQLConnection.py +2 -2
  307. metadata/generated/schema/entity/services/connections/database/bigQueryConnection.py +2 -2
  308. metadata/generated/schema/entity/services/connections/database/clickhouseConnection.py +2 -2
  309. metadata/generated/schema/entity/services/connections/database/common/__init__.py +1 -1
  310. metadata/generated/schema/entity/services/connections/database/common/basicAuth.py +1 -1
  311. metadata/generated/schema/entity/services/connections/database/common/iamAuthConfig.py +1 -1
  312. metadata/generated/schema/entity/services/connections/database/common/jwtAuth.py +1 -1
  313. metadata/generated/schema/entity/services/connections/database/couchbaseConnection.py +6 -1
  314. metadata/generated/schema/entity/services/connections/database/customDatabaseConnection.py +1 -1
  315. metadata/generated/schema/entity/services/connections/database/databricksConnection.py +2 -7
  316. metadata/generated/schema/entity/services/connections/database/datalake/__init__.py +1 -1
  317. metadata/generated/schema/entity/services/connections/database/datalake/azureConfig.py +1 -1
  318. metadata/generated/schema/entity/services/connections/database/datalake/gcsConfig.py +1 -1
  319. metadata/generated/schema/entity/services/connections/database/datalake/s3Config.py +1 -1
  320. metadata/generated/schema/entity/services/connections/database/datalakeConnection.py +2 -2
  321. metadata/generated/schema/entity/services/connections/database/db2Connection.py +3 -2
  322. metadata/generated/schema/entity/services/connections/database/deltaLakeConnection.py +1 -1
  323. metadata/generated/schema/entity/services/connections/database/domoDatabaseConnection.py +1 -1
  324. metadata/generated/schema/entity/services/connections/database/dorisConnection.py +86 -0
  325. metadata/generated/schema/entity/services/connections/database/druidConnection.py +2 -2
  326. metadata/generated/schema/entity/services/connections/database/dynamoDBConnection.py +1 -1
  327. metadata/generated/schema/entity/services/connections/database/glueConnection.py +1 -1
  328. metadata/generated/schema/entity/services/connections/database/greenplumConnection.py +2 -2
  329. metadata/generated/schema/entity/services/connections/database/hiveConnection.py +2 -2
  330. metadata/generated/schema/entity/services/connections/database/iceberg/__init__.py +3 -0
  331. metadata/generated/schema/entity/services/connections/database/iceberg/dynamoDbCatalogConnection.py +17 -0
  332. metadata/generated/schema/entity/services/connections/database/iceberg/glueCatalogConnection.py +16 -0
  333. metadata/generated/schema/entity/services/connections/database/iceberg/hiveCatalogConnection.py +23 -0
  334. metadata/generated/schema/entity/services/connections/database/iceberg/icebergCatalog.py +43 -0
  335. metadata/generated/schema/entity/services/connections/database/iceberg/icebergFileSystem.py +20 -0
  336. metadata/generated/schema/entity/services/connections/database/iceberg/restCatalogConnection.py +69 -0
  337. metadata/generated/schema/entity/services/connections/database/icebergConnection.py +35 -0
  338. metadata/generated/schema/entity/services/connections/database/impalaConnection.py +2 -2
  339. metadata/generated/schema/entity/services/connections/database/mariaDBConnection.py +2 -2
  340. metadata/generated/schema/entity/services/connections/database/mongoDBConnection.py +24 -14
  341. metadata/generated/schema/entity/services/connections/database/mssqlConnection.py +5 -2
  342. metadata/generated/schema/entity/services/connections/database/mysqlConnection.py +2 -2
  343. metadata/generated/schema/entity/services/connections/database/oracleConnection.py +2 -2
  344. metadata/generated/schema/entity/services/connections/database/pinotDBConnection.py +2 -2
  345. metadata/generated/schema/entity/services/connections/database/postgresConnection.py +2 -2
  346. metadata/generated/schema/entity/services/connections/database/prestoConnection.py +2 -2
  347. metadata/generated/schema/entity/services/connections/database/redshiftConnection.py +2 -2
  348. metadata/generated/schema/entity/services/connections/database/salesforceConnection.py +1 -1
  349. metadata/generated/schema/entity/services/connections/database/sapHanaConnection.py +2 -2
  350. metadata/generated/schema/entity/services/connections/database/sasConnection.py +48 -0
  351. metadata/generated/schema/entity/services/connections/database/singleStoreConnection.py +2 -2
  352. metadata/generated/schema/entity/services/connections/database/snowflakeConnection.py +2 -2
  353. metadata/generated/schema/entity/services/connections/database/sqliteConnection.py +2 -2
  354. metadata/generated/schema/entity/services/connections/database/trinoConnection.py +2 -2
  355. metadata/generated/schema/entity/services/connections/database/unityCatalogConnection.py +90 -0
  356. metadata/generated/schema/entity/services/connections/database/verticaConnection.py +2 -2
  357. metadata/generated/schema/entity/services/connections/messaging/__init__.py +1 -1
  358. metadata/generated/schema/entity/services/connections/messaging/customMessagingConnection.py +1 -1
  359. metadata/generated/schema/entity/services/connections/messaging/kafkaConnection.py +1 -1
  360. metadata/generated/schema/entity/services/connections/messaging/kinesisConnection.py +1 -1
  361. metadata/generated/schema/entity/services/connections/messaging/pulsarConnection.py +1 -1
  362. metadata/generated/schema/entity/services/connections/messaging/redpandaConnection.py +1 -1
  363. metadata/generated/schema/entity/services/connections/messaging/saslMechanismType.py +1 -1
  364. metadata/generated/schema/entity/services/connections/metadata/__init__.py +1 -1
  365. metadata/generated/schema/entity/services/connections/metadata/alationConnection.py +1 -1
  366. metadata/generated/schema/entity/services/connections/metadata/amundsenConnection.py +1 -1
  367. metadata/generated/schema/entity/services/connections/metadata/atlasConnection.py +1 -1
  368. metadata/generated/schema/entity/services/connections/metadata/metadataESConnection.py +1 -1
  369. metadata/generated/schema/entity/services/connections/metadata/openMetadataConnection.py +5 -20
  370. metadata/generated/schema/entity/services/connections/mlmodel/__init__.py +1 -1
  371. metadata/generated/schema/entity/services/connections/mlmodel/customMlModelConnection.py +1 -1
  372. metadata/generated/schema/entity/services/connections/mlmodel/mlflowConnection.py +1 -1
  373. metadata/generated/schema/entity/services/connections/mlmodel/sageMakerConnection.py +1 -1
  374. metadata/generated/schema/entity/services/connections/mlmodel/sklearnConnection.py +1 -1
  375. metadata/generated/schema/entity/services/connections/pipeline/__init__.py +1 -1
  376. metadata/generated/schema/entity/services/connections/pipeline/airbyteConnection.py +1 -1
  377. metadata/generated/schema/entity/services/connections/pipeline/airflowConnection.py +2 -8
  378. metadata/generated/schema/entity/services/connections/pipeline/backendConnection.py +1 -1
  379. metadata/generated/schema/entity/services/connections/pipeline/customPipelineConnection.py +1 -1
  380. metadata/generated/schema/entity/services/connections/pipeline/dagsterConnection.py +1 -1
  381. metadata/generated/schema/entity/services/connections/pipeline/databricksPipelineConnection.py +1 -1
  382. metadata/generated/schema/entity/services/connections/pipeline/domoPipelineConnection.py +1 -1
  383. metadata/generated/schema/entity/services/connections/pipeline/fivetranConnection.py +1 -1
  384. metadata/generated/schema/entity/services/connections/pipeline/gluePipelineConnection.py +1 -1
  385. metadata/generated/schema/entity/services/connections/pipeline/nifiConnection.py +1 -1
  386. metadata/generated/schema/entity/services/connections/pipeline/sparkConnection.py +23 -0
  387. metadata/generated/schema/entity/services/connections/pipeline/splineConnection.py +1 -1
  388. metadata/generated/schema/entity/services/connections/search/__init__.py +1 -1
  389. metadata/generated/schema/entity/services/connections/search/customSearchConnection.py +1 -1
  390. metadata/generated/schema/entity/services/connections/search/elasticSearch/__init__.py +1 -1
  391. metadata/generated/schema/entity/services/connections/search/elasticSearch/apiAuth.py +1 -1
  392. metadata/generated/schema/entity/services/connections/search/elasticSearch/basicAuth.py +1 -1
  393. metadata/generated/schema/entity/services/connections/search/elasticSearchConnection.py +1 -1
  394. metadata/generated/schema/entity/services/connections/search/openSearchConnection.py +1 -1
  395. metadata/generated/schema/entity/services/connections/serviceConnection.py +1 -1
  396. metadata/generated/schema/entity/services/connections/storage/__init__.py +1 -1
  397. metadata/generated/schema/entity/services/connections/storage/{adlsConection.py → adlsConnection.py} +2 -2
  398. metadata/generated/schema/entity/services/connections/storage/customStorageConnection.py +1 -1
  399. metadata/generated/schema/entity/services/connections/storage/gcsConnection.py +1 -1
  400. metadata/generated/schema/entity/services/connections/storage/s3Connection.py +1 -1
  401. metadata/generated/schema/entity/services/connections/testConnectionDefinition.py +1 -1
  402. metadata/generated/schema/entity/services/connections/testConnectionResult.py +1 -1
  403. metadata/generated/schema/entity/services/dashboardService.py +4 -1
  404. metadata/generated/schema/entity/services/databaseService.py +13 -1
  405. metadata/generated/schema/entity/services/ingestionPipelines/__init__.py +1 -1
  406. metadata/generated/schema/entity/services/ingestionPipelines/ingestionPipeline.py +27 -22
  407. metadata/generated/schema/entity/services/ingestionPipelines/pipelineServiceClientResponse.py +1 -1
  408. metadata/generated/schema/entity/services/ingestionPipelines/status.py +56 -0
  409. metadata/generated/schema/entity/services/messagingService.py +1 -1
  410. metadata/generated/schema/entity/services/metadataService.py +1 -1
  411. metadata/generated/schema/entity/services/mlmodelService.py +1 -1
  412. metadata/generated/schema/entity/services/pipelineService.py +4 -1
  413. metadata/generated/schema/entity/services/searchService.py +1 -1
  414. metadata/generated/schema/entity/services/serviceType.py +1 -1
  415. metadata/generated/schema/entity/services/storageService.py +10 -3
  416. metadata/generated/schema/entity/teams/__init__.py +1 -1
  417. metadata/generated/schema/entity/teams/persona.py +1 -1
  418. metadata/generated/schema/entity/teams/role.py +2 -6
  419. metadata/generated/schema/entity/teams/team.py +1 -1
  420. metadata/generated/schema/entity/teams/teamHierarchy.py +1 -1
  421. metadata/generated/schema/entity/teams/user.py +3 -10
  422. metadata/generated/schema/entity/type.py +2 -2
  423. metadata/generated/schema/entity/utils/__init__.py +1 -1
  424. metadata/generated/schema/entity/utils/entitiesCount.py +1 -1
  425. metadata/generated/schema/entity/utils/servicesCount.py +1 -1
  426. metadata/generated/schema/entity/utils/supersetApiConnection.py +1 -1
  427. metadata/generated/schema/events/__init__.py +1 -1
  428. metadata/generated/schema/events/alertMetrics.py +27 -0
  429. metadata/generated/schema/events/api/__init__.py +1 -1
  430. metadata/generated/schema/events/api/createEventSubscription.py +14 -12
  431. metadata/generated/schema/events/emailAlertConfig.py +1 -1
  432. metadata/generated/schema/events/eventFilterRule.py +13 -2
  433. metadata/generated/schema/events/eventSubscription.py +89 -49
  434. metadata/generated/schema/events/eventSubscriptionOffset.py +21 -0
  435. metadata/generated/schema/events/failedEvent.py +26 -0
  436. metadata/generated/schema/events/filterResourceDescriptor.py +27 -0
  437. metadata/generated/schema/events/subscriptionResourceDescriptor.py +11 -10
  438. metadata/generated/schema/metadataIngestion/__init__.py +1 -1
  439. metadata/generated/schema/metadataIngestion/application.py +40 -0
  440. metadata/generated/schema/metadataIngestion/applicationPipeline.py +15 -6
  441. metadata/generated/schema/metadataIngestion/dashboardServiceMetadataPipeline.py +1 -1
  442. metadata/generated/schema/metadataIngestion/dataInsightPipeline.py +1 -1
  443. metadata/generated/schema/metadataIngestion/databaseServiceMetadataPipeline.py +6 -1
  444. metadata/generated/schema/metadataIngestion/databaseServiceProfilerPipeline.py +6 -1
  445. metadata/generated/schema/metadataIngestion/databaseServiceQueryLineagePipeline.py +1 -1
  446. metadata/generated/schema/metadataIngestion/databaseServiceQueryUsagePipeline.py +1 -1
  447. metadata/generated/schema/metadataIngestion/dbtPipeline.py +1 -1
  448. metadata/generated/schema/metadataIngestion/dbtconfig/__init__.py +1 -1
  449. metadata/generated/schema/metadataIngestion/dbtconfig/dbtAzureConfig.py +6 -3
  450. metadata/generated/schema/metadataIngestion/dbtconfig/dbtBucketDetails.py +1 -1
  451. metadata/generated/schema/metadataIngestion/dbtconfig/dbtCloudConfig.py +1 -1
  452. metadata/generated/schema/metadataIngestion/dbtconfig/dbtGCSConfig.py +6 -3
  453. metadata/generated/schema/metadataIngestion/dbtconfig/dbtHttpConfig.py +1 -1
  454. metadata/generated/schema/metadataIngestion/dbtconfig/dbtLocalConfig.py +1 -1
  455. metadata/generated/schema/metadataIngestion/dbtconfig/dbtS3Config.py +6 -3
  456. metadata/generated/schema/metadataIngestion/messagingServiceMetadataPipeline.py +1 -1
  457. metadata/generated/schema/metadataIngestion/metadataToElasticSearchPipeline.py +1 -1
  458. metadata/generated/schema/metadataIngestion/mlmodelServiceMetadataPipeline.py +1 -1
  459. metadata/generated/schema/metadataIngestion/pipelineServiceMetadataPipeline.py +1 -1
  460. metadata/generated/schema/metadataIngestion/searchServiceMetadataPipeline.py +1 -1
  461. metadata/generated/schema/metadataIngestion/storage/__init__.py +1 -1
  462. metadata/generated/schema/metadataIngestion/storage/containerMetadataConfig.py +1 -1
  463. metadata/generated/schema/metadataIngestion/storage/manifestMetadataConfig.py +1 -1
  464. metadata/generated/schema/metadataIngestion/storage/storageBucketDetails.py +1 -1
  465. metadata/generated/schema/metadataIngestion/storage/storageMetadataADLSConfig.py +2 -2
  466. metadata/generated/schema/metadataIngestion/storage/storageMetadataGCSConfig.py +24 -0
  467. metadata/generated/schema/metadataIngestion/storage/storageMetadataHttpConfig.py +1 -1
  468. metadata/generated/schema/metadataIngestion/storage/storageMetadataLocalConfig.py +1 -1
  469. metadata/generated/schema/metadataIngestion/storage/storageMetadataS3Config.py +1 -1
  470. metadata/generated/schema/metadataIngestion/storageServiceMetadataPipeline.py +8 -1
  471. metadata/generated/schema/metadataIngestion/testSuitePipeline.py +1 -1
  472. metadata/generated/schema/metadataIngestion/workflow.py +1 -1
  473. metadata/generated/schema/monitoring/__init__.py +1 -1
  474. metadata/generated/schema/monitoring/eventMonitorProvider.py +1 -1
  475. metadata/generated/schema/security/__init__.py +1 -1
  476. metadata/generated/schema/security/client/__init__.py +1 -1
  477. metadata/generated/schema/security/client/auth0SSOClientConfig.py +1 -1
  478. metadata/generated/schema/security/client/azureSSOClientConfig.py +1 -1
  479. metadata/generated/schema/security/client/customOidcSSOClientConfig.py +1 -1
  480. metadata/generated/schema/security/client/googleSSOClientConfig.py +1 -1
  481. metadata/generated/schema/security/client/oktaSSOClientConfig.py +1 -1
  482. metadata/generated/schema/security/client/openMetadataJWTClientConfig.py +1 -1
  483. metadata/generated/schema/security/client/samlSSOClientConfig.py +1 -1
  484. metadata/generated/schema/security/credentials/__init__.py +1 -1
  485. metadata/generated/schema/security/credentials/accessTokenAuth.py +1 -1
  486. metadata/generated/schema/security/credentials/apiAccessTokenAuth.py +1 -1
  487. metadata/generated/schema/security/credentials/awsCredentials.py +1 -1
  488. metadata/generated/schema/security/credentials/azureCredentials.py +1 -1
  489. metadata/generated/schema/security/credentials/basicAuth.py +1 -1
  490. metadata/generated/schema/security/credentials/bitbucketCredentials.py +1 -1
  491. metadata/generated/schema/security/credentials/gcpCredentials.py +1 -1
  492. metadata/generated/schema/security/credentials/gcpValues.py +1 -1
  493. metadata/generated/schema/security/credentials/gitCredentials.py +1 -1
  494. metadata/generated/schema/security/credentials/githubCredentials.py +1 -1
  495. metadata/generated/schema/security/secrets/__init__.py +1 -1
  496. metadata/generated/schema/security/secrets/secretsManagerClientLoader.py +1 -1
  497. metadata/generated/schema/security/secrets/secretsManagerConfiguration.py +14 -4
  498. metadata/generated/schema/security/secrets/secretsManagerProvider.py +2 -2
  499. metadata/generated/schema/security/securityConfiguration.py +1 -1
  500. metadata/generated/schema/security/ssl/__init__.py +1 -1
  501. metadata/generated/schema/security/ssl/validateSSLClientConfig.py +1 -1
  502. metadata/generated/schema/security/ssl/verifySSLConfig.py +4 -1
  503. metadata/generated/schema/settings/__init__.py +1 -1
  504. metadata/generated/schema/settings/settings.py +1 -1
  505. metadata/generated/schema/system/__init__.py +1 -1
  506. metadata/generated/schema/system/entityError.py +17 -0
  507. metadata/generated/schema/system/eventPublisherJob.py +5 -19
  508. metadata/generated/schema/system/indexingError.py +34 -0
  509. metadata/generated/schema/system/ui/__init__.py +1 -1
  510. metadata/generated/schema/system/ui/knowledgePanel.py +1 -1
  511. metadata/generated/schema/system/ui/page.py +1 -1
  512. metadata/generated/schema/tests/__init__.py +1 -1
  513. metadata/generated/schema/tests/assigned.py +18 -0
  514. metadata/generated/schema/tests/basic.py +17 -39
  515. metadata/generated/schema/tests/customMetric.py +4 -2
  516. metadata/generated/schema/tests/resolved.py +35 -0
  517. metadata/generated/schema/tests/testCase.py +11 -2
  518. metadata/generated/schema/tests/testCaseResolutionStatus.py +63 -0
  519. metadata/generated/schema/tests/testDefinition.py +5 -1
  520. metadata/generated/schema/tests/testSuite.py +1 -1
  521. metadata/generated/schema/type/__init__.py +1 -1
  522. metadata/generated/schema/type/auditLog.py +1 -1
  523. metadata/generated/schema/type/basic.py +5 -5
  524. metadata/generated/schema/type/bulkOperationResult.py +1 -1
  525. metadata/generated/schema/type/changeEvent.py +5 -75
  526. metadata/generated/schema/type/changeEventType.py +29 -0
  527. metadata/generated/schema/type/collectionDescriptor.py +1 -1
  528. metadata/generated/schema/type/csvDocumentation.py +1 -1
  529. metadata/generated/schema/type/csvErrorType.py +1 -1
  530. metadata/generated/schema/type/csvFile.py +1 -1
  531. metadata/generated/schema/type/csvImportResult.py +1 -1
  532. metadata/generated/schema/type/dailyCount.py +1 -1
  533. metadata/generated/schema/type/databaseConnectionConfig.py +1 -1
  534. metadata/generated/schema/type/entityHistory.py +1 -1
  535. metadata/generated/schema/type/entityLineage.py +2 -1
  536. metadata/generated/schema/type/entityReference.py +5 -1
  537. metadata/generated/schema/type/entityReferenceList.py +1 -1
  538. metadata/generated/schema/type/entityRelationship.py +1 -1
  539. metadata/generated/schema/type/entityUsage.py +1 -1
  540. metadata/generated/schema/type/filterPattern.py +1 -1
  541. metadata/generated/schema/type/function.py +7 -6
  542. metadata/generated/schema/type/include.py +1 -1
  543. metadata/generated/schema/type/jdbcConnection.py +1 -1
  544. metadata/generated/schema/type/lifeCycle.py +1 -1
  545. metadata/generated/schema/type/paging.py +1 -1
  546. metadata/generated/schema/type/profile.py +1 -1
  547. metadata/generated/schema/type/queryParserData.py +2 -2
  548. metadata/generated/schema/type/reaction.py +1 -1
  549. metadata/generated/schema/type/schedule.py +1 -1
  550. metadata/generated/schema/type/schema.py +1 -1
  551. metadata/generated/schema/type/tableQuery.py +2 -2
  552. metadata/generated/schema/type/tableUsageCount.py +1 -1
  553. metadata/generated/schema/type/tagLabel.py +1 -1
  554. metadata/generated/schema/type/usageDetails.py +1 -1
  555. metadata/generated/schema/type/usageRequest.py +1 -1
  556. metadata/generated/schema/type/votes.py +1 -1
  557. metadata/great_expectations/action.py +3 -2
  558. metadata/ingestion/api/delete.py +5 -2
  559. metadata/ingestion/api/models.py +4 -10
  560. metadata/ingestion/api/parser.py +3 -37
  561. metadata/ingestion/api/status.py +15 -4
  562. metadata/ingestion/api/step.py +39 -6
  563. metadata/ingestion/api/steps.py +20 -0
  564. metadata/ingestion/api/topology_runner.py +114 -168
  565. metadata/ingestion/bulksink/metadata_usage.py +11 -5
  566. metadata/ingestion/lineage/models.py +4 -0
  567. metadata/ingestion/lineage/parser.py +4 -5
  568. metadata/ingestion/lineage/sql_lineage.py +9 -17
  569. metadata/ingestion/models/custom_pydantic.py +4 -2
  570. metadata/ingestion/models/lf_tags_model.py +33 -0
  571. metadata/ingestion/models/patch_request.py +108 -2
  572. metadata/ingestion/models/tests_data.py +9 -0
  573. metadata/ingestion/models/topology.py +177 -60
  574. metadata/ingestion/ometa/auth_provider.py +0 -349
  575. metadata/ingestion/ometa/mixins/es_mixin.py +17 -0
  576. metadata/ingestion/ometa/mixins/patch_mixin.py +17 -68
  577. metadata/ingestion/ometa/mixins/suggestions_mixin.py +41 -0
  578. metadata/ingestion/ometa/mixins/table_mixin.py +18 -0
  579. metadata/ingestion/ometa/mixins/tests_mixin.py +24 -3
  580. metadata/ingestion/ometa/mixins/user_mixin.py +117 -22
  581. metadata/ingestion/ometa/ometa_api.py +18 -25
  582. metadata/ingestion/ometa/routes.py +7 -0
  583. metadata/ingestion/processor/query_parser.py +9 -2
  584. metadata/ingestion/sink/metadata_rest.py +25 -6
  585. metadata/ingestion/source/dashboard/dashboard_service.py +38 -61
  586. metadata/ingestion/source/dashboard/domodashboard/metadata.py +13 -14
  587. metadata/ingestion/source/dashboard/lightdash/metadata.py +2 -1
  588. metadata/ingestion/source/dashboard/looker/metadata.py +38 -25
  589. metadata/ingestion/source/dashboard/metabase/metadata.py +23 -6
  590. metadata/ingestion/source/dashboard/mode/client.py +10 -23
  591. metadata/ingestion/source/dashboard/mode/connection.py +6 -1
  592. metadata/ingestion/source/dashboard/mode/metadata.py +8 -4
  593. metadata/ingestion/source/dashboard/mstr/client.py +208 -0
  594. metadata/ingestion/source/dashboard/mstr/connection.py +53 -0
  595. metadata/ingestion/source/dashboard/mstr/metadata.py +182 -0
  596. metadata/ingestion/source/dashboard/mstr/models.py +144 -0
  597. metadata/ingestion/source/dashboard/powerbi/metadata.py +15 -10
  598. metadata/ingestion/source/dashboard/qliksense/metadata.py +11 -7
  599. metadata/ingestion/source/dashboard/quicksight/metadata.py +9 -5
  600. metadata/ingestion/source/dashboard/redash/metadata.py +23 -14
  601. metadata/ingestion/source/dashboard/superset/api_source.py +11 -8
  602. metadata/ingestion/source/dashboard/superset/client.py +16 -9
  603. metadata/ingestion/source/dashboard/superset/connection.py +3 -3
  604. metadata/ingestion/source/dashboard/superset/db_source.py +14 -10
  605. metadata/ingestion/source/dashboard/superset/mixin.py +22 -18
  606. metadata/ingestion/source/dashboard/superset/queries.py +1 -1
  607. metadata/ingestion/source/dashboard/tableau/client.py +91 -11
  608. metadata/ingestion/source/dashboard/tableau/connection.py +10 -1
  609. metadata/ingestion/source/dashboard/tableau/metadata.py +58 -70
  610. metadata/ingestion/source/dashboard/tableau/models.py +0 -8
  611. metadata/ingestion/source/dashboard/tableau/queries.py +5 -5
  612. metadata/ingestion/source/database/athena/client.py +80 -0
  613. metadata/ingestion/source/database/athena/connection.py +7 -0
  614. metadata/ingestion/source/database/athena/metadata.py +161 -19
  615. metadata/ingestion/source/database/azuresql/metadata.py +0 -1
  616. metadata/ingestion/source/database/bigquery/connection.py +24 -3
  617. metadata/ingestion/source/database/bigquery/metadata.py +39 -27
  618. metadata/ingestion/source/database/bigquery/queries.py +11 -4
  619. metadata/ingestion/source/database/bigquery/query_parser.py +13 -0
  620. metadata/ingestion/source/database/bigquery/usage.py +1 -3
  621. metadata/ingestion/source/database/column_helpers.py +0 -10
  622. metadata/ingestion/source/database/column_type_parser.py +11 -5
  623. metadata/ingestion/source/database/common_db_source.py +8 -2
  624. metadata/ingestion/source/database/common_nosql_source.py +8 -4
  625. metadata/ingestion/source/database/database_service.py +89 -7
  626. metadata/ingestion/source/database/databricks/client.py +5 -10
  627. metadata/ingestion/source/database/databricks/connection.py +16 -55
  628. metadata/ingestion/source/database/databricks/lineage.py +29 -26
  629. metadata/ingestion/source/database/databricks/metadata.py +448 -11
  630. metadata/ingestion/source/database/databricks/queries.py +28 -0
  631. metadata/ingestion/source/database/databricks/query_parser.py +5 -1
  632. metadata/ingestion/source/database/databricks/usage.py +2 -2
  633. metadata/ingestion/source/database/datalake/connection.py +31 -4
  634. metadata/ingestion/source/database/datalake/metadata.py +113 -27
  635. metadata/ingestion/source/database/dbt/dbt_config.py +5 -0
  636. metadata/ingestion/source/database/dbt/dbt_service.py +10 -14
  637. metadata/ingestion/source/database/dbt/dbt_utils.py +3 -1
  638. metadata/ingestion/source/database/dbt/metadata.py +11 -25
  639. metadata/ingestion/source/database/deltalake/metadata.py +6 -3
  640. metadata/ingestion/source/database/domodatabase/metadata.py +7 -6
  641. metadata/ingestion/source/database/doris/connection.py +72 -0
  642. metadata/ingestion/source/database/doris/metadata.py +315 -0
  643. metadata/ingestion/source/database/doris/queries.py +54 -0
  644. metadata/ingestion/source/database/doris/utils.py +64 -0
  645. metadata/ingestion/source/database/extended_sample_data.py +532 -0
  646. metadata/ingestion/source/database/glue/metadata.py +8 -5
  647. metadata/ingestion/source/database/hive/connection.py +0 -2
  648. metadata/ingestion/source/database/hive/utils.py +3 -0
  649. metadata/ingestion/source/database/iceberg/catalog/__init__.py +65 -0
  650. metadata/ingestion/source/database/iceberg/catalog/base.py +40 -0
  651. metadata/ingestion/source/database/iceberg/catalog/dynamodb.py +102 -0
  652. metadata/ingestion/source/database/iceberg/catalog/glue.py +88 -0
  653. metadata/ingestion/source/database/iceberg/catalog/hive.py +51 -0
  654. metadata/ingestion/source/database/iceberg/catalog/rest.py +84 -0
  655. metadata/ingestion/source/database/iceberg/connection.py +68 -0
  656. metadata/ingestion/source/database/iceberg/fs/__init__.py +52 -0
  657. metadata/ingestion/source/database/iceberg/fs/azure.py +44 -0
  658. metadata/ingestion/source/database/iceberg/fs/base.py +30 -0
  659. metadata/ingestion/source/database/iceberg/fs/s3.py +77 -0
  660. metadata/ingestion/source/database/iceberg/helper.py +124 -0
  661. metadata/ingestion/source/database/iceberg/metadata.py +311 -0
  662. metadata/ingestion/source/database/iceberg/models.py +66 -0
  663. metadata/ingestion/source/database/life_cycle_query_mixin.py +72 -3
  664. metadata/ingestion/source/database/mongodb/connection.py +1 -5
  665. metadata/ingestion/source/database/mssql/lineage.py +2 -0
  666. metadata/ingestion/source/database/mssql/metadata.py +108 -4
  667. metadata/ingestion/source/database/mssql/models.py +30 -0
  668. metadata/ingestion/source/database/mssql/queries.py +179 -1
  669. metadata/ingestion/source/database/mssql/utils.py +207 -4
  670. metadata/ingestion/source/database/mysql/metadata.py +0 -2
  671. metadata/ingestion/source/database/oracle/metadata.py +108 -2
  672. metadata/ingestion/source/database/oracle/models.py +30 -0
  673. metadata/ingestion/source/database/oracle/queries.py +98 -17
  674. metadata/ingestion/source/database/oracle/utils.py +0 -1
  675. metadata/ingestion/source/database/postgres/lineage.py +32 -14
  676. metadata/ingestion/source/database/postgres/metadata.py +15 -7
  677. metadata/ingestion/source/database/postgres/pgspider/lineage.py +0 -1
  678. metadata/ingestion/source/database/postgres/queries.py +4 -2
  679. metadata/ingestion/source/database/postgres/query_parser.py +4 -72
  680. metadata/ingestion/source/database/postgres/usage.py +41 -0
  681. metadata/ingestion/source/database/postgres/utils.py +34 -0
  682. metadata/ingestion/source/database/query_parser_source.py +8 -2
  683. metadata/ingestion/source/database/redshift/metadata.py +14 -4
  684. metadata/ingestion/source/database/redshift/queries.py +10 -4
  685. metadata/ingestion/source/database/redshift/query_parser.py +16 -0
  686. metadata/ingestion/source/database/redshift/usage.py +0 -2
  687. metadata/ingestion/source/database/salesforce/metadata.py +32 -3
  688. metadata/ingestion/source/database/sample_data.py +120 -6
  689. metadata/ingestion/source/database/sas/client.py +184 -0
  690. metadata/ingestion/source/database/sas/connection.py +47 -0
  691. metadata/ingestion/source/database/sas/extension_attr.py +103 -0
  692. metadata/ingestion/source/database/sas/metadata.py +914 -0
  693. metadata/ingestion/source/database/snowflake/metadata.py +8 -51
  694. metadata/ingestion/source/database/snowflake/models.py +6 -1
  695. metadata/ingestion/source/database/snowflake/queries.py +0 -4
  696. metadata/ingestion/source/database/snowflake/query_parser.py +5 -20
  697. metadata/ingestion/source/database/snowflake/utils.py +2 -6
  698. metadata/ingestion/source/database/stored_procedures_mixin.py +12 -8
  699. metadata/ingestion/source/database/unitycatalog/__init__.py +0 -0
  700. metadata/ingestion/source/database/unitycatalog/client.py +87 -0
  701. metadata/ingestion/source/database/unitycatalog/connection.py +97 -0
  702. metadata/ingestion/source/database/{databricks/unity_catalog → unitycatalog}/lineage.py +11 -11
  703. metadata/ingestion/source/database/{databricks/unity_catalog → unitycatalog}/metadata.py +42 -49
  704. metadata/ingestion/source/database/unitycatalog/query_parser.py +60 -0
  705. metadata/ingestion/source/database/unitycatalog/usage.py +31 -0
  706. metadata/ingestion/source/database/usage_source.py +3 -2
  707. metadata/ingestion/source/messaging/common_broker_source.py +6 -4
  708. metadata/ingestion/source/messaging/kinesis/metadata.py +6 -3
  709. metadata/ingestion/source/messaging/messaging_service.py +6 -2
  710. metadata/ingestion/source/metadata/amundsen/metadata.py +10 -7
  711. metadata/ingestion/source/metadata/atlas/metadata.py +5 -5
  712. metadata/ingestion/source/mlmodel/mlflow/metadata.py +5 -2
  713. metadata/ingestion/source/mlmodel/mlmodel_service.py +6 -2
  714. metadata/ingestion/source/pipeline/airflow/connection.py +0 -12
  715. metadata/ingestion/source/pipeline/airflow/lineage_parser.py +12 -6
  716. metadata/ingestion/source/pipeline/airflow/metadata.py +63 -34
  717. metadata/ingestion/source/pipeline/airflow/models.py +5 -4
  718. metadata/ingestion/source/pipeline/dagster/metadata.py +7 -4
  719. metadata/ingestion/source/pipeline/databrickspipeline/metadata.py +12 -9
  720. metadata/ingestion/source/pipeline/domopipeline/metadata.py +7 -4
  721. metadata/ingestion/source/pipeline/gluepipeline/metadata.py +5 -2
  722. metadata/ingestion/source/pipeline/pipeline_service.py +6 -2
  723. metadata/ingestion/source/pipeline/spline/metadata.py +0 -1
  724. metadata/ingestion/source/search/elasticsearch/connection.py +4 -1
  725. metadata/ingestion/source/search/elasticsearch/metadata.py +1 -2
  726. metadata/ingestion/source/search/search_service.py +6 -2
  727. metadata/ingestion/source/storage/s3/metadata.py +22 -17
  728. metadata/ingestion/source/storage/storage_service.py +53 -11
  729. metadata/ingestion/stage/table_usage.py +9 -2
  730. metadata/mixins/sqalchemy/sqa_mixin.py +14 -7
  731. metadata/parsers/protobuf_parser.py +29 -11
  732. metadata/pii/processor.py +9 -2
  733. metadata/profiler/api/models.py +19 -1
  734. metadata/profiler/interface/pandas/profiler_interface.py +59 -18
  735. metadata/profiler/interface/profiler_interface.py +13 -2
  736. metadata/profiler/interface/profiler_interface_factory.py +49 -14
  737. metadata/profiler/interface/sqlalchemy/bigquery/profiler_interface.py +3 -0
  738. metadata/profiler/interface/sqlalchemy/databricks/profiler_interface.py +26 -0
  739. metadata/profiler/interface/sqlalchemy/db2/__init__.py +0 -0
  740. metadata/profiler/interface/sqlalchemy/db2/profiler_interface.py +38 -0
  741. metadata/profiler/interface/sqlalchemy/mariadb/profiler_interface.py +85 -0
  742. metadata/profiler/interface/sqlalchemy/profiler_interface.py +77 -34
  743. metadata/profiler/interface/sqlalchemy/single_store/profiler_interface.py +2 -2
  744. metadata/profiler/interface/sqlalchemy/snowflake/profiler_interface.py +7 -0
  745. metadata/profiler/interface/sqlalchemy/trino/profiler_interface.py +2 -2
  746. metadata/profiler/interface/sqlalchemy/unity_catalog/profiler_interface.py +33 -0
  747. metadata/profiler/metrics/composed/null_ratio.py +1 -1
  748. metadata/profiler/metrics/hybrid/histogram.py +1 -0
  749. metadata/profiler/metrics/static/max.py +4 -1
  750. metadata/profiler/metrics/static/min.py +4 -1
  751. metadata/profiler/metrics/system/queries/snowflake.py +89 -17
  752. metadata/profiler/metrics/system/system.py +62 -20
  753. metadata/profiler/orm/functions/length.py +1 -0
  754. metadata/profiler/orm/functions/median.py +7 -0
  755. metadata/profiler/orm/functions/table_metric_computer.py +462 -0
  756. metadata/profiler/orm/registry.py +1 -0
  757. metadata/profiler/processor/core.py +116 -52
  758. metadata/profiler/processor/default.py +14 -3
  759. metadata/profiler/processor/handle_partition.py +2 -2
  760. metadata/profiler/processor/processor.py +9 -4
  761. metadata/profiler/processor/sampler/sqlalchemy/bigquery/sampler.py +31 -3
  762. metadata/profiler/processor/sampler/sqlalchemy/sampler.py +29 -6
  763. metadata/profiler/processor/sampler/sqlalchemy/trino/sampler.py +10 -4
  764. metadata/profiler/source/base/profiler_source.py +5 -2
  765. metadata/profiler/source/bigquery/type_mapper.py +0 -1
  766. metadata/profiler/source/mariadb/functions/median.py +20 -0
  767. metadata/profiler/source/mariadb/metrics/window/first_quartile.py +10 -0
  768. metadata/profiler/source/mariadb/metrics/window/median.py +10 -0
  769. metadata/profiler/source/mariadb/metrics/window/third_quartile.py +10 -0
  770. metadata/profiler/source/metadata.py +43 -10
  771. metadata/profiler/source/metadata_ext.py +16 -50
  772. metadata/py.typed +0 -0
  773. metadata/readers/dataframe/json.py +5 -4
  774. metadata/readers/file/api_reader.py +0 -1
  775. metadata/utils/constants.py +5 -0
  776. metadata/utils/datalake/datalake_utils.py +363 -129
  777. metadata/utils/entity_link.py +26 -6
  778. metadata/utils/fqn.py +20 -0
  779. metadata/utils/helpers.py +55 -9
  780. metadata/utils/importer.py +2 -3
  781. metadata/utils/life_cycle_utils.py +4 -4
  782. metadata/utils/logger.py +13 -2
  783. metadata/utils/partition.py +10 -5
  784. metadata/utils/secrets/client/loader.py +0 -1
  785. metadata/utils/secrets/noop_secrets_manager.py +4 -3
  786. metadata/utils/secrets/secrets_manager_factory.py +3 -4
  787. metadata/utils/{source_hash_utils.py → source_hash.py} +10 -1
  788. metadata/utils/sqlalchemy_utils.py +21 -0
  789. metadata/utils/storage_metadata_config.py +42 -1
  790. metadata/utils/tag_utils.py +5 -2
  791. metadata/workflow/application.py +154 -0
  792. metadata/workflow/application_output_handler.py +34 -0
  793. metadata/workflow/base.py +84 -153
  794. metadata/workflow/data_insight.py +8 -7
  795. metadata/workflow/data_quality.py +3 -2
  796. metadata/workflow/ingestion.py +203 -0
  797. metadata/workflow/metadata.py +2 -3
  798. metadata/workflow/output_handler.py +204 -0
  799. metadata/workflow/profiler.py +2 -2
  800. metadata/workflow/usage.py +3 -4
  801. metadata/workflow/workflow_output_handler.py +15 -255
  802. metadata/workflow/workflow_status_mixin.py +44 -52
  803. openmetadata_ingestion-1.3.0.0.dist-info/METADATA +749 -0
  804. {openmetadata_ingestion-1.2.5.1.dist-info → openmetadata_ingestion-1.3.0.0.dist-info}/RECORD +812 -725
  805. {openmetadata_ingestion-1.2.5.1.dist-info → openmetadata_ingestion-1.3.0.0.dist-info}/WHEEL +1 -1
  806. metadata/generated/schema/entity/applications/appConfig.py +0 -21
  807. metadata/generated/schema/entity/applications/configuration/dataInsightsApp.py +0 -17
  808. metadata/generated/schema/entity/applications/configuration/externalAppIngestionConfig.py +0 -38
  809. metadata/generated/schema/entity/services/connections/database/mongoDB/mongoDBValues.py +0 -44
  810. metadata/generated/schema/events/dataInsightAlertConfig.py +0 -17
  811. metadata/generated/schema/events/entitySpelFilters.py +0 -19
  812. metadata/ingestion/models/es_documents.py +0 -339
  813. metadata/ingestion/ometa/mixins/glossary_mixin.py +0 -501
  814. metadata/ingestion/ometa/provider_registry.py +0 -144
  815. metadata/ingestion/source/database/databricks/legacy/lineage.py +0 -51
  816. metadata/ingestion/source/database/databricks/legacy/metadata.py +0 -339
  817. metadata/ingestion/source/metadata/metadata_elasticsearch/metadata.py +0 -144
  818. metadata/profiler/orm/functions/table_metric_construct.py +0 -365
  819. openmetadata_ingestion-1.2.5.1.dist-info/METADATA +0 -426
  820. /metadata/ingestion/source/{database/databricks/legacy → dashboard/mstr}/__init__.py +0 -0
  821. /metadata/ingestion/source/database/{databricks/unity_catalog → doris}/__init__.py +0 -0
  822. /metadata/ingestion/source/{metadata/metadata_elasticsearch → database/sas}/__init__.py +0 -0
  823. /metadata/ingestion/source/database/{databricks → unitycatalog}/models.py +0 -0
  824. {openmetadata_ingestion-1.2.5.1.dist-info → openmetadata_ingestion-1.3.0.0.dist-info}/LICENSE +0 -0
  825. {openmetadata_ingestion-1.2.5.1.dist-info → openmetadata_ingestion-1.3.0.0.dist-info}/entry_points.txt +0 -0
  826. {openmetadata_ingestion-1.2.5.1.dist-info → openmetadata_ingestion-1.3.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,914 @@
1
+ # Copyright 2021 Collate
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software
7
+ # distributed under the License is distributed on an "AS IS" BASIS,
8
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
+ # See the License for the specific language governing permissions and
10
+ # limitations under the License.
11
+
12
+ """
13
+ SAS source to extract metadata
14
+ """
15
+
16
+ # pylint: disable=protected-access,too-many-branches,too-many-locals
17
+ import copy
18
+ import json
19
+ import re
20
+ import time
21
+ import traceback
22
+ from typing import Any, Iterable, Optional, Tuple, Union
23
+
24
+ from requests.exceptions import HTTPError
25
+
26
+ from metadata.generated.schema.api.data.createDashboard import CreateDashboardRequest
27
+ from metadata.generated.schema.api.data.createDatabase import CreateDatabaseRequest
28
+ from metadata.generated.schema.api.data.createDatabaseSchema import (
29
+ CreateDatabaseSchemaRequest,
30
+ )
31
+ from metadata.generated.schema.api.data.createQuery import CreateQueryRequest
32
+ from metadata.generated.schema.api.data.createStoredProcedure import (
33
+ CreateStoredProcedureRequest,
34
+ )
35
+ from metadata.generated.schema.api.data.createTable import CreateTableRequest
36
+ from metadata.generated.schema.api.data.createTableProfile import (
37
+ CreateTableProfileRequest,
38
+ )
39
+ from metadata.generated.schema.api.lineage.addLineage import AddLineageRequest
40
+ from metadata.generated.schema.api.services.createDashboardService import (
41
+ CreateDashboardServiceRequest,
42
+ )
43
+ from metadata.generated.schema.entity.data.dashboard import Dashboard
44
+ from metadata.generated.schema.entity.data.database import Database
45
+ from metadata.generated.schema.entity.data.table import (
46
+ Column,
47
+ ColumnProfile,
48
+ Table,
49
+ TableProfile,
50
+ )
51
+ from metadata.generated.schema.entity.services.connections.dashboard.customDashboardConnection import (
52
+ CustomDashboardConnection,
53
+ CustomDashboardType,
54
+ )
55
+ from metadata.generated.schema.entity.services.connections.database.sasConnection import (
56
+ SASConnection,
57
+ )
58
+ from metadata.generated.schema.entity.services.dashboardService import (
59
+ DashboardConnection,
60
+ DashboardServiceType,
61
+ )
62
+ from metadata.generated.schema.metadataIngestion.databaseServiceMetadataPipeline import (
63
+ DatabaseServiceMetadataPipeline,
64
+ )
65
+ from metadata.generated.schema.metadataIngestion.workflow import (
66
+ Source as WorkflowSource,
67
+ )
68
+ from metadata.generated.schema.type.entityLineage import EntitiesEdge
69
+ from metadata.generated.schema.type.entityReference import EntityReference
70
+ from metadata.ingestion.api.common import Entity
71
+ from metadata.ingestion.api.models import Either, StackTraceError
72
+ from metadata.ingestion.api.steps import InvalidSourceException
73
+ from metadata.ingestion.models.ometa_classification import OMetaTagAndClassification
74
+ from metadata.ingestion.ometa.ometa_api import OpenMetadata
75
+ from metadata.ingestion.source.connections import get_connection, get_test_connection_fn
76
+ from metadata.ingestion.source.database.column_type_parser import ColumnTypeParser
77
+ from metadata.ingestion.source.database.database_service import DatabaseServiceSource
78
+ from metadata.ingestion.source.database.sas.client import SASClient
79
+ from metadata.ingestion.source.database.sas.extension_attr import TABLE_CUSTOM_ATTR
80
+ from metadata.utils import fqn
81
+ from metadata.utils.logger import ingestion_logger
82
+
83
+ logger = ingestion_logger()
84
+
85
+
86
+ class SasSource(
87
+ DatabaseServiceSource
88
+ ): # pylint: disable=too-many-instance-attributes,too-many-public-methods
89
+ """
90
+ Implements the necessary methods to extract
91
+ Database metadata from SAS Database Source
92
+ """
93
+
94
+ config: WorkflowSource
95
+ sas_client: SASClient
96
+
97
+ def __init__(self, config: WorkflowSource, metadata: OpenMetadata):
98
+ super().__init__()
99
+ self.config = config
100
+ self.metadata = metadata
101
+ self.source_config: DatabaseServiceMetadataPipeline = (
102
+ self.config.sourceConfig.config
103
+ )
104
+ self.service_connection = self.config.serviceConnection.__root__.config
105
+
106
+ self.sas_client = get_connection(self.service_connection)
107
+ self.connection_obj = self.sas_client
108
+ self.test_connection()
109
+
110
+ self.db_service_name = self.config.serviceName
111
+ self.db_name = None
112
+ self.db_schema_name = None
113
+ self.table_fqns = []
114
+
115
+ self.dashboard_service_name = None
116
+ self.chart_names = None
117
+ self.report_description = None
118
+
119
+ self.add_table_custom_attributes()
120
+
121
+ self.databases = None
122
+ self.database_schemas = None
123
+
124
+ @classmethod
125
+ def create(cls, config_dict: dict, metadata: OpenMetadata):
126
+ logger.info(f"running create {config_dict}")
127
+ config: WorkflowSource = WorkflowSource.parse_obj(config_dict)
128
+ connection: SASConnection = config.serviceConnection.__root__.config
129
+ if not isinstance(connection, SASConnection):
130
+ raise InvalidSourceException(
131
+ f"Expected SASConnection, but got {connection}"
132
+ )
133
+ return cls(config, metadata)
134
+
135
+ def _iter(self) -> Iterable[Either[Entity]]:
136
+ # For debug purpose (when ingesting locally)
137
+ # yield Either(
138
+ # right=self.metadata.get_create_service_from_source(
139
+ # entity=DatabaseService, config=self.config
140
+ # )
141
+ # )
142
+
143
+ # create tables from sas dataSets
144
+ if self.sas_client.enable_datatables:
145
+ for table in self.sas_client.list_assets("datasets"):
146
+ yield from self.create_table_entity(table)
147
+
148
+ if self.sas_client.enable_reports:
149
+ yield from self.create_dashboard_service("SAS_reports")
150
+ for report in self.sas_client.list_assets("reports"):
151
+ yield from self.process_report(report)
152
+
153
+ if self.sas_client.enable_dataflows:
154
+ yield from self.create_dashboard_service("SAS_dataFlows")
155
+ for data_flow in self.sas_client.list_assets("dataflows"):
156
+ yield from self.process_dataflow(data_flow)
157
+
158
+ def process_report(self, report):
159
+ self.table_fqns = []
160
+ logger.info(f"Ingesting report: {report}")
161
+ report_instance = self.sas_client.get_instance(report["id"])
162
+ for table in self.get_report_tables(
163
+ report_instance["resourceId"].split("/")[-1]
164
+ ):
165
+ yield from self.create_table_entity(table)
166
+ yield from self.create_report_entity(report_instance)
167
+
168
+ def process_dataflow(self, data_flow):
169
+ """
170
+ Process dataflow assets
171
+ """
172
+ self.table_fqns = []
173
+ logger.info(f"Ingesting dataflow: {data_flow}")
174
+ data_flow_instance = self.sas_client.get_instance(data_flow["id"])
175
+ if not data_flow_instance.get("relationships"):
176
+ logger.warning(f"No relationships are found for {data_flow['name']}")
177
+ return
178
+ input_asset_ids = [
179
+ rel["endpointId"]
180
+ for rel in data_flow_instance["relationships"]
181
+ if rel["definitionId"] == "6179884b-91ec-4236-ad6b-52c7f454f217"
182
+ ]
183
+ output_asset_ids = [
184
+ rel["endpointId"]
185
+ for rel in data_flow_instance["relationships"]
186
+ if rel["definitionId"] == "e1349270-fdbb-4231-9841-79917a307471"
187
+ ]
188
+ for input_asset in (self.sas_client.get_instance(id) for id in input_asset_ids):
189
+ yield from self.create_table_entity(input_asset)
190
+ input_fqns = copy.deepcopy(self.table_fqns)
191
+ self.table_fqns = []
192
+ for output_asset in (
193
+ self.sas_client.get_instance(id) for id in output_asset_ids
194
+ ):
195
+ yield from self.create_table_entity(output_asset)
196
+ yield from self.create_data_flow_entity(
197
+ data_flow_instance, input_fqns, copy.deepcopy(self.table_fqns)
198
+ )
199
+
200
+ def create_database_alt(self, db):
201
+ """
202
+ Find the name of the mock DB service
203
+ Use the link to the parent of the resourceId of the datastore itself, and use its name
204
+ Then the db service name will be the provider id
205
+ """
206
+ data_store_endpoint = db["resourceId"][1:]
207
+ logger.info(f"{data_store_endpoint}")
208
+ data_store_resource = self.sas_client.get_data_source(data_store_endpoint)
209
+
210
+ data_store_parent_endpoint = ""
211
+ for link in data_store_resource["links"]:
212
+ if link["rel"] == "parent":
213
+ data_store_parent_endpoint = link["uri"][1:]
214
+ break
215
+
216
+ data_store_parent = self.sas_client.get_data_source(data_store_parent_endpoint)
217
+ self.db_name = data_store_parent["id"]
218
+ database = CreateDatabaseRequest(
219
+ name=data_store_parent["id"],
220
+ displayName=data_store_parent["name"],
221
+ service=self.db_service_name,
222
+ )
223
+ database_entity = self.metadata.create_or_update(data=database)
224
+ return database_entity
225
+
226
+ def create_database_schema(self, table):
227
+ """
228
+ create database schema
229
+ """
230
+ try:
231
+ context = table["resourceId"].split("/")[3]
232
+
233
+ provider = context.split("~")[0]
234
+ self.db_name = provider + "." + context.split("~")[2]
235
+ self.db_schema_name = context.split("~")[4]
236
+
237
+ database = CreateDatabaseRequest(
238
+ name=self.db_name,
239
+ displayName=self.db_name,
240
+ service=self.config.serviceName,
241
+ )
242
+ database = self.metadata.create_or_update(data=database)
243
+
244
+ db_schema = CreateDatabaseSchemaRequest(
245
+ name=self.db_schema_name, database=database.fullyQualifiedName
246
+ )
247
+ db_schema_entity = self.metadata.create_or_update(db_schema)
248
+ return db_schema_entity
249
+
250
+ except HTTPError as _:
251
+ # Find the "database" entity in Information Catalog
252
+ # First see if the table is a member of the library through the relationships attribute
253
+ # Or we could use views to query the dataStores
254
+ data_store_data_sets = "4b114f6e-1c2a-4060-9184-6809a612f27b"
255
+ data_store_id = None
256
+ for relation in table["relationships"]:
257
+ if relation["definitionId"] != data_store_data_sets:
258
+ continue
259
+ data_store_id = relation["endpointId"]
260
+ break
261
+
262
+ if data_store_id is None:
263
+ # log error due to exclude amount of work with tables in dataTables
264
+ logger.error("Data store id should not be none")
265
+ return None
266
+
267
+ data_store = self.sas_client.get_instance(data_store_id)
268
+ database = self.create_database_alt(data_store)
269
+ self.db_schema_name = data_store["name"]
270
+ db_schema = CreateDatabaseSchemaRequest(
271
+ name=data_store["name"], database=database.fullyQualifiedName
272
+ )
273
+ db_schema_entity = self.metadata.create_or_update(db_schema)
274
+ return db_schema_entity
275
+
276
+ def create_columns_alt(self, table):
277
+ """
278
+ Create columns by loading the table when they are not already loaded
279
+ """
280
+ columns_endpoint = ""
281
+ load_endpoint = ""
282
+ for link in table["links"]:
283
+ if link["rel"] == "columns":
284
+ columns_endpoint = link["uri"][1:] + "?limit=1000"
285
+ if link["rel"] == "load":
286
+ load_endpoint = link["uri"][1:]
287
+ if load_endpoint:
288
+ self.sas_client.load_table(load_endpoint)
289
+ columns_resource = self.sas_client.get_resource(columns_endpoint)
290
+ columns = []
291
+ for item in columns_resource["items"]:
292
+ datatype = item["type"]
293
+ if datatype == "num":
294
+ datatype = "numeric"
295
+ parsed_string = ColumnTypeParser._parse_datatype_string(datatype)
296
+ col_name = item["name"]
297
+ parsed_string["name"] = col_name.replace('"', "'")
298
+ parsed_string["ordinalPosition"] = item["index"]
299
+ if datatype.lower() in ["char", "varchar", "binary", "varbinary"]:
300
+ parsed_string["dataLength"] = 0
301
+ col = Column(**parsed_string)
302
+ columns.append(col)
303
+ return columns
304
+
305
+ def get_entities_using_view(self, table_id):
306
+ """
307
+ Get all the col_entity_instances related to table using views
308
+ """
309
+ views_query = {
310
+ "query": "match (t:dataSet)-[r:dataSetDataFields]->(c:dataField) return t,r,c",
311
+ "parameters": {"t": {"id": f"{table_id}"}},
312
+ }
313
+ views_data = json.dumps(views_query)
314
+ views = self.sas_client.get_views(views_data)
315
+ if not views.get("entities"): # if the resource is not a table
316
+ return None, None
317
+
318
+ col_entity_instances = views["entities"]
319
+ # find datatables in col_entity_instances
320
+ table_entity_instance = list(
321
+ filter(lambda x: "Table" in x["type"], col_entity_instances)
322
+ )
323
+ if len(table_entity_instance) == 1:
324
+ table_entity_instance = table_entity_instance[0]
325
+
326
+ return col_entity_instances, table_entity_instance
327
+
328
+ def get_table_fqn(self, table_name):
329
+ return fqn.build(
330
+ self.metadata,
331
+ entity_type=Table,
332
+ service_name=self.db_service_name,
333
+ database_name=self.db_name,
334
+ schema_name=self.db_schema_name,
335
+ table_name=table_name,
336
+ )
337
+
338
+ def create_columns_and_profiles(self, entities, table_entity_instance):
339
+ """
340
+ Create columns and profiles
341
+ """
342
+ columns = []
343
+ col_profile_list = []
344
+ for entity in entities:
345
+ if entity["id"] == table_entity_instance["id"]:
346
+ continue
347
+ if "Column" not in entity["type"]:
348
+ continue
349
+ col_attributes = entity["attributes"]
350
+ if "casDataType" in col_attributes:
351
+ datatype = col_attributes["casDataType"]
352
+ else:
353
+ datatype = col_attributes["dataType"]
354
+ if datatype == "num":
355
+ datatype = "numeric"
356
+ parsed_string = ColumnTypeParser._parse_datatype_string(datatype)
357
+ col_name = entity["name"]
358
+ parsed_string["name"] = col_name.replace('"', "'")
359
+ parsed_string["ordinalPosition"] = col_attributes["ordinalPosition"]
360
+ # Column profile to be added
361
+ attr_map = {
362
+ "mean": "mean",
363
+ "median": "sum",
364
+ "min": "min",
365
+ "max": "max",
366
+ "standardDeviation": "stddev",
367
+ "missingCount": "nullCount",
368
+ "completenessPercent": "valuesPercentage",
369
+ "uniquenessPercent": "uniqueProportion",
370
+ "cardinalityCount": "distinctCount",
371
+ "skewness": "nonParametricSkew",
372
+ "quantiles25": "firstQuartile",
373
+ "quantiles50": "median",
374
+ "quantiles75": "thirdQuartile",
375
+ "mismatchedCount": "missingCount",
376
+ "charsMinCount": "minLength",
377
+ "charsMaxCount": "maxLength",
378
+ }
379
+ col_profile_dict = {}
380
+ for attr, mapped_attr in attr_map.items():
381
+ if attr in col_attributes:
382
+ if attr == "uniquenessPercent":
383
+ col_profile_dict[mapped_attr] = col_attributes[attr] / 100
384
+ else:
385
+ col_profile_dict[mapped_attr] = col_attributes[attr]
386
+ if "rowCount" in table_entity_instance["attributes"]:
387
+ col_profile_dict["valuesCount"] = table_entity_instance["attributes"][
388
+ "rowCount"
389
+ ]
390
+ if "valuesCount" in col_profile_dict:
391
+ if "distinctCount" in col_profile_dict:
392
+ col_profile_dict["distinctProportion"] = (
393
+ col_profile_dict["distinctCount"]
394
+ / col_profile_dict["valuesCount"]
395
+ )
396
+ col_profile_dict["uniqueCount"] = col_profile_dict["distinctCount"]
397
+ if "nullCount" in col_profile_dict:
398
+ col_profile_dict["nullProportion"] = (
399
+ col_profile_dict["nullCount"] / col_profile_dict["valuesCount"]
400
+ )
401
+ if "missingCount" in col_profile_dict:
402
+ col_profile_dict["missingPercentage"] = (
403
+ col_profile_dict["missingCount"]
404
+ / col_profile_dict["valuesCount"]
405
+ )
406
+ col_profile_dict["validCount"] = (
407
+ col_profile_dict["valuesCount"]
408
+ - col_profile_dict["missingCount"]
409
+ )
410
+ timestamp = time.time() - 100000
411
+ col_profile_dict["timestamp"] = timestamp
412
+ col_profile_dict["name"] = parsed_string["name"]
413
+ column_profile = ColumnProfile(**col_profile_dict)
414
+ col_profile_list.append(column_profile)
415
+ parsed_string["profile"] = column_profile
416
+ if datatype.lower() in ["char", "varchar", "binary", "varbinary"]:
417
+ if "charsMaxCount" in col_attributes:
418
+ parsed_string["dataLength"] = col_attributes["charsMaxCount"]
419
+ else:
420
+ parsed_string["dataLength"] = 0
421
+ logger.info(f"This is parsed string: {parsed_string}")
422
+ col = Column(**parsed_string)
423
+ columns.append(col)
424
+ return columns, col_profile_list
425
+
426
+ def create_table_entity(self, table) -> Iterable[Either[CreateTableRequest]]:
427
+ # pylint: disable=global-variable-undefined
428
+ """
429
+ Create database + db service & Create database schema
430
+ """
431
+ logger.info(f"Ingesting table: {table}")
432
+ global table_entity
433
+ global table_fqn
434
+
435
+ table_entity, table_fqn = None, None
436
+
437
+ try:
438
+ table_url = self.sas_client.get_information_catalog_link(table["id"])
439
+ col_entity_instances, table_entity_instance = self.get_entities_using_view(
440
+ table["id"]
441
+ )
442
+ logger.info(f"table entity: {table_entity_instance}")
443
+
444
+ if not table_entity_instance:
445
+ return
446
+
447
+ table_name = table_entity_instance["name"]
448
+ table_extension = table_entity_instance["attributes"]
449
+
450
+ # create tables in database
451
+ database_schema = self.create_database_schema(table_entity_instance)
452
+
453
+ # find the table entity to see if it already exists
454
+ table_fqn = self.get_table_fqn(table_name)
455
+ table_entity = self.metadata.get_by_name(
456
+ entity=Table, fqn=table_fqn, fields=["extension"]
457
+ )
458
+
459
+ logger.debug(table_entity)
460
+
461
+ # if the table entity already exists, we don't need to create it again
462
+ # only update it when either the sourceUrl or analysisTimeStamp changed
463
+ if not table_entity or (
464
+ table_url != table_entity.sourceUrl.__root__
465
+ or table_entity.extension.__root__.get("analysisTimeStamp")
466
+ != table_extension.get("analysisTimeStamp")
467
+ ):
468
+ # create the columns of the table
469
+ columns, col_profile_list = self.create_columns_and_profiles(
470
+ col_entity_instances, table_entity_instance
471
+ )
472
+
473
+ # set description based on col counts
474
+ if len(columns) == 0:
475
+ table_description = (
476
+ "Table has not been analyzed. "
477
+ f'Head over to <a target="_blank" href="{table_url}">'
478
+ f"SAS Information Catalog</a> to analyze the table."
479
+ )
480
+ try:
481
+ # Create columns alternatively
482
+ table_resource = self.sas_client.get_resource(
483
+ table_entity_instance["resourceId"][1:]
484
+ )
485
+ columns = self.create_columns_alt(table_resource)
486
+ except HTTPError as http_err:
487
+ table_description = f"{str(http_err)} This table does not exist in the file path"
488
+ else:
489
+ table_description = (
490
+ f"Last analyzed: <b>{table_extension.get('analysisTimeStamp')}</b>. "
491
+ f'Visit <a target="_blank" href="{table_url}">SAS Information Catalog</a>'
492
+ f" for more information."
493
+ )
494
+
495
+ # build table extension attr
496
+ for attr in table_extension:
497
+ if isinstance(table_extension[attr], bool):
498
+ table_extension[attr] = str(table_extension[attr])
499
+
500
+ custom_attributes = [
501
+ custom_attribute["name"] for custom_attribute in TABLE_CUSTOM_ATTR
502
+ ]
503
+ extension_attributes = {
504
+ attr: value
505
+ for attr, value in table_extension.items()
506
+ if attr in custom_attributes
507
+ }
508
+
509
+ table_request = CreateTableRequest(
510
+ name=table_name,
511
+ sourceUrl=table_url,
512
+ description=table_description,
513
+ columns=columns,
514
+ databaseSchema=database_schema.fullyQualifiedName,
515
+ extension=extension_attributes,
516
+ )
517
+
518
+ yield Either(right=table_request)
519
+
520
+ # find the table entity to see if it already exists
521
+ yield from self.create_lineage_table_source(table_extension, table_name)
522
+
523
+ table_entity = self.metadata.get_by_name(
524
+ entity=Table, fqn=self.get_table_fqn(table_name)
525
+ )
526
+ # update the description
527
+ logger.debug(
528
+ f"Updating description for {table_entity.id.__root__} with {table_description}"
529
+ )
530
+ self.metadata.client.patch(
531
+ path=f"/tables/{table_entity.id.__root__}",
532
+ data=json.dumps(
533
+ [
534
+ {
535
+ "op": "add",
536
+ "path": "/description",
537
+ "value": table_description,
538
+ }
539
+ ]
540
+ ),
541
+ )
542
+
543
+ # update the custom properties
544
+ logger.debug(
545
+ f"Updating custom properties for {table_entity.id.__root__} with {extension_attributes}"
546
+ )
547
+ self.metadata.client.patch(
548
+ path=f"/tables/{table_entity.id.__root__}",
549
+ data=json.dumps(
550
+ [
551
+ {
552
+ "op": "add",
553
+ "path": "/extension",
554
+ "value": extension_attributes,
555
+ }
556
+ ]
557
+ ),
558
+ )
559
+
560
+ # quit updating table profile if table doesn't exist
561
+ if (
562
+ table_description
563
+ and "This table does not exist in the file path"
564
+ in table_description
565
+ ):
566
+ return
567
+
568
+ # update table profile
569
+ table_profile_dict = {
570
+ "timestamp": time.time() - 100000,
571
+ "createDateTime": table_entity_instance["creationTimeStamp"],
572
+ "rowCount": (
573
+ 0
574
+ if "rowCount" not in table_extension
575
+ else table_extension["rowCount"]
576
+ ),
577
+ "columnCount": (
578
+ 0
579
+ if "columnCount" not in table_extension
580
+ else table_extension["columnCount"]
581
+ ),
582
+ "sizeInByte": (
583
+ 0
584
+ if "dataSize" not in extension_attributes
585
+ else table_extension["dataSize"]
586
+ ),
587
+ }
588
+
589
+ # create Profiles & Data Quality Column
590
+ table_profile_request = CreateTableProfileRequest(
591
+ tableProfile=TableProfile(**table_profile_dict),
592
+ columnProfile=col_profile_list,
593
+ )
594
+ self.metadata.client.put(
595
+ path=f"{self.metadata.get_suffix(Table)}/{table_entity.id.__root__}/tableProfile",
596
+ data=table_profile_request.json(),
597
+ )
598
+
599
+ except Exception as exc:
600
+ logger.error(f"table failed to create: {table}")
601
+ yield Either(
602
+ left=StackTraceError(
603
+ name=table_name,
604
+ error=f"Unexpected exception to create table [{table_name}]: {exc}",
605
+ stack_trace=traceback.format_exc(),
606
+ )
607
+ )
608
+ finally:
609
+ if table_entity:
610
+ self.table_fqns.append(table_fqn)
611
+
612
+ def create_lineage_table_source(self, table_extension, table_name):
613
+ """
614
+ create lineage between the table and its source
615
+ """
616
+ if "sourceName" in table_extension and table_extension["sourceName"] != "":
617
+ source_name = table_extension["sourceName"]
618
+ # see if the source table already exists
619
+ source_table_fqn = self.get_table_fqn(source_name)
620
+ logger.debug(f"source_table_fqn for sourceTable is {source_table_fqn}")
621
+ source_table_entity = self.metadata.get_by_name(
622
+ entity=Table, fqn=source_table_fqn
623
+ )
624
+ target_table_entity = self.metadata.get_by_name(
625
+ entity=Table, fqn=self.get_table_fqn(table_name)
626
+ )
627
+
628
+ # process to create lineage if source table doesn't exist
629
+ if not source_table_entity:
630
+ sanitized_source_name = re.sub("[@!#$%^&*]", "", source_name)
631
+ param = f"filter=contains(name, '{sanitized_source_name}')"
632
+ get_instances_with_param = self.sas_client.get_instances_with_param(
633
+ param
634
+ )
635
+ if get_instances_with_param and len(get_instances_with_param) == 1:
636
+ source_table = get_instances_with_param[0]
637
+ yield from self.create_table_entity(source_table)
638
+
639
+ source_table_entity = self.metadata.get_by_name(
640
+ entity=Table, fqn=source_table_fqn
641
+ )
642
+
643
+ if source_table_entity:
644
+ yield from self.create_table_lineage(
645
+ source_table_entity, target_table_entity
646
+ )
647
+
648
+ def add_table_custom_attributes(self):
649
+ """
650
+ Adding custom attribute from extension_attr.py
651
+ """
652
+ string_type = self.metadata.client.get(path="/metadata/types/name/string")["id"]
653
+ integer_type = self.metadata.client.get(path="/metadata/types/name/integer")[
654
+ "id"
655
+ ]
656
+ for attr in TABLE_CUSTOM_ATTR:
657
+ if attr["propertyType"]["id"] == "STRING_TYPE":
658
+ attr["propertyType"]["id"] = string_type
659
+ else:
660
+ attr["propertyType"]["id"] = integer_type
661
+ table_type = self.metadata.client.get(path="/metadata/types/name/table")
662
+ table_id = table_type["id"]
663
+ for attr in TABLE_CUSTOM_ATTR:
664
+ self.metadata.client.put(
665
+ path=f"/metadata/types/{table_id}", data=json.dumps(attr)
666
+ )
667
+
668
+ def create_table_lineage(self, from_entity, to_entity):
669
+ yield self.create_lineage_request("table", "table", from_entity, to_entity)
670
+
671
+ def create_dashboard_service(self, dashboard_service_name):
672
+ self.dashboard_service_name = dashboard_service_name
673
+
674
+ try:
675
+ dashboard_service_request = CreateDashboardServiceRequest(
676
+ name=dashboard_service_name,
677
+ serviceType=DashboardServiceType.CustomDashboard,
678
+ connection=DashboardConnection(
679
+ config=CustomDashboardConnection(
680
+ type=CustomDashboardType.CustomDashboard,
681
+ sourcePythonClass="metadata.ingestion.source.database.customdatabase.metadata.SASDB",
682
+ )
683
+ ),
684
+ )
685
+ yield Either(right=dashboard_service_request)
686
+ except Exception as exc:
687
+ yield Either(
688
+ left=StackTraceError(
689
+ name=dashboard_service_name,
690
+ error=f"Unexpected exception to create dashboard service for [{dashboard_service_name}]: {exc}",
691
+ stack_trace=traceback.format_exc(),
692
+ )
693
+ )
694
+
695
+ def get_report_tables(self, report_id):
696
+ """
697
+ Get datasets related to the report
698
+ """
699
+ report_tables = self.sas_client.get_report_relationship(report_id)
700
+ table_instances = []
701
+ self.report_description = []
702
+ # loop through each relatedResourceUri from relationships
703
+ for table in report_tables:
704
+ table_uri = table["relatedResourceUri"][1:]
705
+ try:
706
+ # load the table if it can be found
707
+ table_resource = self.sas_client.get_resource(table_uri)
708
+ table_data_resource = table_resource["tableReference"]["tableUri"]
709
+ param = f"filter=eq(resourceId,'{table_data_resource}')"
710
+ if "state" in table_resource and table_resource["state"] == "unloaded":
711
+ self.sas_client.load_table(table_uri + "/state?value=loaded")
712
+
713
+ except HTTPError as exc:
714
+ # append http error to table description if it can't be found
715
+ logger.error(f"table_uri: {table_uri}")
716
+ self.report_description.append(str(exc))
717
+ name_index = table_uri.rindex("/")
718
+ table_name = table_uri[name_index + 1 :]
719
+ param = f"filter=eq(name,'{table_name}')"
720
+
721
+ get_instances_with_param = self.sas_client.get_instances_with_param(param)
722
+ if get_instances_with_param and len(get_instances_with_param) == 1:
723
+ table_instance = get_instances_with_param[0]
724
+ table_instances.append(table_instance)
725
+ return table_instances
726
+
727
+ def create_lineage_request(self, from_type, in_type, from_entity, to_entity):
728
+ return Either(
729
+ right=AddLineageRequest(
730
+ edge=EntitiesEdge(
731
+ fromEntity=EntityReference(
732
+ id=from_entity.id.__root__, type=from_type
733
+ ),
734
+ toEntity=EntityReference(id=to_entity.id.__root__, type=in_type),
735
+ )
736
+ )
737
+ )
738
+
739
+ def create_report_entity(self, report):
740
+ """
741
+ Create report entity and its corresponding lineage to the datasets
742
+ """
743
+ report_id = report["id"]
744
+ report_name = report["name"]
745
+ try:
746
+ report_resource = report["resourceId"]
747
+ report_url = self.sas_client.get_report_link("report", report_resource)
748
+ self.report_description = (
749
+ str(self.report_description) if self.report_description else None
750
+ )
751
+ report_request = CreateDashboardRequest(
752
+ name=report_id,
753
+ displayName=report_name,
754
+ sourceUrl=report_url,
755
+ charts=self.chart_names,
756
+ service=self.dashboard_service_name,
757
+ description=self.report_description,
758
+ )
759
+ yield Either(right=report_request)
760
+
761
+ dashboard_fqn = fqn.build(
762
+ self.metadata,
763
+ entity_type=Dashboard,
764
+ service_name=self.dashboard_service_name,
765
+ dashboard_name=report_id,
766
+ )
767
+
768
+ dashboard_entity = self.metadata.get_by_name(
769
+ entity=Dashboard, fqn=dashboard_fqn
770
+ )
771
+ table_entities = []
772
+ for table in self.table_fqns:
773
+ entity_instance = self.metadata.get_by_name(entity=Table, fqn=table)
774
+ table_entities.append(entity_instance)
775
+ for entity in table_entities:
776
+ yield self.create_lineage_request(
777
+ "table", "dashboard", entity, dashboard_entity
778
+ )
779
+ except Exception as exc:
780
+ logger.error(f"report failed to create: {report}")
781
+ yield Either(
782
+ left=StackTraceError(
783
+ name=report_name,
784
+ error=f"Unexpected exception to create report [{report['id']}]: {exc}",
785
+ stack_trace=traceback.format_exc(),
786
+ )
787
+ )
788
+
789
+ def create_data_flow_entity(self, data_flow, input_fqns, output_fqns):
790
+ """
791
+ Create data flow and its corresponding lineage with the input & output table
792
+ """
793
+ data_flow_id = data_flow["id"]
794
+ data_flow_resource = data_flow["resourceId"]
795
+
796
+ try:
797
+ data_flow_url = self.sas_client.get_report_link(
798
+ "dataFlow", data_flow_resource
799
+ )
800
+ data_flow_request = CreateDashboardRequest(
801
+ name=data_flow_id,
802
+ displayName=data_flow["name"],
803
+ service=self.dashboard_service_name,
804
+ sourceUrl=data_flow_url,
805
+ )
806
+ yield Either(right=data_flow_request)
807
+
808
+ dashboard_fqn = fqn.build(
809
+ self.metadata,
810
+ entity_type=Dashboard,
811
+ service_name=self.dashboard_service_name,
812
+ dashboard_name=data_flow_id,
813
+ )
814
+
815
+ dashboard_entity = self.metadata.get_by_name(
816
+ entity=Dashboard, fqn=dashboard_fqn
817
+ )
818
+
819
+ input_entities = [
820
+ self.metadata.get_by_name(entity=Table, fqn=input_entity)
821
+ for input_entity in input_fqns
822
+ ]
823
+ output_entities = [
824
+ self.metadata.get_by_name(entity=Table, fqn=output_entity)
825
+ for output_entity in output_fqns
826
+ ]
827
+
828
+ for entity in input_entities:
829
+ yield self.create_lineage_request(
830
+ "table", "dashboard", entity, dashboard_entity
831
+ )
832
+ for entity in output_entities:
833
+ yield self.create_lineage_request(
834
+ "dashboard", "table", dashboard_entity, entity
835
+ )
836
+ except Exception as exc:
837
+ logger.error(f"dataflow failed to create: {data_flow}")
838
+ yield Either(
839
+ left=StackTraceError(
840
+ name=data_flow_id,
841
+ error=f"Unexpected exception to create data flow [{data_flow_id}]: {exc}",
842
+ stack_trace=traceback.format_exc(),
843
+ )
844
+ )
845
+
846
+ def get_database_names(self) -> Iterable[str]:
847
+ for database in self.databases:
848
+ yield database
849
+
850
+ def yield_database(
851
+ self, database_name: str
852
+ ) -> Iterable[Either[CreateDatabaseRequest]]:
853
+ yield Either(
854
+ right=CreateDatabaseRequest(
855
+ name=database_name,
856
+ service=self.context.database_service,
857
+ )
858
+ )
859
+
860
+ def get_database_schema_names(self) -> Iterable[Tuple[str, str]]:
861
+ for database, database_schemas in self.database_schemas.items():
862
+ for database_schema in database_schemas:
863
+ yield database, database_schema
864
+
865
+ def yield_database_schema(
866
+ self, schema_name: Tuple[str, str]
867
+ ) -> Iterable[Either[CreateDatabaseSchemaRequest]]:
868
+ yield Either(
869
+ right=CreateDatabaseSchemaRequest(
870
+ name=schema_name[1],
871
+ database=fqn.build(
872
+ metadata=self.metadata,
873
+ entity_type=Database,
874
+ service_name=self.context.database_service,
875
+ database_name=schema_name[0],
876
+ ),
877
+ )
878
+ )
879
+
880
+ def yield_tag(
881
+ self, schema_name: str
882
+ ) -> Iterable[Either[OMetaTagAndClassification]]:
883
+ """No tags to send"""
884
+
885
+ def yield_view_lineage(self) -> Iterable[Either[AddLineageRequest]]:
886
+ yield from []
887
+
888
+ def get_tables_name_and_type(self) -> Optional[Iterable[Tuple[str, list]]]:
889
+ """Not implemented"""
890
+
891
+ def yield_table(
892
+ self, table_name_and_type: Tuple[str, list]
893
+ ) -> Iterable[Either[Entity]]:
894
+ """Not implemented"""
895
+
896
+ def get_stored_procedures(self) -> Iterable[Any]:
897
+ """Not implemented"""
898
+
899
+ def yield_stored_procedure(
900
+ self, stored_procedure: Any
901
+ ) -> Iterable[Either[CreateStoredProcedureRequest]]:
902
+ """Not implemented"""
903
+
904
+ def yield_procedure_lineage_and_queries(
905
+ self,
906
+ ) -> Iterable[Either[Union[AddLineageRequest, CreateQueryRequest]]]:
907
+ yield from []
908
+
909
+ def close(self) -> None:
910
+ pass
911
+
912
+ def test_connection(self) -> None:
913
+ test_connection_fn = get_test_connection_fn(self.service_connection)
914
+ test_connection_fn(self.metadata, self.connection_obj, self.service_connection)