getdx 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 (68) hide show
  1. getdx-0.1.0/.github/workflows/ci.yml +61 -0
  2. getdx-0.1.0/.github/workflows/publish.yml +33 -0
  3. getdx-0.1.0/.gitignore +18 -0
  4. getdx-0.1.0/.pre-commit-config.yaml +17 -0
  5. getdx-0.1.0/CHANGELOG.md +82 -0
  6. getdx-0.1.0/CONTRIBUTING.md +118 -0
  7. getdx-0.1.0/LICENSE +21 -0
  8. getdx-0.1.0/PKG-INFO +146 -0
  9. getdx-0.1.0/README.md +120 -0
  10. getdx-0.1.0/examples/01_web_api_basics.py +30 -0
  11. getdx-0.1.0/examples/02_entity_overview_and_relations.py +19 -0
  12. getdx-0.1.0/examples/03_manage_entities.py +32 -0
  13. getdx-0.1.0/examples/04_data_cloud_deployments.py +36 -0
  14. getdx-0.1.0/examples/05_data_cloud_incidents.py +33 -0
  15. getdx-0.1.0/examples/06_data_cloud_custom_data.py +45 -0
  16. getdx-0.1.0/examples/07_data_cloud_repo_groups.py +41 -0
  17. getdx-0.1.0/examples/08_env_vars_and_combined_client.py +23 -0
  18. getdx-0.1.0/pyproject.toml +95 -0
  19. getdx-0.1.0/scripts/generate_from_openapi.py +439 -0
  20. getdx-0.1.0/specs/dx_data_cloud_api_openapi.json +1410 -0
  21. getdx-0.1.0/specs/dx_web_api_openapi.json +2344 -0
  22. getdx-0.1.0/src/getdx/__init__.py +51 -0
  23. getdx-0.1.0/src/getdx/client.py +71 -0
  24. getdx-0.1.0/src/getdx/config.py +95 -0
  25. getdx-0.1.0/src/getdx/data_cloud/__init__.py +4 -0
  26. getdx-0.1.0/src/getdx/data_cloud/client.py +301 -0
  27. getdx-0.1.0/src/getdx/data_cloud/operations.py +319 -0
  28. getdx-0.1.0/src/getdx/data_cloud/services/__init__.py +28 -0
  29. getdx-0.1.0/src/getdx/data_cloud/services/ai_tool_metrics.py +60 -0
  30. getdx-0.1.0/src/getdx/data_cloud/services/custom_data.py +137 -0
  31. getdx-0.1.0/src/getdx/data_cloud/services/deployments.py +68 -0
  32. getdx-0.1.0/src/getdx/data_cloud/services/incidents.py +46 -0
  33. getdx-0.1.0/src/getdx/data_cloud/services/pipeline_runs.py +58 -0
  34. getdx-0.1.0/src/getdx/data_cloud/services/repo_groups.py +132 -0
  35. getdx-0.1.0/src/getdx/errors.py +77 -0
  36. getdx-0.1.0/src/getdx/helpers.py +20 -0
  37. getdx-0.1.0/src/getdx/http/__init__.py +3 -0
  38. getdx-0.1.0/src/getdx/http/retry.py +49 -0
  39. getdx-0.1.0/src/getdx/http/transport.py +135 -0
  40. getdx-0.1.0/src/getdx/py.typed +0 -0
  41. getdx-0.1.0/src/getdx/types.py +12 -0
  42. getdx-0.1.0/src/getdx/web/__init__.py +12 -0
  43. getdx-0.1.0/src/getdx/web/aggregates.py +165 -0
  44. getdx-0.1.0/src/getdx/web/client.py +55 -0
  45. getdx-0.1.0/src/getdx/web/operations.py +822 -0
  46. getdx-0.1.0/src/getdx/web/services/__init__.py +52 -0
  47. getdx-0.1.0/src/getdx/web/services/entities.py +201 -0
  48. getdx-0.1.0/src/getdx/web/services/entity_relations.py +38 -0
  49. getdx-0.1.0/src/getdx/web/services/entity_types.py +133 -0
  50. getdx-0.1.0/src/getdx/web/services/events.py +36 -0
  51. getdx-0.1.0/src/getdx/web/services/initiatives.py +74 -0
  52. getdx-0.1.0/src/getdx/web/services/orgfiles.py +113 -0
  53. getdx-0.1.0/src/getdx/web/services/platformx.py +56 -0
  54. getdx-0.1.0/src/getdx/web/services/queries.py +31 -0
  55. getdx-0.1.0/src/getdx/web/services/scorecards.py +121 -0
  56. getdx-0.1.0/src/getdx/web/services/snapshots.py +93 -0
  57. getdx-0.1.0/src/getdx/web/services/teams.py +94 -0
  58. getdx-0.1.0/src/getdx/web/services/user_groups.py +123 -0
  59. getdx-0.1.0/src/getdx/web/services/users.py +77 -0
  60. getdx-0.1.0/src/getdx/web/services/workflow_runs.py +121 -0
  61. getdx-0.1.0/tests/integration/test_aggregates.py +75 -0
  62. getdx-0.1.0/tests/integration/test_client_flow.py +60 -0
  63. getdx-0.1.0/tests/integration/test_data_cloud_flow.py +68 -0
  64. getdx-0.1.0/tests/live/test_smoke_live.py +65 -0
  65. getdx-0.1.0/tests/unit/test_config.py +29 -0
  66. getdx-0.1.0/tests/unit/test_generated_surface.py +58 -0
  67. getdx-0.1.0/tests/unit/test_transport.py +78 -0
  68. getdx-0.1.0/uv.lock +727 -0
@@ -0,0 +1,61 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint, Format & Type-check
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v4
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: uv sync --dev
23
+
24
+ - name: Check formatting
25
+ run: uv run ruff format --check src/ tests/
26
+
27
+ - name: Lint
28
+ run: uv run ruff check src/ tests/
29
+
30
+ - name: Type check
31
+ run: uv run mypy src/
32
+
33
+ test:
34
+ name: Test (Python ${{ matrix.python-version }})
35
+ runs-on: ubuntu-latest
36
+ strategy:
37
+ fail-fast: false
38
+ matrix:
39
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
40
+
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+
44
+ - name: Install uv
45
+ uses: astral-sh/setup-uv@v4
46
+ with:
47
+ python-version: ${{ matrix.python-version }}
48
+
49
+ - name: Install dependencies
50
+ run: uv sync --dev
51
+
52
+ - name: Run tests with coverage
53
+ run: uv run pytest
54
+
55
+ - name: Upload coverage artifact
56
+ if: matrix.python-version == '3.12'
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: coverage-xml
60
+ path: coverage.xml
61
+ if-no-files-found: ignore
@@ -0,0 +1,33 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ name: Build and publish to PyPI
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write
15
+ contents: read
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Install uv
22
+ uses: astral-sh/setup-uv@v4
23
+
24
+ - name: Set up Python 3.12
25
+ run: uv python install 3.12
26
+
27
+ - name: Build package
28
+ run: uv build
29
+
30
+ - name: Publish to PyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
32
+ with:
33
+ packages-dir: dist/
getdx-0.1.0/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ __pycache__/
2
+ .pytest_cache/
3
+ .ruff_cache/
4
+ .venv/
5
+ *.pyc
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ .env
10
+ .mypy_cache/
11
+ .coverage
12
+ coverage.xml
13
+ htmlcov/
14
+ .claude/
15
+ .omc/
16
+
17
+ # Local-only readiness checklist
18
+ TODO.md
@@ -0,0 +1,17 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v4.6.0
11
+ hooks:
12
+ - id: trailing-whitespace
13
+ - id: end-of-file-fixer
14
+ - id: check-yaml
15
+ - id: check-toml
16
+ - id: check-merge-conflict
17
+ - id: check-added-large-files
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-05-21
11
+
12
+ ### Added
13
+
14
+ #### Core client
15
+ - `DXClient` — top-level sync client exposing `web` and `data_cloud` namespaces via a context-manager interface.
16
+ - `DXWebConfig` and `DXDataCloudConfig` — frozen dataclass configuration objects for each API.
17
+ - `DXClientConfig` — composite config for passing both configs together.
18
+ - `DXClientNotConfiguredError` raised when an unconfigured namespace is accessed.
19
+
20
+ #### DX Web API client (`client.web`)
21
+ - `entities` — list, info, scorecards, and tasks operations.
22
+ - `entity_relations` — list entity relationships with cursor-based pagination.
23
+ - `entity_types` — entity type listing.
24
+ - `scorecards` — scorecard listing and detail operations.
25
+ - `teams` — team listing and detail operations.
26
+ - `users` — user listing and detail operations.
27
+ - `user_groups` — user group operations.
28
+ - `events` — event ingestion and listing.
29
+ - `initiatives` — initiative listing and detail operations.
30
+ - `orgfiles` — org file operations.
31
+ - `platformx` — PlatformX operations.
32
+ - `queries` — query execution operations.
33
+ - `snapshots` — snapshot operations.
34
+ - `workflow_runs` — workflow run operations.
35
+ - `aggregates` — higher-level helpers built on top of core services:
36
+ - `entity_overview(identifier)` — fetches entity info, scorecards, and tasks in a single call and returns an `EntityOverview` dataclass.
37
+ - `entity_relations(identifier, ...)` — fetches all pages of entity relations and returns an `EntityRelationsGraph` dataclass with resolved nodes and edges.
38
+
39
+ #### DX Data Cloud API client (`client.data_cloud`)
40
+ - `custom_data` — upsert and delete custom data records; convenience helpers `delete_by_id` and `delete_by_reference_key`.
41
+ - `deployments` — deployment record operations; convenience helpers `set_pull_services_by_github_pull_id` and `set_pull_services_by_repo_and_number`.
42
+ - `incidents` — incident record operations.
43
+ - `pipeline_runs` — pipeline run record operations.
44
+ - `repo_groups` — repository group get and upsert operations.
45
+ - `ai_tool_metrics` — AI tool metrics operations.
46
+
47
+ #### Error hierarchy
48
+ - `DXAPIError` — base exception for all SDK errors.
49
+ - `DXClientConfigurationError` — raised for invalid or incomplete client configuration.
50
+ - `DXClientNotConfiguredError` — raised when accessing a namespace that was not configured.
51
+ - `DXArgumentError` — raised for invalid arguments passed to SDK methods.
52
+ - `DXResponseError` — raised for HTTP error responses; carries `status_code`, `response_json`, and `response_text`.
53
+ - `DXTransportError` — raised for network-level transport failures.
54
+ - `DXAuthError` — raised on HTTP 401 responses.
55
+ - `DXPermissionError` — raised on HTTP 403 responses.
56
+ - `DXFeatureUnavailableError` — raised when a feature is not available for the account.
57
+ - `DXValidationError` — raised on HTTP 422 / request validation failures.
58
+ - `DXRateLimitError` — raised on HTTP 429; carries `retry_after_seconds` when the server provides a `Retry-After` header.
59
+ - `DXServerError` — raised on HTTP 5xx responses.
60
+
61
+ #### Retry and transport
62
+ - `RetryConfig` — frozen dataclass controlling `max_attempts`, exponential `backoff_base_seconds` / `backoff_max_seconds`, and the set of `retry_statuses` (default: 429, 500, 502, 503, 504).
63
+ - Automatic exponential back-off for GET requests; honours the `Retry-After` response header for rate-limit delays.
64
+ - Retries on `httpx.TransportError` for GET requests.
65
+
66
+ #### Auto-generated service wrappers
67
+ - Web API and Data Cloud API service modules generated from OpenAPI specs via `scripts/generate_from_openapi.py`.
68
+ - Regeneration script accepts `--api-name` and `--spec` arguments to target either API.
69
+
70
+ #### Packaging and typing
71
+ - `py.typed` marker included in the wheel (PEP 561 compliant; fully typed package).
72
+ - Supports Python 3.10, 3.11, 3.12, and 3.13.
73
+ - Runtime dependencies: `httpx>=0.27.0`, `typing-extensions>=4.12.0`.
74
+ - Built with `hatchling>=1.25.0`.
75
+
76
+ #### Environment variable fallbacks
77
+ - `DX_WEB_API_TOKEN` — fallback token for the Web API.
78
+ - `DX_DATA_CLOUD_TOKEN` — fallback token for the Data Cloud API.
79
+ - `DX_DATA_CLOUD_INSTANCE` — fallback instance name for the Data Cloud API base URL.
80
+
81
+ [Unreleased]: https://github.com/priiiiit/dx-python/compare/v0.1.0...HEAD
82
+ [0.1.0]: https://github.com/priiiiit/dx-python/releases/tag/v0.1.0
@@ -0,0 +1,118 @@
1
+ # Contributing to getdx
2
+
3
+ Thank you for your interest in contributing! This guide covers everything you need to get started.
4
+
5
+ ## Development Setup
6
+
7
+ This project uses [uv](https://docs.astral.sh/uv/) for dependency management.
8
+
9
+ ```bash
10
+ # Clone the repository
11
+ git clone https://github.com/priiiiit/dx-python.git
12
+ cd dx-python
13
+
14
+ # Install all dependencies including dev extras
15
+ uv sync --dev
16
+ ```
17
+
18
+ **Requirements:** Python 3.10+
19
+
20
+ ## Project Structure
21
+
22
+ ```
23
+ src/getdx/ # Package source code
24
+ tests/ # Test suite
25
+ scripts/ # Code generation and other utilities
26
+ specs/ # OpenAPI specifications
27
+ ```
28
+
29
+ ## Running Tests
30
+
31
+ ```bash
32
+ uv run pytest
33
+ ```
34
+
35
+ Tests use [pytest-httpx](https://github.com/Colin-b/pytest-httpx) to mock HTTP interactions. Please add tests for any new functionality or bug fixes.
36
+
37
+ Optional live smoke tests (require real API credentials):
38
+
39
+ ```bash
40
+ RUN_LIVE_DX_TESTS=1 uv run pytest tests/live -q
41
+ ```
42
+
43
+ ## Code Style
44
+
45
+ This project uses [ruff](https://docs.astral.sh/ruff/) for formatting and linting (line length: 100).
46
+
47
+ ```bash
48
+ # Format code
49
+ uv run ruff format .
50
+
51
+ # Lint code
52
+ uv run ruff check .
53
+
54
+ # Auto-fix lint issues where possible
55
+ uv run ruff check --fix .
56
+ ```
57
+
58
+ Please ensure your code passes both format and lint checks before opening a pull request.
59
+
60
+ ### Pre-commit hooks
61
+
62
+ Install [pre-commit](https://pre-commit.com/) hooks so format, lint, and basic
63
+ file-hygiene checks run automatically on every commit:
64
+
65
+ ```bash
66
+ uv run pre-commit install
67
+ ```
68
+
69
+ You can run all hooks against the full tree on demand:
70
+
71
+ ```bash
72
+ uv run pre-commit run --all-files
73
+ ```
74
+
75
+ ### Type checking
76
+
77
+ This project is fully typed (`py.typed`). Type checks must pass on `src/`:
78
+
79
+ ```bash
80
+ uv run mypy src/
81
+ ```
82
+
83
+ ## Auto-Generated API Services
84
+
85
+ The service wrappers for the DX Web API and DX Data Cloud API are **auto-generated** from OpenAPI specifications via `scripts/generate_from_openapi.py`. Do not hand-edit these files — any manual changes will be overwritten the next time code generation runs.
86
+
87
+ To regenerate the API wrappers after updating a spec:
88
+
89
+ ```bash
90
+ # Regenerate from the DX Web API spec
91
+ uv run python scripts/generate_from_openapi.py --api-name web --spec specs/dx_web_api_openapi.json
92
+
93
+ # Regenerate from the DX Data Cloud API spec
94
+ uv run python scripts/generate_from_openapi.py --api-name data_cloud --spec specs/dx_data_cloud_api_openapi.json
95
+ ```
96
+
97
+ If you need to change the structure or behavior of the generated code, modify the generator script rather than the generated output.
98
+
99
+ ## Building the Package
100
+
101
+ ```bash
102
+ uv build
103
+ ```
104
+
105
+ ## Pull Request Process
106
+
107
+ 1. Fork the repository and create a branch from `main`.
108
+ 2. Make your changes, following the code style guidelines above.
109
+ 3. Add or update tests as appropriate.
110
+ 4. Ensure all checks pass:
111
+ ```bash
112
+ uv run ruff format .
113
+ uv run ruff check .
114
+ uv run pytest
115
+ ```
116
+ 5. Open a pull request against `main` with a clear description of what changed and why.
117
+
118
+ For significant changes, consider opening an issue first to discuss the approach before investing time in implementation.
getdx-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Priit Pihus
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.
getdx-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: getdx
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the DX Web and DX Data Cloud APIs
5
+ Project-URL: Homepage, https://github.com/priiiiit/dx-python
6
+ Project-URL: Repository, https://github.com/priiiiit/dx-python
7
+ Project-URL: Issues, https://github.com/priiiiit/dx-python/issues
8
+ Project-URL: Documentation, https://docs.getdx.com
9
+ Author: Priit Pihus
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,client,data,developer experience,devex,dx,engineering metrics,sdk
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: httpx>=0.27.0
24
+ Requires-Dist: typing-extensions>=4.12.0
25
+ Description-Content-Type: text/markdown
26
+
27
+ # getdx
28
+
29
+ [![PyPI version](https://img.shields.io/pypi/v/getdx.svg)](https://pypi.org/project/getdx/)
30
+ [![Python versions](https://img.shields.io/pypi/pyversions/getdx.svg)](https://pypi.org/project/getdx/)
31
+ [![CI](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml/badge.svg)](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml)
32
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
33
+
34
+ Sync-first Python SDK covering both DX APIs:
35
+ - DX Web API (`https://api.getdx.com`)
36
+ - DX Data Cloud API (`https://{instance}.getdx.net/api`)
37
+
38
+ This SDK does not cache API responses. Each call fetches fresh data.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install getdx
44
+ ```
45
+
46
+ Requires Python 3.10+.
47
+
48
+ ## Quickstart
49
+
50
+ ### Web API only
51
+ ```python
52
+ from getdx import DXClient, DXWebConfig
53
+
54
+ with DXClient(web=DXWebConfig(token="<DX_WEB_API_TOKEN>")) as client:
55
+ entities = client.web.entities.list(limit=10)
56
+ overview = client.web.aggregates.entity_overview("my-entity-id")
57
+ print(entities)
58
+ print(overview.tasks)
59
+ ```
60
+
61
+ ### Data Cloud API only
62
+ ```python
63
+ from getdx import DXClient, DXDataCloudConfig
64
+
65
+ with DXClient(
66
+ data_cloud=DXDataCloudConfig(
67
+ token="<DX_DATA_CLOUD_TOKEN>",
68
+ instance="yourinstance",
69
+ )
70
+ ) as client:
71
+ group = client.data_cloud.repo_groups.get(reference_id="frontend-team")
72
+ print(group)
73
+ ```
74
+
75
+ ### Both APIs in one client
76
+ ```python
77
+ from getdx import DXClient, DXDataCloudConfig, DXWebConfig
78
+
79
+ with DXClient(
80
+ web=DXWebConfig(token="<DX_WEB_API_TOKEN>"),
81
+ data_cloud=DXDataCloudConfig(token="<DX_DATA_CLOUD_TOKEN>", instance="yourinstance"),
82
+ ) as client:
83
+ web_entity = client.web.entities.info("entity-1")
84
+ repo_group = client.data_cloud.repo_groups.get(reference_id="frontend-team")
85
+ ```
86
+
87
+ ## Data Cloud convenience helpers
88
+ - `client.data_cloud.custom_data.delete_by_id(id)`
89
+ - `client.data_cloud.custom_data.delete_by_reference_key(reference, key)`
90
+ - `client.data_cloud.deployments.set_pull_services_by_github_pull_id(...)`
91
+ - `client.data_cloud.deployments.set_pull_services_by_repo_and_number(...)`
92
+
93
+ ## Optional namespace behavior
94
+ If `web` or `data_cloud` was not configured on `DXClient`, accessing that namespace raises
95
+ `DXClientNotConfiguredError`.
96
+
97
+ ## Environment variables
98
+ - `DX_WEB_API_TOKEN` for Web API token fallback
99
+ - `DX_DATA_CLOUD_TOKEN` for Data Cloud token fallback
100
+ - `DX_DATA_CLOUD_INSTANCE` for Data Cloud instance fallback
101
+
102
+ ## Development
103
+
104
+ Clone and install with `uv`:
105
+
106
+ ```bash
107
+ git clone https://github.com/priiiiit/dx-python.git
108
+ cd dx-python
109
+ uv sync --dev
110
+ ```
111
+
112
+ ### Regenerate API wrappers
113
+ Generated modules live under:
114
+ - `src/getdx/web/` (operations.py, services/)
115
+ - `src/getdx/data_cloud/` (operations.py, services/)
116
+
117
+ ```bash
118
+ uv run python scripts/generate_from_openapi.py \
119
+ --api-name web \
120
+ --spec specs/dx_web_api_openapi.json
121
+
122
+ uv run python scripts/generate_from_openapi.py \
123
+ --api-name data_cloud \
124
+ --spec specs/dx_data_cloud_api_openapi.json
125
+ ```
126
+
127
+ ### Testing and linting
128
+ ```bash
129
+ uv run ruff format .
130
+ uv run ruff check .
131
+ uv run pytest
132
+ ```
133
+
134
+ Optional live smoke tests:
135
+ ```bash
136
+ RUN_LIVE_DX_TESTS=1 uv run pytest tests/live -q
137
+ ```
138
+
139
+ For Data Cloud live smoke, set:
140
+ - `DX_DATA_CLOUD_TOKEN`
141
+ - `DX_DATA_CLOUD_INSTANCE`
142
+ - `DX_DATA_CLOUD_TEST_REFERENCE_ID`
143
+
144
+ ## License
145
+
146
+ MIT — see [LICENSE](LICENSE).
getdx-0.1.0/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # getdx
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/getdx.svg)](https://pypi.org/project/getdx/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/getdx.svg)](https://pypi.org/project/getdx/)
5
+ [![CI](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml/badge.svg)](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
8
+ Sync-first Python SDK covering both DX APIs:
9
+ - DX Web API (`https://api.getdx.com`)
10
+ - DX Data Cloud API (`https://{instance}.getdx.net/api`)
11
+
12
+ This SDK does not cache API responses. Each call fetches fresh data.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pip install getdx
18
+ ```
19
+
20
+ Requires Python 3.10+.
21
+
22
+ ## Quickstart
23
+
24
+ ### Web API only
25
+ ```python
26
+ from getdx import DXClient, DXWebConfig
27
+
28
+ with DXClient(web=DXWebConfig(token="<DX_WEB_API_TOKEN>")) as client:
29
+ entities = client.web.entities.list(limit=10)
30
+ overview = client.web.aggregates.entity_overview("my-entity-id")
31
+ print(entities)
32
+ print(overview.tasks)
33
+ ```
34
+
35
+ ### Data Cloud API only
36
+ ```python
37
+ from getdx import DXClient, DXDataCloudConfig
38
+
39
+ with DXClient(
40
+ data_cloud=DXDataCloudConfig(
41
+ token="<DX_DATA_CLOUD_TOKEN>",
42
+ instance="yourinstance",
43
+ )
44
+ ) as client:
45
+ group = client.data_cloud.repo_groups.get(reference_id="frontend-team")
46
+ print(group)
47
+ ```
48
+
49
+ ### Both APIs in one client
50
+ ```python
51
+ from getdx import DXClient, DXDataCloudConfig, DXWebConfig
52
+
53
+ with DXClient(
54
+ web=DXWebConfig(token="<DX_WEB_API_TOKEN>"),
55
+ data_cloud=DXDataCloudConfig(token="<DX_DATA_CLOUD_TOKEN>", instance="yourinstance"),
56
+ ) as client:
57
+ web_entity = client.web.entities.info("entity-1")
58
+ repo_group = client.data_cloud.repo_groups.get(reference_id="frontend-team")
59
+ ```
60
+
61
+ ## Data Cloud convenience helpers
62
+ - `client.data_cloud.custom_data.delete_by_id(id)`
63
+ - `client.data_cloud.custom_data.delete_by_reference_key(reference, key)`
64
+ - `client.data_cloud.deployments.set_pull_services_by_github_pull_id(...)`
65
+ - `client.data_cloud.deployments.set_pull_services_by_repo_and_number(...)`
66
+
67
+ ## Optional namespace behavior
68
+ If `web` or `data_cloud` was not configured on `DXClient`, accessing that namespace raises
69
+ `DXClientNotConfiguredError`.
70
+
71
+ ## Environment variables
72
+ - `DX_WEB_API_TOKEN` for Web API token fallback
73
+ - `DX_DATA_CLOUD_TOKEN` for Data Cloud token fallback
74
+ - `DX_DATA_CLOUD_INSTANCE` for Data Cloud instance fallback
75
+
76
+ ## Development
77
+
78
+ Clone and install with `uv`:
79
+
80
+ ```bash
81
+ git clone https://github.com/priiiiit/dx-python.git
82
+ cd dx-python
83
+ uv sync --dev
84
+ ```
85
+
86
+ ### Regenerate API wrappers
87
+ Generated modules live under:
88
+ - `src/getdx/web/` (operations.py, services/)
89
+ - `src/getdx/data_cloud/` (operations.py, services/)
90
+
91
+ ```bash
92
+ uv run python scripts/generate_from_openapi.py \
93
+ --api-name web \
94
+ --spec specs/dx_web_api_openapi.json
95
+
96
+ uv run python scripts/generate_from_openapi.py \
97
+ --api-name data_cloud \
98
+ --spec specs/dx_data_cloud_api_openapi.json
99
+ ```
100
+
101
+ ### Testing and linting
102
+ ```bash
103
+ uv run ruff format .
104
+ uv run ruff check .
105
+ uv run pytest
106
+ ```
107
+
108
+ Optional live smoke tests:
109
+ ```bash
110
+ RUN_LIVE_DX_TESTS=1 uv run pytest tests/live -q
111
+ ```
112
+
113
+ For Data Cloud live smoke, set:
114
+ - `DX_DATA_CLOUD_TOKEN`
115
+ - `DX_DATA_CLOUD_INSTANCE`
116
+ - `DX_DATA_CLOUD_TEST_REFERENCE_ID`
117
+
118
+ ## License
119
+
120
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,30 @@
1
+ """
2
+ Web API basics: listing entities, teams, scorecards, and initiatives.
3
+ """
4
+
5
+ from getdx import DXClient, DXWebConfig
6
+
7
+ with DXClient(web=DXWebConfig(token="<DX_WEB_API_TOKEN>")) as client:
8
+ # List all entities (first page)
9
+ entities = client.web.entities.list(limit=20)
10
+ print("Entities:", entities)
11
+
12
+ # Get details for a specific entity
13
+ entity = client.web.entities.info("my-service")
14
+ print("Entity:", entity)
15
+
16
+ # List all teams
17
+ teams = client.web.teams.list(limit=10)
18
+ print("Teams:", teams)
19
+
20
+ # Look up a team by reference ID
21
+ team = client.web.teams.info(reference_id="platform-team")
22
+ print("Team:", team)
23
+
24
+ # List all scorecards
25
+ scorecards = client.web.scorecards.list()
26
+ print("Scorecards:", scorecards)
27
+
28
+ # List published initiatives
29
+ initiatives = client.web.initiatives.list(published=True)
30
+ print("Initiatives:", initiatives)
@@ -0,0 +1,19 @@
1
+ """
2
+ Entity overview and relations graph using the aggregate helpers.
3
+ """
4
+
5
+ from getdx import DXClient, DXWebConfig
6
+
7
+ with DXClient(web=DXWebConfig(token="<DX_WEB_API_TOKEN>")) as client:
8
+ # Fetch entity info + scorecards + tasks in one call
9
+ overview = client.web.aggregates.entity_overview("checkout-service")
10
+ print("Entity:", overview.entity)
11
+ print("Open tasks:", overview.tasks)
12
+ print("Scorecards:", overview.scorecards)
13
+
14
+ # Build a full relations graph (auto-paginates)
15
+ graph = client.web.aggregates.entity_relations("checkout-service")
16
+ print(f"Nodes ({len(graph.nodes)}):", list(graph.nodes.keys()))
17
+ print(f"Edges ({len(graph.edges)}):")
18
+ for edge in graph.edges:
19
+ print(f" {edge['source']} -> {edge['target']}")