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.
- getdx-0.1.0/.github/workflows/ci.yml +61 -0
- getdx-0.1.0/.github/workflows/publish.yml +33 -0
- getdx-0.1.0/.gitignore +18 -0
- getdx-0.1.0/.pre-commit-config.yaml +17 -0
- getdx-0.1.0/CHANGELOG.md +82 -0
- getdx-0.1.0/CONTRIBUTING.md +118 -0
- getdx-0.1.0/LICENSE +21 -0
- getdx-0.1.0/PKG-INFO +146 -0
- getdx-0.1.0/README.md +120 -0
- getdx-0.1.0/examples/01_web_api_basics.py +30 -0
- getdx-0.1.0/examples/02_entity_overview_and_relations.py +19 -0
- getdx-0.1.0/examples/03_manage_entities.py +32 -0
- getdx-0.1.0/examples/04_data_cloud_deployments.py +36 -0
- getdx-0.1.0/examples/05_data_cloud_incidents.py +33 -0
- getdx-0.1.0/examples/06_data_cloud_custom_data.py +45 -0
- getdx-0.1.0/examples/07_data_cloud_repo_groups.py +41 -0
- getdx-0.1.0/examples/08_env_vars_and_combined_client.py +23 -0
- getdx-0.1.0/pyproject.toml +95 -0
- getdx-0.1.0/scripts/generate_from_openapi.py +439 -0
- getdx-0.1.0/specs/dx_data_cloud_api_openapi.json +1410 -0
- getdx-0.1.0/specs/dx_web_api_openapi.json +2344 -0
- getdx-0.1.0/src/getdx/__init__.py +51 -0
- getdx-0.1.0/src/getdx/client.py +71 -0
- getdx-0.1.0/src/getdx/config.py +95 -0
- getdx-0.1.0/src/getdx/data_cloud/__init__.py +4 -0
- getdx-0.1.0/src/getdx/data_cloud/client.py +301 -0
- getdx-0.1.0/src/getdx/data_cloud/operations.py +319 -0
- getdx-0.1.0/src/getdx/data_cloud/services/__init__.py +28 -0
- getdx-0.1.0/src/getdx/data_cloud/services/ai_tool_metrics.py +60 -0
- getdx-0.1.0/src/getdx/data_cloud/services/custom_data.py +137 -0
- getdx-0.1.0/src/getdx/data_cloud/services/deployments.py +68 -0
- getdx-0.1.0/src/getdx/data_cloud/services/incidents.py +46 -0
- getdx-0.1.0/src/getdx/data_cloud/services/pipeline_runs.py +58 -0
- getdx-0.1.0/src/getdx/data_cloud/services/repo_groups.py +132 -0
- getdx-0.1.0/src/getdx/errors.py +77 -0
- getdx-0.1.0/src/getdx/helpers.py +20 -0
- getdx-0.1.0/src/getdx/http/__init__.py +3 -0
- getdx-0.1.0/src/getdx/http/retry.py +49 -0
- getdx-0.1.0/src/getdx/http/transport.py +135 -0
- getdx-0.1.0/src/getdx/py.typed +0 -0
- getdx-0.1.0/src/getdx/types.py +12 -0
- getdx-0.1.0/src/getdx/web/__init__.py +12 -0
- getdx-0.1.0/src/getdx/web/aggregates.py +165 -0
- getdx-0.1.0/src/getdx/web/client.py +55 -0
- getdx-0.1.0/src/getdx/web/operations.py +822 -0
- getdx-0.1.0/src/getdx/web/services/__init__.py +52 -0
- getdx-0.1.0/src/getdx/web/services/entities.py +201 -0
- getdx-0.1.0/src/getdx/web/services/entity_relations.py +38 -0
- getdx-0.1.0/src/getdx/web/services/entity_types.py +133 -0
- getdx-0.1.0/src/getdx/web/services/events.py +36 -0
- getdx-0.1.0/src/getdx/web/services/initiatives.py +74 -0
- getdx-0.1.0/src/getdx/web/services/orgfiles.py +113 -0
- getdx-0.1.0/src/getdx/web/services/platformx.py +56 -0
- getdx-0.1.0/src/getdx/web/services/queries.py +31 -0
- getdx-0.1.0/src/getdx/web/services/scorecards.py +121 -0
- getdx-0.1.0/src/getdx/web/services/snapshots.py +93 -0
- getdx-0.1.0/src/getdx/web/services/teams.py +94 -0
- getdx-0.1.0/src/getdx/web/services/user_groups.py +123 -0
- getdx-0.1.0/src/getdx/web/services/users.py +77 -0
- getdx-0.1.0/src/getdx/web/services/workflow_runs.py +121 -0
- getdx-0.1.0/tests/integration/test_aggregates.py +75 -0
- getdx-0.1.0/tests/integration/test_client_flow.py +60 -0
- getdx-0.1.0/tests/integration/test_data_cloud_flow.py +68 -0
- getdx-0.1.0/tests/live/test_smoke_live.py +65 -0
- getdx-0.1.0/tests/unit/test_config.py +29 -0
- getdx-0.1.0/tests/unit/test_generated_surface.py +58 -0
- getdx-0.1.0/tests/unit/test_transport.py +78 -0
- 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,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
|
getdx-0.1.0/CHANGELOG.md
ADDED
|
@@ -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
|
+
[](https://pypi.org/project/getdx/)
|
|
30
|
+
[](https://pypi.org/project/getdx/)
|
|
31
|
+
[](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml)
|
|
32
|
+
[](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
|
+
[](https://pypi.org/project/getdx/)
|
|
4
|
+
[](https://pypi.org/project/getdx/)
|
|
5
|
+
[](https://github.com/priiiiit/dx-python/actions/workflows/ci.yml)
|
|
6
|
+
[](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']}")
|