imbi-api 2.0.0__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 (222) hide show
  1. imbi_api-2.0.0/.github/workflows/deploy.yaml +45 -0
  2. imbi_api-2.0.0/.github/workflows/docs.yaml +54 -0
  3. imbi_api-2.0.0/.github/workflows/testing.yaml +60 -0
  4. imbi_api-2.0.0/.gitignore +13 -0
  5. imbi_api-2.0.0/.pre-commit-config.yaml +37 -0
  6. imbi_api-2.0.0/.python-version +1 -0
  7. imbi_api-2.0.0/CLAUDE.md +173 -0
  8. imbi_api-2.0.0/LICENSE +28 -0
  9. imbi_api-2.0.0/PKG-INFO +188 -0
  10. imbi_api-2.0.0/README.md +143 -0
  11. imbi_api-2.0.0/coderabbit.yaml +32 -0
  12. imbi_api-2.0.0/compose.yaml +62 -0
  13. imbi_api-2.0.0/docs/adr/0001-record-architecture-decisions.md +19 -0
  14. imbi_api-2.0.0/docs/adr/0002-authentication-and-authorization-architecture.md +351 -0
  15. imbi_api-2.0.0/docs/adr/0003-email-sending-architecture.md +368 -0
  16. imbi_api-2.0.0/docs/adr/0004-phase-5-authentication-enhancements.md +365 -0
  17. imbi_api-2.0.0/docs/adr/0005-file-upload-storage-architecture.md +164 -0
  18. imbi_api-2.0.0/docs/adr/0006-project-identity-and-multi-type.md +92 -0
  19. imbi_api-2.0.0/docs/adr/0007-relationship-blueprints.md +131 -0
  20. imbi_api-2.0.0/docs/adr.md +209 -0
  21. imbi_api-2.0.0/docs/configuration.md +383 -0
  22. imbi_api-2.0.0/docs/index.md +133 -0
  23. imbi_api-2.0.0/justfile +112 -0
  24. imbi_api-2.0.0/mkdocs.yml +80 -0
  25. imbi_api-2.0.0/mypy.ini +33 -0
  26. imbi_api-2.0.0/pyproject.toml +229 -0
  27. imbi_api-2.0.0/src/imbi_api/__init__.py +15 -0
  28. imbi_api-2.0.0/src/imbi_api/app.py +83 -0
  29. imbi_api-2.0.0/src/imbi_api/auth/__init__.py +1 -0
  30. imbi_api-2.0.0/src/imbi_api/auth/local_auth.py +58 -0
  31. imbi_api-2.0.0/src/imbi_api/auth/login_providers.py +255 -0
  32. imbi_api-2.0.0/src/imbi_api/auth/models.py +86 -0
  33. imbi_api-2.0.0/src/imbi_api/auth/oauth.py +353 -0
  34. imbi_api-2.0.0/src/imbi_api/auth/password.py +58 -0
  35. imbi_api-2.0.0/src/imbi_api/auth/permissions.py +596 -0
  36. imbi_api-2.0.0/src/imbi_api/auth/seed.py +704 -0
  37. imbi_api-2.0.0/src/imbi_api/auth/sessions.py +106 -0
  38. imbi_api-2.0.0/src/imbi_api/auth/tokens.py +187 -0
  39. imbi_api-2.0.0/src/imbi_api/domain/__init__.py +1 -0
  40. imbi_api-2.0.0/src/imbi_api/domain/models.py +1191 -0
  41. imbi_api-2.0.0/src/imbi_api/domain/scoring.py +141 -0
  42. imbi_api-2.0.0/src/imbi_api/email/__init__.py +171 -0
  43. imbi_api-2.0.0/src/imbi_api/email/client.py +274 -0
  44. imbi_api-2.0.0/src/imbi_api/email/dependencies.py +34 -0
  45. imbi_api-2.0.0/src/imbi_api/email/models.py +131 -0
  46. imbi_api-2.0.0/src/imbi_api/email/templates/base.html +203 -0
  47. imbi_api-2.0.0/src/imbi_api/email/templates/base.txt +13 -0
  48. imbi_api-2.0.0/src/imbi_api/email/templates/password_reset.html +49 -0
  49. imbi_api-2.0.0/src/imbi_api/email/templates/password_reset.txt +24 -0
  50. imbi_api-2.0.0/src/imbi_api/email/templates/welcome.html +42 -0
  51. imbi_api-2.0.0/src/imbi_api/email/templates/welcome.txt +24 -0
  52. imbi_api-2.0.0/src/imbi_api/email/templates.py +192 -0
  53. imbi_api-2.0.0/src/imbi_api/endpoints/__init__.py +59 -0
  54. imbi_api-2.0.0/src/imbi_api/endpoints/_helpers.py +241 -0
  55. imbi_api-2.0.0/src/imbi_api/endpoints/admin.py +48 -0
  56. imbi_api-2.0.0/src/imbi_api/endpoints/admin_plugins.py +483 -0
  57. imbi_api-2.0.0/src/imbi_api/endpoints/api_keys.py +406 -0
  58. imbi_api-2.0.0/src/imbi_api/endpoints/auth.py +1311 -0
  59. imbi_api-2.0.0/src/imbi_api/endpoints/auth_providers.py +668 -0
  60. imbi_api-2.0.0/src/imbi_api/endpoints/blueprints.py +347 -0
  61. imbi_api-2.0.0/src/imbi_api/endpoints/client_credentials.py +396 -0
  62. imbi_api-2.0.0/src/imbi_api/endpoints/document_templates.py +590 -0
  63. imbi_api-2.0.0/src/imbi_api/endpoints/documents.py +678 -0
  64. imbi_api-2.0.0/src/imbi_api/endpoints/environments.py +537 -0
  65. imbi_api-2.0.0/src/imbi_api/endpoints/events.py +264 -0
  66. imbi_api-2.0.0/src/imbi_api/endpoints/identity_plugins.py +79 -0
  67. imbi_api-2.0.0/src/imbi_api/endpoints/link_definitions.py +488 -0
  68. imbi_api-2.0.0/src/imbi_api/endpoints/local_auth.py +77 -0
  69. imbi_api-2.0.0/src/imbi_api/endpoints/mfa.py +456 -0
  70. imbi_api-2.0.0/src/imbi_api/endpoints/operations_log.py +642 -0
  71. imbi_api-2.0.0/src/imbi_api/endpoints/organizations.py +523 -0
  72. imbi_api-2.0.0/src/imbi_api/endpoints/plugin_edges.py +369 -0
  73. imbi_api-2.0.0/src/imbi_api/endpoints/plugin_entities.py +345 -0
  74. imbi_api-2.0.0/src/imbi_api/endpoints/project_configuration.py +408 -0
  75. imbi_api-2.0.0/src/imbi_api/endpoints/project_deployments.py +1113 -0
  76. imbi_api-2.0.0/src/imbi_api/endpoints/project_logs.py +525 -0
  77. imbi_api-2.0.0/src/imbi_api/endpoints/project_plugins.py +201 -0
  78. imbi_api-2.0.0/src/imbi_api/endpoints/project_type_plugins.py +167 -0
  79. imbi_api-2.0.0/src/imbi_api/endpoints/project_types.py +458 -0
  80. imbi_api-2.0.0/src/imbi_api/endpoints/projects.py +1632 -0
  81. imbi_api-2.0.0/src/imbi_api/endpoints/releases.py +1070 -0
  82. imbi_api-2.0.0/src/imbi_api/endpoints/roles.py +567 -0
  83. imbi_api-2.0.0/src/imbi_api/endpoints/sa_api_keys.py +387 -0
  84. imbi_api-2.0.0/src/imbi_api/endpoints/scoring.py +574 -0
  85. imbi_api-2.0.0/src/imbi_api/endpoints/scoring_policies.py +345 -0
  86. imbi_api-2.0.0/src/imbi_api/endpoints/service_accounts.py +449 -0
  87. imbi_api-2.0.0/src/imbi_api/endpoints/service_plugins.py +869 -0
  88. imbi_api-2.0.0/src/imbi_api/endpoints/status.py +21 -0
  89. imbi_api-2.0.0/src/imbi_api/endpoints/tags.py +334 -0
  90. imbi_api-2.0.0/src/imbi_api/endpoints/teams.py +621 -0
  91. imbi_api-2.0.0/src/imbi_api/endpoints/third_party_services.py +1333 -0
  92. imbi_api-2.0.0/src/imbi_api/endpoints/uploads.py +363 -0
  93. imbi_api-2.0.0/src/imbi_api/endpoints/user_activity.py +1047 -0
  94. imbi_api-2.0.0/src/imbi_api/endpoints/users.py +918 -0
  95. imbi_api-2.0.0/src/imbi_api/endpoints/webhooks.py +891 -0
  96. imbi_api-2.0.0/src/imbi_api/entrypoint.py +228 -0
  97. imbi_api-2.0.0/src/imbi_api/graph_sql.py +26 -0
  98. imbi_api-2.0.0/src/imbi_api/identity/__init__.py +1 -0
  99. imbi_api-2.0.0/src/imbi_api/identity/endpoints.py +272 -0
  100. imbi_api-2.0.0/src/imbi_api/identity/errors.py +28 -0
  101. imbi_api-2.0.0/src/imbi_api/identity/flows.py +434 -0
  102. imbi_api-2.0.0/src/imbi_api/identity/host_integration.py +168 -0
  103. imbi_api-2.0.0/src/imbi_api/identity/models.py +79 -0
  104. imbi_api-2.0.0/src/imbi_api/identity/repository.py +428 -0
  105. imbi_api-2.0.0/src/imbi_api/identity/resolution.py +203 -0
  106. imbi_api-2.0.0/src/imbi_api/identity/state.py +127 -0
  107. imbi_api-2.0.0/src/imbi_api/identity/sweeper.py +133 -0
  108. imbi_api-2.0.0/src/imbi_api/lifespans.py +163 -0
  109. imbi_api-2.0.0/src/imbi_api/llm/__init__.py +0 -0
  110. imbi_api-2.0.0/src/imbi_api/llm/dependencies.py +20 -0
  111. imbi_api-2.0.0/src/imbi_api/middleware/__init__.py +5 -0
  112. imbi_api-2.0.0/src/imbi_api/middleware/rate_limit.py +53 -0
  113. imbi_api-2.0.0/src/imbi_api/models.py +104 -0
  114. imbi_api-2.0.0/src/imbi_api/openapi.py +437 -0
  115. imbi_api-2.0.0/src/imbi_api/patch.py +107 -0
  116. imbi_api-2.0.0/src/imbi_api/plugins/__init__.py +40 -0
  117. imbi_api-2.0.0/src/imbi_api/plugins/assignments.py +128 -0
  118. imbi_api-2.0.0/src/imbi_api/plugins/credentials.py +245 -0
  119. imbi_api-2.0.0/src/imbi_api/plugins/installer.py +87 -0
  120. imbi_api-2.0.0/src/imbi_api/plugins/lifecycle.py +141 -0
  121. imbi_api-2.0.0/src/imbi_api/plugins/reload.py +80 -0
  122. imbi_api-2.0.0/src/imbi_api/plugins/resolution.py +233 -0
  123. imbi_api-2.0.0/src/imbi_api/plugins/schemas.py +80 -0
  124. imbi_api-2.0.0/src/imbi_api/py.typed +0 -0
  125. imbi_api-2.0.0/src/imbi_api/relationships.py +23 -0
  126. imbi_api-2.0.0/src/imbi_api/scoring/__init__.py +44 -0
  127. imbi_api-2.0.0/src/imbi_api/scoring/queue.py +281 -0
  128. imbi_api-2.0.0/src/imbi_api/settings.py +302 -0
  129. imbi_api-2.0.0/src/imbi_api/storage/__init__.py +13 -0
  130. imbi_api-2.0.0/src/imbi_api/storage/client.py +187 -0
  131. imbi_api-2.0.0/src/imbi_api/storage/dependencies.py +21 -0
  132. imbi_api-2.0.0/src/imbi_api/storage/thumbnails.py +90 -0
  133. imbi_api-2.0.0/src/imbi_api/storage/validation.py +107 -0
  134. imbi_api-2.0.0/tests/__init__.py +0 -0
  135. imbi_api-2.0.0/tests/auth/__init__.py +1 -0
  136. imbi_api-2.0.0/tests/auth/test_api_key_auth.py +422 -0
  137. imbi_api-2.0.0/tests/auth/test_authentication.py +494 -0
  138. imbi_api-2.0.0/tests/auth/test_authorization.py +571 -0
  139. imbi_api-2.0.0/tests/auth/test_encryption.py +218 -0
  140. imbi_api-2.0.0/tests/auth/test_login_providers.py +253 -0
  141. imbi_api-2.0.0/tests/auth/test_oauth.py +855 -0
  142. imbi_api-2.0.0/tests/auth/test_permissions.py +348 -0
  143. imbi_api-2.0.0/tests/auth/test_seed.py +337 -0
  144. imbi_api-2.0.0/tests/auth/test_sessions.py +130 -0
  145. imbi_api-2.0.0/tests/clickhouse/__init__.py +1 -0
  146. imbi_api-2.0.0/tests/clickhouse/test_client.py +500 -0
  147. imbi_api-2.0.0/tests/clickhouse/test_init.py +341 -0
  148. imbi_api-2.0.0/tests/clickhouse/test_privacy.py +359 -0
  149. imbi_api-2.0.0/tests/email/__init__.py +1 -0
  150. imbi_api-2.0.0/tests/email/test_client.py +416 -0
  151. imbi_api-2.0.0/tests/email/test_init.py +37 -0
  152. imbi_api-2.0.0/tests/email/test_integration.py +333 -0
  153. imbi_api-2.0.0/tests/email/test_models.py +110 -0
  154. imbi_api-2.0.0/tests/email/test_templates.py +189 -0
  155. imbi_api-2.0.0/tests/endpoints/__init__.py +0 -0
  156. imbi_api-2.0.0/tests/endpoints/test_admin.py +126 -0
  157. imbi_api-2.0.0/tests/endpoints/test_admin_plugins.py +241 -0
  158. imbi_api-2.0.0/tests/endpoints/test_api_keys.py +435 -0
  159. imbi_api-2.0.0/tests/endpoints/test_auth.py +2610 -0
  160. imbi_api-2.0.0/tests/endpoints/test_auth_providers.py +548 -0
  161. imbi_api-2.0.0/tests/endpoints/test_blueprints.py +359 -0
  162. imbi_api-2.0.0/tests/endpoints/test_client_credentials.py +318 -0
  163. imbi_api-2.0.0/tests/endpoints/test_document_templates.py +430 -0
  164. imbi_api-2.0.0/tests/endpoints/test_documents.py +644 -0
  165. imbi_api-2.0.0/tests/endpoints/test_environments.py +465 -0
  166. imbi_api-2.0.0/tests/endpoints/test_events.py +288 -0
  167. imbi_api-2.0.0/tests/endpoints/test_init.py +24 -0
  168. imbi_api-2.0.0/tests/endpoints/test_link_definitions.py +412 -0
  169. imbi_api-2.0.0/tests/endpoints/test_local_auth.py +168 -0
  170. imbi_api-2.0.0/tests/endpoints/test_mfa.py +917 -0
  171. imbi_api-2.0.0/tests/endpoints/test_operations_log.py +524 -0
  172. imbi_api-2.0.0/tests/endpoints/test_organizations.py +344 -0
  173. imbi_api-2.0.0/tests/endpoints/test_project_configuration.py +646 -0
  174. imbi_api-2.0.0/tests/endpoints/test_project_deployments.py +856 -0
  175. imbi_api-2.0.0/tests/endpoints/test_project_logs.py +285 -0
  176. imbi_api-2.0.0/tests/endpoints/test_project_plugins.py +195 -0
  177. imbi_api-2.0.0/tests/endpoints/test_project_type_plugins.py +153 -0
  178. imbi_api-2.0.0/tests/endpoints/test_project_types.py +446 -0
  179. imbi_api-2.0.0/tests/endpoints/test_projects.py +1112 -0
  180. imbi_api-2.0.0/tests/endpoints/test_releases.py +972 -0
  181. imbi_api-2.0.0/tests/endpoints/test_roles.py +541 -0
  182. imbi_api-2.0.0/tests/endpoints/test_sa_api_keys.py +462 -0
  183. imbi_api-2.0.0/tests/endpoints/test_scoring.py +568 -0
  184. imbi_api-2.0.0/tests/endpoints/test_scoring_policies.py +365 -0
  185. imbi_api-2.0.0/tests/endpoints/test_service_accounts.py +478 -0
  186. imbi_api-2.0.0/tests/endpoints/test_service_plugins.py +958 -0
  187. imbi_api-2.0.0/tests/endpoints/test_status.py +58 -0
  188. imbi_api-2.0.0/tests/endpoints/test_tags.py +292 -0
  189. imbi_api-2.0.0/tests/endpoints/test_teams.py +721 -0
  190. imbi_api-2.0.0/tests/endpoints/test_third_party_services.py +1678 -0
  191. imbi_api-2.0.0/tests/endpoints/test_uploads.py +409 -0
  192. imbi_api-2.0.0/tests/endpoints/test_user_activity.py +447 -0
  193. imbi_api-2.0.0/tests/endpoints/test_users.py +1466 -0
  194. imbi_api-2.0.0/tests/endpoints/test_webhooks.py +1557 -0
  195. imbi_api-2.0.0/tests/identity/__init__.py +1 -0
  196. imbi_api-2.0.0/tests/identity/test_endpoints.py +313 -0
  197. imbi_api-2.0.0/tests/identity/test_errors.py +34 -0
  198. imbi_api-2.0.0/tests/identity/test_flows.py +476 -0
  199. imbi_api-2.0.0/tests/identity/test_host_integration.py +254 -0
  200. imbi_api-2.0.0/tests/identity/test_repository.py +384 -0
  201. imbi_api-2.0.0/tests/identity/test_resolution.py +380 -0
  202. imbi_api-2.0.0/tests/identity/test_state.py +171 -0
  203. imbi_api-2.0.0/tests/identity/test_sweeper.py +272 -0
  204. imbi_api-2.0.0/tests/middleware/test_rate_limit.py +71 -0
  205. imbi_api-2.0.0/tests/storage/__init__.py +0 -0
  206. imbi_api-2.0.0/tests/storage/test_client.py +152 -0
  207. imbi_api-2.0.0/tests/storage/test_init.py +20 -0
  208. imbi_api-2.0.0/tests/storage/test_thumbnails.py +85 -0
  209. imbi_api-2.0.0/tests/storage/test_validation.py +136 -0
  210. imbi_api-2.0.0/tests/test_app.py +71 -0
  211. imbi_api-2.0.0/tests/test_blueprints.py +591 -0
  212. imbi_api-2.0.0/tests/test_entrypoint.py +265 -0
  213. imbi_api-2.0.0/tests/test_init.py +35 -0
  214. imbi_api-2.0.0/tests/test_lifespans.py +135 -0
  215. imbi_api-2.0.0/tests/test_models.py +686 -0
  216. imbi_api-2.0.0/tests/test_openapi.py +421 -0
  217. imbi_api-2.0.0/tests/test_patch.py +135 -0
  218. imbi_api-2.0.0/tests/test_plugins.py +913 -0
  219. imbi_api-2.0.0/tests/test_scoring_queue.py +496 -0
  220. imbi_api-2.0.0/tests/test_scoring_triggers.py +57 -0
  221. imbi_api-2.0.0/tests/test_settings.py +326 -0
  222. imbi_api-2.0.0/uv.lock +2898 -0
@@ -0,0 +1,45 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ id-token: write
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v6
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v5
20
+
21
+ - name: Set up Python
22
+ run: uv python install 3.14
23
+
24
+ - name: Build
25
+ run: uv build
26
+
27
+ - name: Upload dist
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ steps:
38
+ - name: Download dist
39
+ uses: actions/download-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+
44
+ - name: Publish package
45
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,54 @@
1
+ name: Deploy Documentation
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'docs/**'
9
+ - 'mkdocs.yml'
10
+ - '.github/workflows/docs.yaml'
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+ pages: write
16
+ id-token: write
17
+
18
+ concurrency:
19
+ group: "pages"
20
+ cancel-in-progress: false
21
+
22
+ jobs:
23
+ build:
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - name: Checkout repository
27
+ uses: actions/checkout@v5
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v7
31
+ with:
32
+ enable-cache: true
33
+
34
+ - name: Install dependencies
35
+ run: uv sync --all-extras --all-groups --frozen
36
+
37
+ - name: Build documentation
38
+ run: uv run mkdocs build --strict
39
+
40
+ - name: Upload artifact
41
+ uses: actions/upload-pages-artifact@v3
42
+ with:
43
+ path: ./site
44
+
45
+ deploy:
46
+ environment:
47
+ name: github-pages
48
+ url: ${{ steps.deployment.outputs.page_url }}
49
+ runs-on: ubuntu-latest
50
+ needs: build
51
+ steps:
52
+ - name: Deploy to GitHub Pages
53
+ id: deployment
54
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,60 @@
1
+ name: "Run Tests"
2
+ on:
3
+ push:
4
+ branches: [ main ]
5
+ paths-ignore:
6
+ - 'docs/**'
7
+ - '*.md'
8
+ tags-ignore: [ "*" ]
9
+ pull_request:
10
+ branches: [ main ]
11
+
12
+ jobs:
13
+ lint:
14
+ name: "Static Analysis"
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v5
19
+ - name: Install just
20
+ uses: taiki-e/install-action@v2
21
+ with:
22
+ tool: just@1.50.0
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v7
25
+ with:
26
+ enable-cache: true
27
+ - name: Run lint checks
28
+ env:
29
+ UV_FROZEN: "1"
30
+ run: just lint
31
+
32
+ test:
33
+ name: "Automated Tests"
34
+ runs-on: ubuntu-latest
35
+ strategy:
36
+ fail-fast: false
37
+ matrix:
38
+ python: [ "3.14" ]
39
+ steps:
40
+ - name: Checkout repository
41
+ uses: actions/checkout@v5
42
+ - name: Install just
43
+ uses: taiki-e/install-action@v2
44
+ with:
45
+ tool: just@1.50.0
46
+ - name: Install uv
47
+ uses: astral-sh/setup-uv@v7
48
+ with:
49
+ enable-cache: true
50
+ python-version: ${{ matrix.python }}
51
+ - name: Run tests
52
+ env:
53
+ UV_FROZEN: "1"
54
+ run: just test
55
+ - name: Upload coverage reports
56
+ uses: codecov/codecov-action@v5
57
+ with:
58
+ token: ${{ secrets.CODECOV_TOKEN }}
59
+ files: "build/coverage.xml"
60
+ flags: unittests
@@ -0,0 +1,13 @@
1
+ .*
2
+ /build
3
+ /dist
4
+ /docs/superpowers
5
+ /public
6
+ /site
7
+ VERSION
8
+ __pycache__/
9
+ *.pyc
10
+ !/.github
11
+ !/.gitignore
12
+ !/.pre-commit-config.yaml
13
+ !/.python-version
@@ -0,0 +1,37 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-added-large-files
9
+ - id: check-merge-conflict
10
+ - id: check-toml
11
+ - id: debug-statements
12
+
13
+ - repo: https://github.com/astral-sh/ruff-pre-commit
14
+ rev: v0.14.6
15
+ hooks:
16
+ - id: ruff-check
17
+ args: [--fix]
18
+ - id: ruff-format
19
+
20
+ - repo: https://github.com/tombi-toml/tombi-pre-commit
21
+ rev: v0.7.25
22
+ hooks:
23
+ - id: tombi-format
24
+
25
+ - repo: local
26
+ hooks:
27
+ - id: mypy
28
+ name: mypy
29
+ language: system
30
+ types: [python]
31
+ pass_filenames: false
32
+ entry: uv
33
+ args:
34
+ - run
35
+ - --no-sync
36
+ - mypy
37
+ - src
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,173 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Imbi is a DevOps Service Management Platform designed to manage large environments containing many services and applications. Version 2 (currently in alpha) is a complete rewrite using FastAPI, Apache AGE (PostgreSQL) for graph data, and ClickHouse for analytics.
8
+
9
+ **See [README.md](README.md)** for project overview and core concepts.
10
+
11
+ ## Development Commands
12
+
13
+ This project uses [just](https://github.com/casey/just) as a command runner and [uv](https://docs.astral.sh/uv/) for Python package management:
14
+
15
+ ```bash
16
+ just setup # Install deps + pre-commit hooks (uv sync --all-groups --all-extras --frozen)
17
+ just serve # Setup + docker + run the API server
18
+ just serve --dev # Run with auto-reload
19
+ just test # Setup + docker + run all tests with coverage
20
+ just test <test> # Run a single test using pytest syntax
21
+ just lint # Setup + run pre-commit, basedpyright, mypy
22
+ just format # Setup + reformat all files
23
+ just format <file> # Reformat a specific file
24
+ just clean # Remove runtime artifacts + tear down docker
25
+ just real-clean # Remove everything including .venv and caches (with confirmation)
26
+ ```
27
+
28
+ ### Running Tests
29
+
30
+ ```bash
31
+ just test tests/auth/test_permissions.py
32
+ just test tests/auth/test_permissions.py::PermissionTests::test_get_permissions
33
+ just test -v
34
+ ```
35
+
36
+ ### First-Time Setup
37
+
38
+ ```bash
39
+ just setup
40
+ uv run imbi-api setup # Seeds roles/permissions, creates initial admin user (interactive, idempotent)
41
+ ```
42
+
43
+ ### Environment Configuration
44
+
45
+ The `docker` recipe (run automatically by `just serve` and `just test`) starts Docker Compose services and generates a `.env` file with dynamically assigned ports. Docker services defined in `compose.yaml`:
46
+ - **Neo4j**: graph database (ports 7474, 7687) — *migration to PostgreSQL+AGE in progress*
47
+ - **ClickHouse**: analytics (ports 8123, 9000)
48
+ - **Jaeger**: OpenTelemetry tracing (ports 4317, 16686)
49
+ - **Mailpit**: SMTP testing (ports 1025, 8025)
50
+ - **LocalStack**: S3-compatible object storage (port 4566)
51
+
52
+ The server starts on `localhost:8000` by default (configurable via `IMBI_HOST` and `IMBI_PORT`).
53
+
54
+ ## Code Architecture
55
+
56
+ ### Source Layout
57
+
58
+ ```
59
+ src/imbi_api/
60
+ ├── app.py # FastAPI application factory (create_app)
61
+ ├── entrypoint.py # CLI (Typer): `serve` and `setup` commands
62
+ ├── lifespans.py # Async lifespan hooks (ClickHouse, Graph, Email, Storage)
63
+ ├── models.py # Re-exports: imbi_common.models + domain.models
64
+ ├── settings.py # API-specific settings extending imbi_common.settings
65
+ ├── relationships.py # Hypermedia relationship link utilities
66
+ ├── openapi.py # Custom OpenAPI schema with blueprint-enhanced models
67
+ ├── domain/
68
+ │ └── models.py # API-specific models (APIKey, OAuth, ServiceAccount, etc.)
69
+ ├── endpoints/ # FastAPI routers (registered via endpoints/__init__.py:routers)
70
+ ├── auth/ # Auth system (permissions, seed, sessions, OAuth providers)
71
+ ├── email/ # SMTP client + Jinja2 templates with DI
72
+ ├── storage/ # S3 client via aioboto3 with DI
73
+ └── middleware/ # Rate limiting
74
+ ```
75
+
76
+ **imbi_common** (external git dependency): Shared code across Imbi services — core domain models, graph pool (Apache AGE), ClickHouse client, Cypher query generation, settings, JWT/password hashing.
77
+
78
+ ### Key Patterns
79
+
80
+ **Application factory** (`app.py`): `create_app()` composes lifespan hooks, CORS, rate limiting, and registers all routers from `endpoints/__init__.py`.
81
+
82
+ **Lifespan-based DI** (`lifespans.py`): Services are initialized/torn down via `imbi_common.lifespan.Lifespan`:
83
+ 1. `clickhouse_hook` — init/close ClickHouse (module-level singleton)
84
+ 2. `graph.graph_lifespan` — Graph pool (blueprint refresh registered via `graph.set_on_startup()` in `lifespans.py`)
85
+ 3. `email_hook` — yields `(EmailClient, TemplateManager)` tuple
86
+ 4. `storage_hook` — yields `StorageClient`
87
+
88
+ Each DI-managed service has a `dependencies.py` module with a `_get_*` function calling `context.get_state(hook)`, exposed as a type alias (e.g., `InjectStorageClient = Annotated[StorageClient, Depends(_get_storage_client)]`).
89
+
90
+ **Graph pool DI**: Injected via `graph.Pool` type alias (`Annotated[Graph, Depends(...)]`).
91
+
92
+ **Model re-exports** (`models.py`): Single import path combining `imbi_common.models` (shared domain: Blueprint, Organization, Project, etc.) and `imbi_api.domain.models` (API-specific: APIKey, OAuth, ServiceAccount, etc.).
93
+
94
+ ### Graph Integration (Apache AGE)
95
+
96
+ ```python
97
+ # In endpoint handlers — injected automatically:
98
+ @router.get('/items/')
99
+ async def list_items(db: graph.Pool) -> list[Item]:
100
+ return await db.match(Item)
101
+
102
+ # CRUD: create, merge (upsert), match (query), delete
103
+ await db.create(node)
104
+ await db.merge(node, ['slug'])
105
+ results = await db.match(Model, {'slug': 'foo'})
106
+ await db.delete(node)
107
+ ```
108
+
109
+ **Cypher template syntax** (AGE + `psycopg.sql.SQL.format()`):
110
+ - Parameters use `{param}` placeholders (NOT `$param`)
111
+ - Property maps must double-escape braces: `{{key: {value}}}`
112
+ - AGE has no `ON CREATE SET` / `ON MATCH SET` — use plain `SET`
113
+ - Timestamps are stored as ISO strings (no `datetime()` function)
114
+
115
+ ### Authentication & Authorization
116
+
117
+ ```python
118
+ @router.get('/resource')
119
+ async def get_resource(
120
+ auth: typing.Annotated[
121
+ permissions.AuthContext,
122
+ fastapi.Depends(permissions.require_permission('resource:read'))
123
+ ]
124
+ ) -> dict:
125
+ # auth.user, auth.token_metadata
126
+ return {'user': auth.user.username}
127
+ ```
128
+
129
+ Flow: OAuth/password -> JWT access token (15 min) + refresh token (7 days) -> `Authorization: Bearer <token>` -> `require_permission()` validates and checks permissions.
130
+
131
+ ### Testing Patterns
132
+
133
+ Tests use `unittest.IsolatedAsyncioTestCase`. Override DI dependencies via `app.dependency_overrides`:
134
+
135
+ ```python
136
+ from imbi_api.storage.dependencies import _get_storage_client
137
+ mock_storage = unittest.mock.AsyncMock(spec=StorageClient)
138
+ app.dependency_overrides[_get_storage_client] = lambda: mock_storage
139
+ ```
140
+
141
+ Coverage target: 90% (`pyproject.toml` `tool.coverage.report.fail_under`). Current: ~30%.
142
+
143
+ ## Code Style
144
+
145
+ - **Line length**: 79 characters
146
+ - **Quote style**: Single quotes
147
+ - **Python version**: 3.14+
148
+ - **Formatter/Linter**: Ruff (configured in `pyproject.toml`)
149
+ - **Type checking**: basedpyright (strict, `src/` + `tests/`) and mypy (strict, `mypy.ini`, `src/imbi_api` only)
150
+ - **Pre-commit hooks**: trailing whitespace, EOF fixer, YAML/TOML checks, debug statements, Ruff lint+format, tombi-format (TOML), mypy
151
+ - Always run `just format <filename>` on modified files before returning control to the user, running tests, or committing
152
+
153
+ **Conventions**:
154
+ - Async/await for all I/O operations
155
+ - Module-level loggers: `LOGGER = logging.getLogger(__name__)`
156
+ - Modern type hints (`str | None`, not `Optional[str]`)
157
+ - `typing.LiteralString` for Cypher queries
158
+ - **Prefer `typing.Literal` over `enum.StrEnum`** for constrained string fields — simple strings are the only type natively supported across AGE, ClickHouse, JSON, and msgpack
159
+
160
+ **Ignored ruff rules**: `N818`, `RSE`, `S105`/`S106`, `TRY003`, `TRY400`, `UP040`, `UP047`. Security rules (`S`) disabled in `tests/`.
161
+
162
+ ## CI/CD
163
+
164
+ **GitHub Actions** (`.github/workflows/`):
165
+ - `testing.yaml`: Lint (`just lint`) + tests (`just test`) on Python 3.14 on every push/PR to `main`. Coverage uploaded to Codecov.
166
+ - `docs.yaml`: MkDocs build/deploy to GitHub Pages on doc changes.
167
+ - `deploy.yaml`: On release — `uv build`, multi-platform Docker image to `ghcr.io`, provenance attestation.
168
+
169
+ ## Git Workflow
170
+
171
+ - Main branch: `main`
172
+ - Feature branches: `feature/<feature-name>`
173
+ - All PRs target `main`
imbi_api-2.0.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2018 - 2026, AWeber
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: imbi-api
3
+ Version: 2.0.0
4
+ Summary: Imbi is a DevOps Service Management Platform designed to provide an efficient way to manage a large environment that contains many services and applications.
5
+ Author-email: Alex Campbell <alexc@aweber.com>, Dave Shawley <daves@aweber.com>, "Gavin M. Roy" <gavinr@aweber.com>
6
+ License: BSD-3-Clause
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Natural Language :: English
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Requires-Python: >=3.14
15
+ Requires-Dist: aioboto3>=15.5.0
16
+ Requires-Dist: aiohttp
17
+ Requires-Dist: argon2-cffi>=25.1.0
18
+ Requires-Dist: authlib>=1.6.11
19
+ Requires-Dist: fastapi
20
+ Requires-Dist: filetype
21
+ Requires-Dist: httpx<1,>=0.28.1
22
+ Requires-Dist: imbi-common[databases,llm,server]>=0.8.4
23
+ Requires-Dist: jinja2
24
+ Requires-Dist: jsonpatch>=1.33
25
+ Requires-Dist: nanoid>=2.0.0
26
+ Requires-Dist: orjson>=3.11.6
27
+ Requires-Dist: pillow
28
+ Requires-Dist: pydantic[email]
29
+ Requires-Dist: pyotp>=2.9.0
30
+ Requires-Dist: python-multipart>=0.0.26
31
+ Requires-Dist: qrcode>=8.0
32
+ Requires-Dist: slowapi==0.1.9
33
+ Requires-Dist: typer
34
+ Requires-Dist: uvicorn
35
+ Requires-Dist: yarl
36
+ Provides-Extra: otel
37
+ Requires-Dist: opentelemetry-distro; extra == 'otel'
38
+ Requires-Dist: opentelemetry-instrumentation-asyncio; extra == 'otel'
39
+ Requires-Dist: opentelemetry-instrumentation-fastapi; extra == 'otel'
40
+ Requires-Dist: opentelemetry-instrumentation-httpx; extra == 'otel'
41
+ Requires-Dist: opentelemetry-instrumentation-jinja2; extra == 'otel'
42
+ Provides-Extra: sentry
43
+ Requires-Dist: sentry-sdk; extra == 'sentry'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # Imbi
47
+
48
+ > A DevOps Service Management Platform for managing complex service ecosystems
49
+
50
+ Imbi provides a centralized platform to manage, track, and understand all services and applications across your
51
+ organization. It serves as a single source of truth for service metadata, dependencies, ownership, and operational
52
+ information.
53
+
54
+ ## What is Imbi?
55
+
56
+ Imbi helps organizations answer critical questions about their service landscape:
57
+
58
+ - **What services do we have?** Complete inventory with ownership, type, and namespace organization
59
+ - **How are they related?** Graph-based dependency tracking and relationship visualization
60
+ - **Who owns what?** Clear ownership and team assignments
61
+ - **What's deployed where?** Environment-specific URLs and deployment tracking
62
+ - **What needs attention?** Project health scoring based on configurable factors
63
+ - **Where's the documentation?** Links to repos, CI/CD, monitoring, and other tools
64
+
65
+ ### Key Benefits
66
+
67
+ - **Single Source of Truth**: Centralized service catalog with comprehensive metadata
68
+ - **Relationship Visualization**: Graph database enables intuitive dependency mapping
69
+ - **Automation Ready**: API-first design enables integration with CI/CD, webhooks, and automations
70
+ - **AI-Powered**: Built-in vector search and conversational AI support for natural language queries
71
+ - **Extensible**: Blueprint system for customizable project metadata schemas
72
+ - **Developer Friendly**: Automatic data collection via GitHub webhooks and integrations
73
+
74
+ ## Version 2.0 (Alpha)
75
+
76
+ **Complete rewrite** using modern Python technologies for improved performance, scalability, and AI integration:
77
+
78
+ - **FastAPI**: Modern async web framework with automatic OpenAPI documentation
79
+ - **Apache AGE**: Graph database (PostgreSQL extension) for modeling service relationships and dependencies
80
+ - **ClickHouse**: Analytics and time-series data storage for operations logs and metrics
81
+ - **Pydantic v2**: Type-safe data validation and settings management
82
+
83
+ ### What's New in v2
84
+
85
+ - **Graph Database**: Apache AGE (PostgreSQL) for intuitive relationship modeling and AI-friendly Cypher queries
86
+ - **Modern API**: FastAPI provides automatic OpenAPI docs, async performance, and better type safety
87
+ - **Simplified Architecture**: Single PostgreSQL instance for relational and graph data
88
+ - **Full Authentication**: OAuth2/OIDC (Google, GitHub, Keycloak) and local password authentication with JWT tokens
89
+ - **Fine-Grained Authorization**: Permission-based access control with resource-level permissions and role management
90
+ - **Analytics Ready**: ClickHouse integration for operations logs and time-series metrics
91
+
92
+ For developers, see [CLAUDE.md](CLAUDE.md) for development guide and architecture details.
93
+
94
+ ## Quick Start
95
+
96
+ ### Development Environment
97
+
98
+ ```bash
99
+ # Set up development environment (install deps, pre-commit hooks)
100
+ just setup
101
+
102
+ # Start Docker services and run the development server with auto-reload
103
+ just serve --dev
104
+
105
+ # Initialize Imbi (first time only — seeds roles/permissions, creates admin user)
106
+ uv run imbi-api setup
107
+
108
+ # Access the API
109
+ curl http://localhost:8000/status
110
+ ```
111
+
112
+ ### Testing
113
+
114
+ ```bash
115
+ # Run all tests with coverage
116
+ just test
117
+
118
+ # Run pre-commit checks + type checking
119
+ just lint
120
+ ```
121
+
122
+ ## Core Concepts
123
+
124
+ ### Data Model
125
+
126
+ Imbi organizes services using a flexible, graph-based data model:
127
+
128
+ - **Organizations**: Top-level organizational units
129
+ - Unique slug identifier
130
+ - Name, description, and optional icon
131
+ - Foundation for hierarchical team structure
132
+
133
+ - **Teams**: Groups within organizations
134
+ - Managed by an organization (MANAGED_BY relationship)
135
+ - Own and maintain projects
136
+ - Unique slug identifier within their scope
137
+
138
+ - **Projects**: Individual services or applications
139
+ - Owned by a team (OWNED_BY relationship)
140
+ - Categorized by project type (TYPE relationship)
141
+ - Deployed in environments (DEPLOYED_IN relationship)
142
+ - Links to external tools (GitHub, Jira, PagerDuty, monitoring, etc.)
143
+ - Environment-specific URLs (staging, production, etc.)
144
+ - Custom identifiers (repo IDs, service IDs, etc.)
145
+
146
+ - **Project Types**: Service categorization
147
+ - Web Services, APIs, Libraries, Databases, etc.
148
+ - Unique slug identifier
149
+ - Used to classify projects
150
+
151
+ - **Environments**: Deployment targets
152
+ - Production, Staging, Development, etc.
153
+ - Unique slug identifier
154
+ - Projects can be deployed to multiple environments
155
+
156
+ - **Blueprints**: JSON Schema-based metadata templates
157
+ - Apply to Organizations, Teams, Environments, Project Types, or Projects
158
+ - Define custom fields with validation rules
159
+ - Enforce required metadata
160
+ - Priority-based application when multiple blueprints match
161
+ - Optional filtering based on entity properties
162
+
163
+ - **Users, Groups, and Roles**: Authentication and authorization
164
+ - Users with OAuth or local password authentication
165
+ - Groups for organizing users
166
+ - Roles with fine-grained permissions
167
+ - Resource-based access control
168
+
169
+ ### API Access
170
+
171
+ Once the server is running, explore the API:
172
+
173
+ ```bash
174
+ # Health check
175
+ curl http://localhost:8000/status
176
+
177
+ # Get authentication providers
178
+ curl http://localhost:8000/auth/providers
179
+
180
+ # API documentation
181
+ open http://localhost:8000/docs # ReDoc UI
182
+ ```
183
+
184
+ ## License
185
+
186
+ BSD 3-Clause License
187
+
188
+ Copyright (c) 2018 - 2026, AWeber