dataplat 0.1.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 (139) hide show
  1. dataplat-0.1.0/.github/workflows/ci.yml +31 -0
  2. dataplat-0.1.0/.github/workflows/release.yml +58 -0
  3. dataplat-0.1.0/.gitignore +212 -0
  4. dataplat-0.1.0/.python-version +1 -0
  5. dataplat-0.1.0/CHANGELOG.md +17 -0
  6. dataplat-0.1.0/LICENSE +21 -0
  7. dataplat-0.1.0/PKG-INFO +326 -0
  8. dataplat-0.1.0/README.md +282 -0
  9. dataplat-0.1.0/dataplat/__init__.py +3 -0
  10. dataplat-0.1.0/dataplat/cli/__init__.py +1 -0
  11. dataplat-0.1.0/dataplat/cli/_missing.py +108 -0
  12. dataplat-0.1.0/dataplat/cli/bi/__init__.py +1 -0
  13. dataplat-0.1.0/dataplat/cli/bi/app.py +14 -0
  14. dataplat-0.1.0/dataplat/cli/bi/superset.py +558 -0
  15. dataplat-0.1.0/dataplat/cli/ci/__init__.py +1 -0
  16. dataplat-0.1.0/dataplat/cli/ci/app.py +14 -0
  17. dataplat-0.1.0/dataplat/cli/ci/github/__init__.py +1 -0
  18. dataplat-0.1.0/dataplat/cli/ci/github/app.py +10 -0
  19. dataplat-0.1.0/dataplat/cli/ci/github/runner.py +399 -0
  20. dataplat-0.1.0/dataplat/cli/cloud/__init__.py +1 -0
  21. dataplat-0.1.0/dataplat/cli/cloud/app.py +14 -0
  22. dataplat-0.1.0/dataplat/cli/cloud/aws/__init__.py +1 -0
  23. dataplat-0.1.0/dataplat/cli/cloud/aws/_common.py +77 -0
  24. dataplat-0.1.0/dataplat/cli/cloud/aws/app.py +12 -0
  25. dataplat-0.1.0/dataplat/cli/cloud/aws/rds.py +686 -0
  26. dataplat-0.1.0/dataplat/cli/cloud/aws/redshift.py +312 -0
  27. dataplat-0.1.0/dataplat/cli/cloud/aws/secrets.py +875 -0
  28. dataplat-0.1.0/dataplat/cli/config.py +492 -0
  29. dataplat-0.1.0/dataplat/cli/db/__init__.py +342 -0
  30. dataplat-0.1.0/dataplat/cli/db/_common.py +130 -0
  31. dataplat-0.1.0/dataplat/cli/db/_report.py +180 -0
  32. dataplat-0.1.0/dataplat/cli/db/dbt_orphans.py +842 -0
  33. dataplat-0.1.0/dataplat/cli/db/describe.py +939 -0
  34. dataplat-0.1.0/dataplat/cli/db/long_queries.py +299 -0
  35. dataplat-0.1.0/dataplat/cli/db/role.py +434 -0
  36. dataplat-0.1.0/dataplat/cli/db/role_create.py +452 -0
  37. dataplat-0.1.0/dataplat/cli/db/role_drop.py +290 -0
  38. dataplat-0.1.0/dataplat/cli/db/role_list.py +147 -0
  39. dataplat-0.1.0/dataplat/cli/db/top_tables.py +337 -0
  40. dataplat-0.1.0/dataplat/cli/ingest/__init__.py +1 -0
  41. dataplat-0.1.0/dataplat/cli/ingest/airbyte/__init__.py +5 -0
  42. dataplat-0.1.0/dataplat/cli/ingest/airbyte/_common.py +36 -0
  43. dataplat-0.1.0/dataplat/cli/ingest/airbyte/_cursor.py +268 -0
  44. dataplat-0.1.0/dataplat/cli/ingest/airbyte/_resource.py +192 -0
  45. dataplat-0.1.0/dataplat/cli/ingest/airbyte/app.py +31 -0
  46. dataplat-0.1.0/dataplat/cli/ingest/airbyte/connections.py +1234 -0
  47. dataplat-0.1.0/dataplat/cli/ingest/airbyte/definitions.py +122 -0
  48. dataplat-0.1.0/dataplat/cli/ingest/airbyte/destinations.py +26 -0
  49. dataplat-0.1.0/dataplat/cli/ingest/airbyte/enums.py +45 -0
  50. dataplat-0.1.0/dataplat/cli/ingest/airbyte/jobs.py +112 -0
  51. dataplat-0.1.0/dataplat/cli/ingest/airbyte/sources.py +26 -0
  52. dataplat-0.1.0/dataplat/cli/ingest/airbyte/tags.py +57 -0
  53. dataplat-0.1.0/dataplat/cli/ingest/airbyte/templates.py +144 -0
  54. dataplat-0.1.0/dataplat/cli/ingest/airbyte/tui.py +123 -0
  55. dataplat-0.1.0/dataplat/cli/ingest/airbyte/workspaces.py +80 -0
  56. dataplat-0.1.0/dataplat/cli/ingest/app.py +14 -0
  57. dataplat-0.1.0/dataplat/cli/open.py +117 -0
  58. dataplat-0.1.0/dataplat/cli/status.py +308 -0
  59. dataplat-0.1.0/dataplat/core/__init__.py +1 -0
  60. dataplat-0.1.0/dataplat/core/deps.py +138 -0
  61. dataplat-0.1.0/dataplat/core/envrc.py +125 -0
  62. dataplat-0.1.0/dataplat/core/errors.py +23 -0
  63. dataplat-0.1.0/dataplat/main.py +87 -0
  64. dataplat-0.1.0/dataplat/services/__init__.py +1 -0
  65. dataplat-0.1.0/dataplat/services/airbyte/__init__.py +1 -0
  66. dataplat-0.1.0/dataplat/services/airbyte/_resource.py +113 -0
  67. dataplat-0.1.0/dataplat/services/airbyte/client.py +280 -0
  68. dataplat-0.1.0/dataplat/services/airbyte/connections.py +306 -0
  69. dataplat-0.1.0/dataplat/services/airbyte/definitions.py +64 -0
  70. dataplat-0.1.0/dataplat/services/airbyte/destinations.py +68 -0
  71. dataplat-0.1.0/dataplat/services/airbyte/jobs.py +72 -0
  72. dataplat-0.1.0/dataplat/services/airbyte/sources.py +58 -0
  73. dataplat-0.1.0/dataplat/services/airbyte/tags.py +120 -0
  74. dataplat-0.1.0/dataplat/services/airbyte/workspaces.py +47 -0
  75. dataplat-0.1.0/dataplat/services/aws/__init__.py +1 -0
  76. dataplat-0.1.0/dataplat/services/aws/auth.py +80 -0
  77. dataplat-0.1.0/dataplat/services/db/__init__.py +1 -0
  78. dataplat-0.1.0/dataplat/services/db/connection.py +169 -0
  79. dataplat-0.1.0/dataplat/services/db/describe.py +1034 -0
  80. dataplat-0.1.0/dataplat/services/db/long_queries.py +378 -0
  81. dataplat-0.1.0/dataplat/services/db/orphans.py +429 -0
  82. dataplat-0.1.0/dataplat/services/db/role.py +812 -0
  83. dataplat-0.1.0/dataplat/services/db/role_admin.py +458 -0
  84. dataplat-0.1.0/dataplat/services/db/role_dialects.py +521 -0
  85. dataplat-0.1.0/dataplat/services/db/targets.py +128 -0
  86. dataplat-0.1.0/dataplat/services/db/top_tables.py +193 -0
  87. dataplat-0.1.0/dataplat/services/superset/__init__.py +1 -0
  88. dataplat-0.1.0/dataplat/services/superset/client.py +319 -0
  89. dataplat-0.1.0/pyproject.toml +95 -0
  90. dataplat-0.1.0/tests/__init__.py +0 -0
  91. dataplat-0.1.0/tests/cli/__init__.py +0 -0
  92. dataplat-0.1.0/tests/cli/test_airbyte_commands.py +555 -0
  93. dataplat-0.1.0/tests/cli/test_airbyte_cursor_logic.py +387 -0
  94. dataplat-0.1.0/tests/cli/test_airbyte_guards.py +127 -0
  95. dataplat-0.1.0/tests/cli/test_aws_secrets.py +347 -0
  96. dataplat-0.1.0/tests/cli/test_cli_smoke.py +267 -0
  97. dataplat-0.1.0/tests/cli/test_config.py +152 -0
  98. dataplat-0.1.0/tests/cli/test_db_common.py +76 -0
  99. dataplat-0.1.0/tests/cli/test_db_long_queries.py +163 -0
  100. dataplat-0.1.0/tests/cli/test_db_query.py +70 -0
  101. dataplat-0.1.0/tests/cli/test_dbt_orphans.py +102 -0
  102. dataplat-0.1.0/tests/cli/test_describe.py +534 -0
  103. dataplat-0.1.0/tests/cli/test_github_runner.py +402 -0
  104. dataplat-0.1.0/tests/cli/test_missing_deps.py +107 -0
  105. dataplat-0.1.0/tests/cli/test_open.py +61 -0
  106. dataplat-0.1.0/tests/cli/test_redshift.py +17 -0
  107. dataplat-0.1.0/tests/cli/test_regression.py +140 -0
  108. dataplat-0.1.0/tests/cli/test_role.py +389 -0
  109. dataplat-0.1.0/tests/cli/test_role_create.py +213 -0
  110. dataplat-0.1.0/tests/cli/test_status.py +138 -0
  111. dataplat-0.1.0/tests/cli/test_top_tables.py +185 -0
  112. dataplat-0.1.0/tests/conftest.py +42 -0
  113. dataplat-0.1.0/tests/core/__init__.py +0 -0
  114. dataplat-0.1.0/tests/core/test_deps.py +117 -0
  115. dataplat-0.1.0/tests/core/test_envrc.py +134 -0
  116. dataplat-0.1.0/tests/services/__init__.py +0 -0
  117. dataplat-0.1.0/tests/services/airbyte/__init__.py +0 -0
  118. dataplat-0.1.0/tests/services/airbyte/test_client.py +39 -0
  119. dataplat-0.1.0/tests/services/airbyte/test_connections.py +194 -0
  120. dataplat-0.1.0/tests/services/airbyte/test_definitions.py +98 -0
  121. dataplat-0.1.0/tests/services/airbyte/test_destinations.py +138 -0
  122. dataplat-0.1.0/tests/services/airbyte/test_jobs.py +105 -0
  123. dataplat-0.1.0/tests/services/airbyte/test_sources.py +138 -0
  124. dataplat-0.1.0/tests/services/airbyte/test_workspaces.py +92 -0
  125. dataplat-0.1.0/tests/services/aws/__init__.py +0 -0
  126. dataplat-0.1.0/tests/services/aws/test_auth.py +103 -0
  127. dataplat-0.1.0/tests/services/db/__init__.py +0 -0
  128. dataplat-0.1.0/tests/services/db/test_connection.py +125 -0
  129. dataplat-0.1.0/tests/services/db/test_describe.py +667 -0
  130. dataplat-0.1.0/tests/services/db/test_long_queries.py +165 -0
  131. dataplat-0.1.0/tests/services/db/test_orphans.py +599 -0
  132. dataplat-0.1.0/tests/services/db/test_role.py +467 -0
  133. dataplat-0.1.0/tests/services/db/test_role_admin.py +484 -0
  134. dataplat-0.1.0/tests/services/db/test_role_dialects.py +389 -0
  135. dataplat-0.1.0/tests/services/db/test_targets.py +96 -0
  136. dataplat-0.1.0/tests/services/db/test_top_tables.py +126 -0
  137. dataplat-0.1.0/tests/services/superset/__init__.py +0 -0
  138. dataplat-0.1.0/tests/services/superset/test_client.py +46 -0
  139. dataplat-0.1.0/uv.lock +619 -0
@@ -0,0 +1,31 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["**"]
6
+ pull_request:
7
+
8
+ jobs:
9
+ checks:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Setup uv
16
+ uses: astral-sh/setup-uv@v5
17
+
18
+ - name: Setup Python
19
+ run: uv python install 3.13
20
+
21
+ - name: Install dependencies
22
+ run: uv sync --group dev --all-extras
23
+
24
+ - name: Ruff
25
+ run: uv run ruff check .
26
+
27
+ - name: MyPy
28
+ run: uv run mypy dataplat
29
+
30
+ - name: Pytest
31
+ run: uv run pytest
@@ -0,0 +1,58 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["[0-9]*.[0-9]*.[0-9]*"]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout
12
+ uses: actions/checkout@v4
13
+
14
+ - name: Setup uv
15
+ uses: astral-sh/setup-uv@v5
16
+
17
+ - name: Build sdist and wheel
18
+ run: uv build
19
+
20
+ - name: Upload artifacts
21
+ uses: actions/upload-artifact@v4
22
+ with:
23
+ name: dist
24
+ path: dist/
25
+
26
+ publish:
27
+ needs: build
28
+ runs-on: ubuntu-latest
29
+ environment: pypi
30
+ permissions:
31
+ id-token: write # PyPI Trusted Publishing (OIDC)
32
+ steps:
33
+ - name: Download artifacts
34
+ uses: actions/download-artifact@v4
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+
39
+ - name: Publish to PyPI
40
+ uses: pypa/gh-action-pypi-publish@release/v1
41
+
42
+ github-release:
43
+ needs: publish
44
+ runs-on: ubuntu-latest
45
+ permissions:
46
+ contents: write
47
+ steps:
48
+ - name: Download artifacts
49
+ uses: actions/download-artifact@v4
50
+ with:
51
+ name: dist
52
+ path: dist/
53
+
54
+ - name: Create GitHub release
55
+ uses: softprops/action-gh-release@v2
56
+ with:
57
+ files: dist/*
58
+ generate_release_notes: true
@@ -0,0 +1,212 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
208
+ .github/runner
209
+ local/
210
+
211
+ # Superpowers scratch (plans, specs) — not tracked in this repo.
212
+ docs/superpowers/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ Initial public release.
6
+
7
+ - Optional per-area dependency extras (`dataplat[db,ingest,bi,cloud,all]`)
8
+ with auto-detection: `dp config sync` installs what your enabled areas
9
+ need, and hitting a stubbed area offers to install its extra and re-run
10
+ your command.
11
+
12
+ - `dp` command with areas per component type: `db`, `ingest` (Airbyte),
13
+ `bi` (Superset), `cloud` (AWS), `ci` (GitHub runners), plus `status`,
14
+ `open`, and `config`.
15
+ - Fully config-driven database targets via `DP_TARGETS` and per-target
16
+ `<NAME>_*` environment variables (Postgres and Redshift engines).
17
+ - `.envrc` loading with a global config link (`dp config init`).
dataplat-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hans Lemm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,326 @@
1
+ Metadata-Version: 2.4
2
+ Name: dataplat
3
+ Version: 0.1.0
4
+ Summary: One command to manage any shape of data platform: databases, ingestion, BI, cloud, and CI.
5
+ Project-URL: Homepage, https://github.com/hanslemm/dataplat
6
+ Project-URL: Repository, https://github.com/hanslemm/dataplat
7
+ Project-URL: Issues, https://github.com/hanslemm/dataplat/issues
8
+ Project-URL: Changelog, https://github.com/hanslemm/dataplat/blob/main/CHANGELOG.md
9
+ Author: Hans Lemm
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: airbyte,aws,cli,data-platform,dbt,postgres,redshift,superset
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: System Administrators
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Database
20
+ Classifier: Topic :: System :: Systems Administration
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.13
23
+ Requires-Dist: rich>=14.2.0
24
+ Requires-Dist: typer>=0.21.1
25
+ Provides-Extra: all
26
+ Requires-Dist: boto3>=1.35.0; extra == 'all'
27
+ Requires-Dist: croniter>=2.0.0; extra == 'all'
28
+ Requires-Dist: httpx>=0.25.0; extra == 'all'
29
+ Requires-Dist: plotext>=5.3.2; extra == 'all'
30
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == 'all'
31
+ Requires-Dist: textual>=0.64.0; extra == 'all'
32
+ Provides-Extra: bi
33
+ Requires-Dist: httpx>=0.25.0; extra == 'bi'
34
+ Provides-Extra: cloud
35
+ Requires-Dist: boto3>=1.35.0; extra == 'cloud'
36
+ Requires-Dist: plotext>=5.3.2; extra == 'cloud'
37
+ Provides-Extra: db
38
+ Requires-Dist: psycopg[binary]>=3.2.9; extra == 'db'
39
+ Provides-Extra: ingest
40
+ Requires-Dist: croniter>=2.0.0; extra == 'ingest'
41
+ Requires-Dist: httpx>=0.25.0; extra == 'ingest'
42
+ Requires-Dist: textual>=0.64.0; extra == 'ingest'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # dataplat
46
+
47
+ **One command to manage any shape of data platform.**
48
+
49
+ `dataplat` ships a single CLI, `dp`, with an area for each type of component
50
+ in a data platform: warehouses/databases, ingestion, BI, cloud, and CI. Point
51
+ it at *your* stack through environment variables — nothing about your
52
+ infrastructure is hardcoded.
53
+
54
+ ```text
55
+ dp
56
+ ├── status # one-shot health overview (--json, --no-aws)
57
+ ├── open # airbyte | superset | rds [id] | redshift | secrets [name]
58
+ ├── config # init | show | doctor [--connect]
59
+ ├── db # warehouses & databases (Postgres, Redshift)
60
+ │ ├── query # ad-hoc SQL (--format table|csv|json, --write guard)
61
+ │ ├── describe # schema/table/view report (--json)
62
+ │ ├── long-queries # triage per target (--history, --json)
63
+ │ ├── kill # cancel/terminate queries by PID
64
+ │ ├── role # list | show | create | drop
65
+ │ ├── top-tables # rank big tables (--drop-sql, --drop)
66
+ │ └── dbt-orphans # scan/rename | revert | purge (--older-than)
67
+ ├── ingest # data ingestion
68
+ │ └── airbyte
69
+ │ ├── connections # list | get | create | update | set-cursor
70
+ │ │ # sync | refresh | reset | delete
71
+ │ ├── jobs # list | get | cancel
72
+ │ ├── sources # list | get | create | update | delete
73
+ │ ├── destinations # list | get | create | update | delete
74
+ │ ├── definitions # list-sources | list-destinations
75
+ │ ├── workspaces # list | get
76
+ │ ├── tags # list | create
77
+ │ └── templates # source | destination | connection
78
+ ├── bi # business intelligence
79
+ │ └── superset
80
+ │ ├── users # list | create | update | delete
81
+ │ ├── roles # list
82
+ │ └── groups # list
83
+ ├── cloud # cloud providers
84
+ │ └── aws
85
+ │ ├── secrets # list | get | compare | set | edit | rename-key
86
+ │ │ # describe | versions | rollback | delete | restore
87
+ │ ├── rds # metrics | plot | list
88
+ │ └── redshift # metrics
89
+ └── ci # build infrastructure
90
+ └── github
91
+ └── runner # start | stop | status
92
+ ```
93
+
94
+ ## Installation
95
+
96
+ ```bash
97
+ uv tool install "dataplat[all]" # recommended: everything
98
+ # or
99
+ pipx install "dataplat[all]"
100
+ # or
101
+ pip install "dataplat[all]"
102
+ ```
103
+
104
+ Each area's dependencies are an optional extra, so you can also install
105
+ only what your platform uses:
106
+
107
+ | Extra | Enables | Pulls in |
108
+ | --- | --- | --- |
109
+ | `db` | `dp db` | psycopg |
110
+ | `ingest` | `dp ingest` | httpx, textual, croniter |
111
+ | `bi` | `dp bi` | httpx |
112
+ | `cloud` | `dp cloud` | boto3, plotext |
113
+ | `all` | everything | all of the above |
114
+
115
+ A bare `pip install dataplat` gives you the core (`status`, `open`,
116
+ `config`) with every other area stubbed. You don't have to plan this in
117
+ advance: `dp` knows which areas your configuration enables and installs
118
+ what's missing on demand — see below.
119
+
120
+ ## Auto-installing dependencies
121
+
122
+ Two ways, both of which detect whether `dp` runs from a uv tool, pipx, or
123
+ plain-venv install and use the matching installer:
124
+
125
+ ```bash
126
+ dp config sync # detect enabled areas, install missing deps (confirms)
127
+ dp config sync --check # report only; exit 1 if something is missing (CI-friendly)
128
+ ```
129
+
130
+ Or just use a command: if your config enables an area whose extra is
131
+ missing, `dp db query ...` shows exactly what it will run, asks, installs,
132
+ and re-runs your original command. Non-interactive sessions never install
133
+ silently — they print the command and exit instead. `dp config doctor`
134
+ also reports per-area dependency status.
135
+
136
+ ## Quick start
137
+
138
+ 1. Declare your database targets — any names you like:
139
+
140
+ ```bash
141
+ # ~/.envrc (or any env mechanism you prefer)
142
+ export DP_TARGETS="warehouse,lake"
143
+ export DP_DEFAULT_TARGET="warehouse"
144
+
145
+ export WAREHOUSE_ENGINE=postgresql
146
+ export WAREHOUSE_HOST=db.example.com
147
+ export WAREHOUSE_DATABASE=analytics
148
+ export WAREHOUSE_USER=me
149
+ export WAREHOUSE_PASSWORD=…
150
+
151
+ export LAKE_ENGINE=redshift
152
+ export LAKE_HOST=lake.abc123.eu-central-1.redshift-serverless.amazonaws.com
153
+ export LAKE_DATABASE=dev
154
+ export LAKE_USER=me
155
+ export LAKE_PASSWORD=…
156
+ export LAKE_REASSIGN_OWNER=admin # role drop reassigns owned objects here
157
+ ```
158
+
159
+ 2. Optionally link that file globally and check your setup:
160
+
161
+ ```bash
162
+ dp config init --envrc ~/.envrc # set the global link
163
+ dp config show # which .envrc is active, what's set
164
+ dp config doctor --connect # validate config; probe live systems
165
+ ```
166
+
167
+ 3. Go:
168
+
169
+ ```bash
170
+ dp status
171
+ dp db query 'SELECT 1'
172
+ dp db query -t lake 'SELECT 1'
173
+ ```
174
+
175
+ ## Environment loading
176
+
177
+ `dp` loads variables from `.envrc` on startup without overriding values
178
+ already set in your shell. Lookup order:
179
+
180
+ 1. `DP_ENVRC_PATH`
181
+ 2. `~/.config/dataplat/.envrc` (the global link — set it with `dp config init`)
182
+ 3. `.envrc` in the current directory
183
+
184
+ ## Configuration reference
185
+
186
+ | Variable | Purpose |
187
+ | --- | --- |
188
+ | `DP_TARGETS` | Comma-separated DB target names (e.g. `warehouse,lake`). |
189
+ | `DP_DEFAULT_TARGET` | Target used when `--target` is omitted (default: first of `DP_TARGETS`). |
190
+ | `<NAME>_ENGINE` | `postgresql` (default) or `redshift`, per target. |
191
+ | `<NAME>_HOST/_PORT/_USER/_PASSWORD/_DATABASE/_SSLMODE` | Connection settings, per target. |
192
+ | `<NAME>_REASSIGN_OWNER` | Default owner for `dp db role drop` ownership transfer. |
193
+ | `AIRBYTE_BASE_URL` + `AIRBYTE_CLIENT_ID`/`AIRBYTE_CLIENT_SECRET` (cloud) or `AIRBYTE_EMAIL`/`AIRBYTE_PASSWORD` (OSS) | Airbyte API access. |
194
+ | `SUPERSET_BASE_URL`, `SUPERSET_ADMIN_USERNAME`, `SUPERSET_ADMIN_PASSWORD` | Superset API access. |
195
+ | `DP_AWS_PROFILE` | Default AWS profile for `dp cloud aws` commands. |
196
+ | `DP_AWS_PROFILE_ALIASES` | Short aliases, e.g. `prod=AdminAccess-Prod,qa=AdminAccess-QA`. |
197
+ | `DP_AWS_REGION` | Default AWS region (falls back to `AWS_REGION`, then the profile). |
198
+ | `DP_RDS_INSTANCE` | Default RDS instance for `dp cloud aws rds` / `dp status`. |
199
+ | `DP_DBT_PROJECT` | dbt project name — required for `dp db dbt-orphans`. |
200
+ | `DP_DBT_INVOCATION_COMMAND` | Optional filter on dbt_artifacts invocations. |
201
+ | `DP_DBT_ORPHANS_EXCLUDE_SCHEMAS` | Comma-separated schemas to skip (default `raw,_raw,dbt_artifacts`). |
202
+ | `GHA_APP_ID`, `GHA_APP_PRIVATE_KEY` | GitHub App creds for `dp ci github runner`. |
203
+ | `DP_CI_RUNNER_DNS` | Comma-separated DNS servers for the runner container. |
204
+
205
+ ## Conventions
206
+
207
+ - **`-t/--target`** — named DB target from `DP_TARGETS`. Multi-target
208
+ commands accept `all`. Sets the engine and env prefix in one flag;
209
+ `--engine` / `--env-prefix` remain as overrides.
210
+ - **`--json`** — every read command can emit machine-readable output.
211
+ - **`--yes/-y`** — every destructive or bulk-mutating command confirms first;
212
+ pass `--yes` in scripts. Bulk mutators also support `--dry-run`.
213
+ - **`--limit/-n`** — row caps share one spelling everywhere.
214
+ - **Secrets stay off argv** — prefer `--value-stdin` / hidden prompts; values
215
+ are never echoed back.
216
+
217
+ ## Examples
218
+
219
+ ### Daily overview
220
+
221
+ ```bash
222
+ dp status # DBs, Airbyte jobs (24h), runners, RDS at a glance
223
+ dp open superset # jump to a web UI
224
+ ```
225
+
226
+ ### DB query
227
+
228
+ ```bash
229
+ dp db query 'SELECT 1' # default target
230
+ dp db query -t lake 'SELECT 1' # named target
231
+ dp db query --format csv -n 0 'SELECT ...' > out.csv
232
+ echo 'SELECT 1' | dp db query
233
+ dp db query --write 'UPDATE t SET x = 1' # writes need --write or a confirm
234
+ ```
235
+
236
+ ### Long queries and kill
237
+
238
+ ```bash
239
+ dp db long-queries # all targets: running + recent failures
240
+ dp db long-queries -t warehouse --history # pg_stat_statements aggregate
241
+ dp db kill 12345 -t warehouse # terminate a backend (confirms first)
242
+ ```
243
+
244
+ ### DB roles
245
+
246
+ ```bash
247
+ dp db role list --users-only
248
+ dp db role show alice -t lake --json
249
+ dp db role create svc_reporting --table-select reporting --databases analytics
250
+ dp db role create readers --no-login --table-select reporting # passwordless group role
251
+ dp db role create readers --no-login --grant-to alice,bob
252
+ dp db role drop old_user --all-databases --dry-run
253
+ ```
254
+
255
+ `list`, `create`, and `drop` work against both Postgres and Redshift targets.
256
+ `create` makes login roles with generated passwords by default; `--no-login`
257
+ creates a passwordless group-style role instead. `drop` transfers owned
258
+ objects to the target's `<NAME>_REASSIGN_OWNER` before `DROP USER`.
259
+
260
+ ### Cleanup
261
+
262
+ ```bash
263
+ dp db top-tables --schema-prefix dev_ -n 30
264
+ dp db top-tables --drop-sql > review.sql # emit a script
265
+ dp db dbt-orphans # dry-run scan (default)
266
+ dp db dbt-orphans --no-dry-run # apply renames (confirms)
267
+ dp db dbt-orphans purge --older-than 7 --no-dry-run
268
+ dp db dbt-orphans revert # undo from the audit log
269
+ ```
270
+
271
+ ### AWS secrets
272
+
273
+ ```bash
274
+ dp cloud aws secrets list --prefix /kubernetes
275
+ dp cloud aws secrets get /my/secret --key password
276
+ dp cloud aws secrets compare /my/secret -p prod -p qa
277
+ echo -n "hunter2" | dp cloud aws secrets set my/secret --value-stdin -p qa
278
+ dp cloud aws secrets versions my/secret
279
+ dp cloud aws secrets rollback my/secret # AWSCURRENT -> AWSPREVIOUS
280
+ ```
281
+
282
+ All writes show their targets and confirm (or `--yes`).
283
+
284
+ ### AWS monitoring
285
+
286
+ ```bash
287
+ dp cloud aws rds metrics --json
288
+ dp cloud aws rds plot -m cpu -m connections --hours 12
289
+ dp cloud aws redshift metrics -w my-workgroup
290
+ ```
291
+
292
+ ### Airbyte
293
+
294
+ ```bash
295
+ dp ingest airbyte connections list -w <workspace-id> --json
296
+ dp ingest airbyte connections sync -c <connection-id> --wait
297
+ dp ingest airbyte connections reset -c <connection-id>
298
+
299
+ # Move every date-based cursor to a date, across all connections from one source
300
+ dp ingest airbyte connections set-cursor --source-id <id> --to 2024-01-01 --dry-run
301
+ dp ingest airbyte connections set-cursor -c <connection-id> --to 2024-01-01 --yes
302
+
303
+ # xmin (Postgres transaction-id) cursors: set them directly
304
+ dp ingest airbyte connections set-cursor -c <connection-id> --xmin 0 --yes
305
+ ```
306
+
307
+ ## Development
308
+
309
+ ```bash
310
+ git clone https://github.com/hanslemm/dataplat
311
+ cd dataplat
312
+ uv sync --group dev --all-extras
313
+ uv run pytest
314
+ uv run ruff check .
315
+ uv run mypy dataplat
316
+ ```
317
+
318
+ ## Releasing
319
+
320
+ Tag `X.Y.Z` (bare semver, no `v` prefix) on `main`; GitHub Actions builds
321
+ and publishes to PyPI via Trusted Publishing. Commits follow
322
+ [Conventional Commits](https://www.conventionalcommits.org/).
323
+
324
+ ## License
325
+
326
+ [MIT](LICENSE)