databao-context-engine 0.1.6__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/PKG-INFO +1 -1
  2. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/pyproject.toml +1 -1
  3. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/__init__.py +7 -1
  4. databao_context_engine-0.1.7/src/databao_context_engine/cli/info.py +36 -0
  5. databao_context_engine-0.1.7/src/databao_context_engine/plugins/dbt/dbt_context_extractor.py +212 -0
  6. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/dbt/types.py +29 -0
  7. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/dbt/types_artifacts.py +24 -5
  8. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/info.py +14 -9
  9. databao_context_engine-0.1.6/src/databao_context_engine/cli/info.py +0 -33
  10. databao_context_engine-0.1.6/src/databao_context_engine/plugins/dbt/dbt_context_extractor.py +0 -106
  11. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/README.md +0 -0
  12. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/__init__.py +0 -0
  13. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/build_runner.py +0 -0
  14. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/build_service.py +0 -0
  15. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/build_wiring.py +0 -0
  16. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/export_results.py +0 -0
  17. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/build_sources/plugin_execution.py +0 -0
  18. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/cli/__init__.py +0 -0
  19. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/cli/add_datasource_config.py +0 -0
  20. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/cli/commands.py +0 -0
  21. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/cli/datasources.py +0 -0
  22. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/config/__init__.py +0 -0
  23. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/config/log_config.yaml +0 -0
  24. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/config/logging.py +0 -0
  25. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/databao_context_engine.py +0 -0
  26. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/databao_context_project_manager.py +0 -0
  27. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/datasources/__init__.py +0 -0
  28. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/datasources/check_config.py +0 -0
  29. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/datasources/datasource_context.py +0 -0
  30. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/datasources/datasource_discovery.py +0 -0
  31. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/datasources/types.py +0 -0
  32. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/event_journal/__init__.py +0 -0
  33. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/event_journal/writer.py +0 -0
  34. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/generate_configs_schemas.py +0 -0
  35. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/init_project.py +0 -0
  36. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/introspection/__init__.py +0 -0
  37. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/introspection/property_extract.py +0 -0
  38. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/__init__.py +0 -0
  39. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/api.py +0 -0
  40. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/config.py +0 -0
  41. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/descriptions/__init__.py +0 -0
  42. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/descriptions/ollama.py +0 -0
  43. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/descriptions/provider.py +0 -0
  44. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/embeddings/__init__.py +0 -0
  45. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/embeddings/ollama.py +0 -0
  46. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/embeddings/provider.py +0 -0
  47. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/errors.py +0 -0
  48. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/factory.py +0 -0
  49. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/install.py +0 -0
  50. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/runtime.py +0 -0
  51. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/llm/service.py +0 -0
  52. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/main.py +0 -0
  53. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/mcp/__init__.py +0 -0
  54. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/mcp/mcp_runner.py +0 -0
  55. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/mcp/mcp_server.py +0 -0
  56. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugin_loader.py +0 -0
  57. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/pluginlib/__init__.py +0 -0
  58. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/pluginlib/build_plugin.py +0 -0
  59. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/pluginlib/config.py +0 -0
  60. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/pluginlib/plugin_utils.py +0 -0
  61. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/__init__.py +0 -0
  62. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/__init__.py +0 -0
  63. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/athena/__init__.py +0 -0
  64. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/athena/athena_db_plugin.py +0 -0
  65. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/athena/athena_introspector.py +0 -0
  66. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/base_db_plugin.py +0 -0
  67. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/base_introspector.py +0 -0
  68. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/clickhouse/__init__.py +0 -0
  69. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/clickhouse/clickhouse_db_plugin.py +0 -0
  70. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/clickhouse/clickhouse_introspector.py +0 -0
  71. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/database_chunker.py +0 -0
  72. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/databases_types.py +0 -0
  73. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/duckdb/__init__.py +0 -0
  74. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/duckdb/duckdb_db_plugin.py +0 -0
  75. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/duckdb/duckdb_introspector.py +0 -0
  76. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/introspection_model_builder.py +0 -0
  77. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/introspection_scope.py +0 -0
  78. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/introspection_scope_matcher.py +0 -0
  79. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mssql/__init__.py +0 -0
  80. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mssql/mssql_db_plugin.py +0 -0
  81. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mssql/mssql_introspector.py +0 -0
  82. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mysql/__init__.py +0 -0
  83. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mysql/mysql_db_plugin.py +0 -0
  84. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/mysql/mysql_introspector.py +0 -0
  85. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/postgresql/__init__.py +0 -0
  86. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/postgresql/postgresql_db_plugin.py +0 -0
  87. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/postgresql/postgresql_introspector.py +0 -0
  88. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/snowflake/__init__.py +0 -0
  89. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/snowflake/snowflake_db_plugin.py +0 -0
  90. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/snowflake/snowflake_introspector.py +0 -0
  91. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/sqlite/__init__.py +0 -0
  92. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/sqlite/sqlite_db_plugin.py +0 -0
  93. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/databases/sqlite/sqlite_introspector.py +0 -0
  94. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/dbt/__init__.py +0 -0
  95. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/dbt/dbt_chunker.py +0 -0
  96. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/dbt/dbt_plugin.py +0 -0
  97. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/duckdb_tools.py +0 -0
  98. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/files/__init__.py +0 -0
  99. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/files/unstructured_files_plugin.py +0 -0
  100. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/plugin_loader.py +0 -0
  101. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/resources/__init__.py +0 -0
  102. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/resources/parquet_chunker.py +0 -0
  103. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/resources/parquet_introspector.py +0 -0
  104. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/plugins/resources/parquet_plugin.py +0 -0
  105. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/__init__.py +0 -0
  106. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/init_project.py +0 -0
  107. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/layout.py +0 -0
  108. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/project_config.py +0 -0
  109. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/resources/examples/src/databases/example_postgres.yaml +0 -0
  110. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/resources/examples/src/files/documentation.md +0 -0
  111. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/project/resources/examples/src/files/notes.txt +0 -0
  112. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/retrieve_embeddings/__init__.py +0 -0
  113. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/retrieve_embeddings/retrieve_runner.py +0 -0
  114. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/retrieve_embeddings/retrieve_service.py +0 -0
  115. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/retrieve_embeddings/retrieve_wiring.py +0 -0
  116. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/serialization/__init__.py +0 -0
  117. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/serialization/yaml.py +0 -0
  118. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/__init__.py +0 -0
  119. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/chunk_embedding_service.py +0 -0
  120. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/embedding_shard_resolver.py +0 -0
  121. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/factories.py +0 -0
  122. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/models.py +0 -0
  123. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/persistence_service.py +0 -0
  124. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/services/table_name_policy.py +0 -0
  125. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/__init__.py +0 -0
  126. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/connection.py +0 -0
  127. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/exceptions/__init__.py +0 -0
  128. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/exceptions/exceptions.py +0 -0
  129. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/migrate.py +0 -0
  130. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/migrations/V01__init.sql +0 -0
  131. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/models.py +0 -0
  132. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/__init__.py +0 -0
  133. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/chunk_repository.py +0 -0
  134. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/embedding_model_registry_repository.py +0 -0
  135. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/embedding_repository.py +0 -0
  136. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/factories.py +0 -0
  137. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/repositories/vector_search_repository.py +0 -0
  138. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/storage/transaction.py +0 -0
  139. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/system/__init__.py +0 -0
  140. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/system/properties.py +0 -0
  141. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/templating/__init__.py +0 -0
  142. {databao_context_engine-0.1.6 → databao_context_engine-0.1.7}/src/databao_context_engine/templating/renderer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: databao-context-engine
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Semantic context for your LLMs — generated automatically
5
5
  Requires-Dist: click>=8.3.0
6
6
  Requires-Dist: duckdb>=1.4.3
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "databao-context-engine"
3
- version = "0.1.6"
3
+ version = "0.1.7"
4
4
  description = "Semantic context for your LLMs — generated automatically"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -23,7 +23,12 @@ from databao_context_engine.pluginlib.build_plugin import (
23
23
  DatasourceType,
24
24
  )
25
25
  from databao_context_engine.pluginlib.config import ConfigPropertyDefinition
26
- from databao_context_engine.project.info import DceInfo, DceProjectInfo, get_databao_context_engine_info
26
+ from databao_context_engine.project.info import (
27
+ DceInfo,
28
+ DceProjectInfo,
29
+ get_databao_context_engine_info,
30
+ get_databao_context_engine_project_info,
31
+ )
27
32
  from databao_context_engine.project.init_project import InitErrorReason, InitProjectError
28
33
  from databao_context_engine.services.chunk_embedding_service import ChunkEmbeddingMode
29
34
 
@@ -41,6 +46,7 @@ __all__ = [
41
46
  "DatasourceConfigFile",
42
47
  "DatasourceType",
43
48
  "get_databao_context_engine_info",
49
+ "get_databao_context_engine_project_info",
44
50
  "DceInfo",
45
51
  "DceProjectInfo",
46
52
  "init_dce_project",
@@ -0,0 +1,36 @@
1
+ import os
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ import click
6
+
7
+ from databao_context_engine import DceInfo, DceProjectInfo, get_databao_context_engine_info
8
+ from databao_context_engine.project.info import get_databao_context_engine_project_info
9
+
10
+
11
+ def echo_info(project_dir: Path) -> None:
12
+ dce_info = get_databao_context_engine_info()
13
+ dce_project_info = get_databao_context_engine_project_info(project_dir=project_dir)
14
+ click.echo(_generate_info_string(dce_info, dce_project_info))
15
+
16
+
17
+ def _generate_info_string(dce_info: DceInfo, project_info: DceProjectInfo) -> str:
18
+ info_lines = []
19
+ info_lines.append(f"Databao context engine version: {dce_info.version}")
20
+ info_lines.append(f"Databao context engine storage dir: {dce_info.dce_path}")
21
+ info_lines.append(f"Databao context engine plugins: {dce_info.plugin_ids}")
22
+
23
+ info_lines.append("")
24
+
25
+ info_lines.append(f"OS name: {sys.platform}")
26
+ info_lines.append(f"OS architecture: {os.uname().machine if hasattr(os, 'uname') else 'unknown'}")
27
+
28
+ info_lines.append("")
29
+
30
+ if project_info.is_initialized:
31
+ info_lines.append(f"Project dir: {project_info.project_path.resolve()}")
32
+ info_lines.append(f"Project ID: {str(project_info.project_id)}")
33
+ else:
34
+ info_lines.append(f"Project not initialized at {project_info.project_path.resolve()}")
35
+
36
+ return os.linesep.join(info_lines)
@@ -0,0 +1,212 @@
1
+ import re
2
+ from collections import defaultdict
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ from databao_context_engine.plugins.dbt.types import (
7
+ DbtAcceptedValuesConstraint,
8
+ DbtColumn,
9
+ DbtConfigFile,
10
+ DbtConstraint,
11
+ DbtContext,
12
+ DbtMaterialization,
13
+ DbtModel,
14
+ DbtRelationshipConstraint,
15
+ DbtSimpleConstraint,
16
+ )
17
+ from databao_context_engine.plugins.dbt.types_artifacts import (
18
+ DbtArtifacts,
19
+ DbtCatalog,
20
+ DbtCatalogColumn,
21
+ DbtCatalogNode,
22
+ DbtManifest,
23
+ DbtManifestColumn,
24
+ DbtManifestModel,
25
+ DbtManifestTest,
26
+ )
27
+
28
+
29
+ def check_connection(config_file: DbtConfigFile) -> None:
30
+ _read_dbt_artifacts(config_file.dbt_target_folder_path.expanduser())
31
+
32
+
33
+ def extract_context(config_file: DbtConfigFile) -> DbtContext:
34
+ artifacts = _read_dbt_artifacts(config_file.dbt_target_folder_path.expanduser())
35
+
36
+ return _extract_context_from_artifacts(artifacts)
37
+
38
+
39
+ def _read_dbt_artifacts(dbt_target_folder_path: Path) -> DbtArtifacts:
40
+ if not dbt_target_folder_path.is_dir():
41
+ raise ValueError(f'Invalid "dbt_target_folder_path": not a directory ({dbt_target_folder_path})')
42
+
43
+ # TODO: Check the manifest schema version?
44
+ manifest_file = dbt_target_folder_path.joinpath("manifest.json")
45
+ if not manifest_file.is_file():
46
+ raise ValueError(f'Invalid "dbt_target_folder_path": missing manifest.json file ({manifest_file})')
47
+
48
+ manifest = DbtManifest.model_validate_json(manifest_file.read_text())
49
+
50
+ catalog_file = dbt_target_folder_path.joinpath("catalog.json")
51
+ catalog = DbtCatalog.model_validate_json(catalog_file.read_text()) if catalog_file.is_file() else None
52
+
53
+ return DbtArtifacts(manifest=manifest, catalog=catalog)
54
+
55
+
56
+ def _extract_context_from_artifacts(artifacts: DbtArtifacts) -> DbtContext:
57
+ manifest_models = [
58
+ manifest_node
59
+ for manifest_node in artifacts.manifest.nodes.values()
60
+ if isinstance(manifest_node, DbtManifestModel)
61
+ ]
62
+
63
+ manifest_tests_by_model_and_column = _get_manifest_tests(artifacts.manifest)
64
+
65
+ catalog_nodes = artifacts.catalog.nodes if artifacts.catalog else {}
66
+
67
+ # TODO: Extract the stages? Or at least the "highest-level" models (= marts?)
68
+ # TODO: Organize the models by schemas? Or by stages?
69
+ return DbtContext(
70
+ models=[
71
+ _manifest_model_to_dbt_model(
72
+ manifest_model,
73
+ catalog_nodes.get(manifest_model.unique_id, None),
74
+ manifest_tests_by_model_and_column.get(manifest_model.unique_id, {}),
75
+ )
76
+ for manifest_model in manifest_models
77
+ ],
78
+ )
79
+
80
+
81
+ def _get_manifest_tests(manifest: DbtManifest) -> dict[Any, dict[Any, list]]:
82
+ """Extract all tests nodes in the manifest and groups them by model and column."""
83
+ manifest_tests_by_model_and_column: dict[str, dict[str, list[DbtManifestTest]]] = defaultdict(
84
+ lambda: defaultdict(list)
85
+ )
86
+ for manifest_node in manifest.nodes.values():
87
+ if isinstance(manifest_node, DbtManifestTest) and manifest_node.attached_node and manifest_node.column_name:
88
+ manifest_tests_by_model_and_column[manifest_node.attached_node][manifest_node.column_name].append(
89
+ manifest_node
90
+ )
91
+ return manifest_tests_by_model_and_column
92
+
93
+
94
+ def _manifest_model_to_dbt_model(
95
+ manifest_model: DbtManifestModel,
96
+ catalog_node: DbtCatalogNode | None,
97
+ test_nodes_by_column_name: dict[str, list[DbtManifestTest]],
98
+ ) -> DbtModel:
99
+ catalog_columns = catalog_node.columns if catalog_node else {}
100
+
101
+ return DbtModel(
102
+ id=manifest_model.unique_id,
103
+ name=manifest_model.name,
104
+ database=manifest_model.database,
105
+ schema=manifest_model.schema_,
106
+ description=manifest_model.description,
107
+ columns=[
108
+ _manifest_column_to_dbt_column(
109
+ manifest_column,
110
+ catalog_columns.get(manifest_column.name),
111
+ test_nodes_by_column_name.get(manifest_column.name, []),
112
+ )
113
+ for manifest_column in manifest_model.columns.values()
114
+ ],
115
+ materialization=_manifest_materialization_to_dbt_materializaton(
116
+ manifest_model.config.materialized if manifest_model.config else None
117
+ ),
118
+ primary_key=manifest_model.primary_key,
119
+ depends_on_nodes=manifest_model.depends_on.get("nodes", []) if manifest_model.depends_on else [],
120
+ )
121
+
122
+
123
+ def _manifest_column_to_dbt_column(
124
+ manifest_column: DbtManifestColumn, catalog_column: DbtCatalogColumn | None, test_nodes: list[DbtManifestTest]
125
+ ) -> DbtColumn:
126
+ constraints = _manifest_test_to_dbt_constraint(test_nodes)
127
+
128
+ return DbtColumn(
129
+ name=manifest_column.name,
130
+ description=manifest_column.description,
131
+ type=catalog_column.type if catalog_column else manifest_column.data_type,
132
+ constraints=constraints,
133
+ )
134
+
135
+
136
+ def _manifest_test_to_dbt_constraint(test_nodes: list[DbtManifestTest]) -> list[DbtConstraint]:
137
+ result: list[DbtConstraint] = []
138
+
139
+ for test_node in test_nodes:
140
+ is_enforced = test_node.config.severity == "ERROR" if test_node.config else False
141
+
142
+ if test_node.test_metadata is None:
143
+ continue
144
+
145
+ match test_node.test_metadata.name:
146
+ case "not_null":
147
+ result.append(
148
+ DbtSimpleConstraint(type="not_null", is_enforced=is_enforced, description=test_node.description)
149
+ )
150
+ case "unique":
151
+ result.append(
152
+ DbtSimpleConstraint(type="unique", is_enforced=is_enforced, description=test_node.description)
153
+ )
154
+ case "accepted_values":
155
+ if test_node.test_metadata.kwargs is None:
156
+ continue
157
+
158
+ accepted_values = test_node.test_metadata.kwargs.get("values", None)
159
+ if accepted_values is None:
160
+ continue
161
+ result.append(
162
+ DbtAcceptedValuesConstraint(
163
+ type="accepted_values",
164
+ is_enforced=is_enforced,
165
+ description=test_node.description,
166
+ accepted_values=accepted_values,
167
+ )
168
+ )
169
+ case "relationships":
170
+ if test_node.test_metadata.kwargs is None:
171
+ continue
172
+
173
+ target_model = _extract_ref_model(test_node.test_metadata.kwargs.get("to", None))
174
+ if target_model is None:
175
+ continue
176
+ target_column = test_node.test_metadata.kwargs.get("field", None)
177
+ if target_column is None:
178
+ continue
179
+ result.append(
180
+ DbtRelationshipConstraint(
181
+ type="relationships",
182
+ is_enforced=is_enforced,
183
+ description=test_node.description,
184
+ target_model=target_model,
185
+ target_column=target_column,
186
+ )
187
+ )
188
+ case _:
189
+ continue
190
+
191
+ return result
192
+
193
+
194
+ def _extract_ref_model(target_model_with_ref: str | None) -> str | None:
195
+ if target_model_with_ref is None:
196
+ return None
197
+
198
+ match = re.fullmatch(r"ref\(['\"]([\w.]+)['\"]\)", target_model_with_ref)
199
+ if match:
200
+ return match.group(1)
201
+
202
+ return None
203
+
204
+
205
+ def _manifest_materialization_to_dbt_materializaton(materialized: str | None) -> DbtMaterialization | None:
206
+ if materialized is None:
207
+ return None
208
+
209
+ try:
210
+ return DbtMaterialization(materialized)
211
+ except ValueError:
212
+ return None
@@ -1,6 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from enum import Enum
3
3
  from pathlib import Path
4
+ from typing import Literal
4
5
 
5
6
  from pydantic import BaseModel, Field
6
7
 
@@ -19,11 +20,39 @@ class DbtMaterialization(str, Enum):
19
20
  return self.value
20
21
 
21
22
 
23
+ @dataclass(kw_only=True)
24
+ class DbtSimpleConstraint:
25
+ type: Literal["unique", "not_null"]
26
+ is_enforced: bool
27
+ description: str | None = None
28
+
29
+
30
+ @dataclass(kw_only=True)
31
+ class DbtAcceptedValuesConstraint:
32
+ type: Literal["accepted_values"]
33
+ is_enforced: bool
34
+ description: str | None = None
35
+ accepted_values: list[str]
36
+
37
+
38
+ @dataclass(kw_only=True)
39
+ class DbtRelationshipConstraint:
40
+ type: Literal["relationships"]
41
+ is_enforced: bool
42
+ description: str | None = None
43
+ target_model: str
44
+ target_column: str
45
+
46
+
47
+ DbtConstraint = DbtSimpleConstraint | DbtAcceptedValuesConstraint | DbtRelationshipConstraint
48
+
49
+
22
50
  @dataclass(kw_only=True)
23
51
  class DbtColumn:
24
52
  name: str
25
53
  type: str | None = None
26
54
  description: str | None = None
55
+ constraints: list[DbtConstraint] | None = None
27
56
 
28
57
 
29
58
  @dataclass(kw_only=True)
@@ -1,10 +1,10 @@
1
1
  from dataclasses import dataclass
2
- from typing import Annotated, Literal
2
+ from typing import Annotated, Any, Literal
3
3
 
4
4
  from pydantic import BaseModel, Discriminator, Field
5
5
 
6
6
 
7
- class DbtManifestNodeConfig(BaseModel):
7
+ class DbtManifestModelConfig(BaseModel):
8
8
  materialized: str
9
9
 
10
10
 
@@ -21,17 +21,36 @@ class DbtManifestModel(BaseModel):
21
21
  database: str
22
22
  schema_: str = Field(alias="schema")
23
23
  description: str | None = None
24
- config: DbtManifestNodeConfig | None = None
24
+ config: DbtManifestModelConfig | None = None
25
25
  columns: dict[str, DbtManifestColumn]
26
26
  depends_on: dict[str, list[str]] | None = None
27
27
  primary_key: list[str] | None = None
28
28
 
29
29
 
30
+ class DbtManifestTestConfig(BaseModel):
31
+ severity: str
32
+
33
+
34
+ class DbtManifestTestMetadata(BaseModel):
35
+ name: str | None = None
36
+ kwargs: dict[str, Any] | None = None
37
+
38
+
39
+ class DbtManifestTest(BaseModel):
40
+ resource_type: Literal["test"]
41
+ unique_id: str
42
+ attached_node: str | None = None
43
+ column_name: str | None = None
44
+ description: str | None = None
45
+ test_metadata: DbtManifestTestMetadata | None = None
46
+ config: DbtManifestTestConfig | None = None
47
+
48
+
30
49
  class DbtManifestOtherNode(BaseModel):
31
- resource_type: Literal["seed", "analysis", "test", "operation", "sql_operation", "snapshot"]
50
+ resource_type: Literal["seed", "analysis", "operation", "sql_operation", "snapshot"]
32
51
 
33
52
 
34
- DbtManifestNode = Annotated[DbtManifestModel | DbtManifestOtherNode, Discriminator("resource_type")]
53
+ DbtManifestNode = Annotated[DbtManifestModel | DbtManifestTest | DbtManifestOtherNode, Discriminator("resource_type")]
35
54
 
36
55
 
37
56
  class DbtManifest(BaseModel):
@@ -30,33 +30,38 @@ class DceInfo:
30
30
  Attributes:
31
31
  version: The version of the databao_context_engine package installed on the system.
32
32
  dce_path: The path where databao_context_engine stores its global data.
33
- project_info: Information about the Databao Context Engine project.
34
33
  """
35
34
 
36
35
  version: str
37
36
  dce_path: Path
38
37
  plugin_ids: list[str]
39
38
 
40
- project_info: DceProjectInfo
41
39
 
42
-
43
- def get_databao_context_engine_info(project_dir: Path) -> DceInfo:
40
+ def get_databao_context_engine_info() -> DceInfo:
44
41
  """Return information about the current Databao Context Engine installation and project.
45
42
 
46
- Args:
47
- project_dir: The root directory of the Databao Context Project.
48
-
49
43
  Returns:
50
- A DceInfo instance containing information about the Databao Context Engine installation and project.
44
+ A DceInfo instance containing information about the Databao Context Engine installation.
51
45
  """
52
46
  return DceInfo(
53
47
  version=get_dce_version(),
54
48
  dce_path=get_dce_path(),
55
49
  plugin_ids=[plugin.id for plugin in load_plugins().values()],
56
- project_info=_get_project_info(project_dir),
57
50
  )
58
51
 
59
52
 
53
+ def get_databao_context_engine_project_info(project_dir: Path) -> DceProjectInfo:
54
+ """Return information about the current Databao Context Engine project.
55
+
56
+ Args:
57
+ project_dir: The root directory of the Databao Context Project.
58
+
59
+ Returns:
60
+ A DceProjectInfo instance containing information about the Databao Context Engine project.
61
+ """
62
+ return _get_project_info(project_dir)
63
+
64
+
60
65
  def _get_project_info(project_dir: Path) -> DceProjectInfo:
61
66
  project_layout = validate_project_dir(project_dir)
62
67
 
@@ -1,33 +0,0 @@
1
- import os
2
- import sys
3
- from pathlib import Path
4
-
5
- import click
6
-
7
- from databao_context_engine import DceInfo, get_databao_context_engine_info
8
-
9
-
10
- def echo_info(project_dir: Path) -> None:
11
- click.echo(_generate_info_string(get_databao_context_engine_info(project_dir=project_dir)))
12
-
13
-
14
- def _generate_info_string(command_info: DceInfo) -> str:
15
- info_lines = []
16
- info_lines.append(f"Databao context engine version: {command_info.version}")
17
- info_lines.append(f"Databao context engine storage dir: {command_info.dce_path}")
18
- info_lines.append(f"Databao context engine plugins: {command_info.plugin_ids}")
19
-
20
- info_lines.append("")
21
-
22
- info_lines.append(f"OS name: {sys.platform}")
23
- info_lines.append(f"OS architecture: {os.uname().machine if hasattr(os, 'uname') else 'unknown'}")
24
-
25
- info_lines.append("")
26
-
27
- if command_info.project_info.is_initialized:
28
- info_lines.append(f"Project dir: {command_info.project_info.project_path.resolve()}")
29
- info_lines.append(f"Project ID: {str(command_info.project_info.project_id)}")
30
- else:
31
- info_lines.append(f"Project not initialized at {command_info.project_info.project_path.resolve()}")
32
-
33
- return os.linesep.join(info_lines)
@@ -1,106 +0,0 @@
1
- from pathlib import Path
2
-
3
- from databao_context_engine.plugins.dbt.types import (
4
- DbtColumn,
5
- DbtConfigFile,
6
- DbtContext,
7
- DbtMaterialization,
8
- DbtModel,
9
- )
10
- from databao_context_engine.plugins.dbt.types_artifacts import (
11
- DbtArtifacts,
12
- DbtCatalog,
13
- DbtCatalogColumn,
14
- DbtCatalogNode,
15
- DbtManifest,
16
- DbtManifestColumn,
17
- DbtManifestModel,
18
- )
19
-
20
-
21
- def check_connection(config_file: DbtConfigFile) -> None:
22
- _read_dbt_artifacts(config_file.dbt_target_folder_path.expanduser())
23
-
24
-
25
- def extract_context(config_file: DbtConfigFile) -> DbtContext:
26
- artifacts = _read_dbt_artifacts(config_file.dbt_target_folder_path.expanduser())
27
-
28
- return _extract_context_from_artifacts(artifacts)
29
-
30
-
31
- def _read_dbt_artifacts(dbt_target_folder_path: Path) -> DbtArtifacts:
32
- if not dbt_target_folder_path.is_dir():
33
- raise ValueError(f'Invalid "dbt_target_folder_path": not a directory ({dbt_target_folder_path})')
34
-
35
- # TODO: Check the manifest schema version?
36
- manifest_file = dbt_target_folder_path.joinpath("manifest.json")
37
- if not manifest_file.is_file():
38
- raise ValueError(f'Invalid "dbt_target_folder_path": missing manifest.json file ({manifest_file})')
39
-
40
- manifest = DbtManifest.model_validate_json(manifest_file.read_text())
41
-
42
- catalog_file = dbt_target_folder_path.joinpath("catalog.json")
43
- catalog = DbtCatalog.model_validate_json(catalog_file.read_text()) if catalog_file.is_file() else None
44
-
45
- return DbtArtifacts(manifest=manifest, catalog=catalog)
46
-
47
-
48
- def _extract_context_from_artifacts(artifacts: DbtArtifacts) -> DbtContext:
49
- manifest_models = [
50
- manifest_model
51
- for manifest_model in artifacts.manifest.nodes.values()
52
- if isinstance(manifest_model, DbtManifestModel)
53
- ]
54
-
55
- catalog_nodes = artifacts.catalog.nodes if artifacts.catalog else {}
56
-
57
- # TODO: Extract the stages? Or at least the "highest-level" models (= marts?)
58
- # TODO: Extract the constraints
59
- # TODO: Organize the models by schemas? Or by stages?
60
- return DbtContext(
61
- models=[
62
- _manifest_model_to_dbt_model(manifest_model, catalog_nodes.get(manifest_model.unique_id, None))
63
- for manifest_model in manifest_models
64
- ],
65
- )
66
-
67
-
68
- def _manifest_model_to_dbt_model(manifest_model: DbtManifestModel, catalog_node: DbtCatalogNode | None) -> DbtModel:
69
- catalog_columns = catalog_node.columns if catalog_node else {}
70
-
71
- return DbtModel(
72
- id=manifest_model.unique_id,
73
- name=manifest_model.name,
74
- database=manifest_model.database,
75
- schema=manifest_model.schema_,
76
- description=manifest_model.description,
77
- columns=[
78
- _manifest_column_to_dbt_column(manifest_column, catalog_columns.get(manifest_column.name))
79
- for manifest_column in manifest_model.columns.values()
80
- ],
81
- materialization=_manifest_materialization_to_dbt_materializaton(
82
- manifest_model.config.materialized if manifest_model.config else None
83
- ),
84
- primary_key=manifest_model.primary_key,
85
- depends_on_nodes=manifest_model.depends_on.get("nodes", []) if manifest_model.depends_on else [],
86
- )
87
-
88
-
89
- def _manifest_column_to_dbt_column(
90
- manifest_column: DbtManifestColumn, catalog_column: DbtCatalogColumn | None
91
- ) -> DbtColumn:
92
- return DbtColumn(
93
- name=manifest_column.name,
94
- description=manifest_column.description,
95
- type=catalog_column.type if catalog_column else manifest_column.data_type,
96
- )
97
-
98
-
99
- def _manifest_materialization_to_dbt_materializaton(materialized: str | None) -> DbtMaterialization | None:
100
- if materialized is None:
101
- return None
102
-
103
- try:
104
- return DbtMaterialization(materialized)
105
- except ValueError:
106
- return None