harness-platform-sdk 1.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.
- harness_platform_sdk-1.0.0/PKG-INFO +209 -0
- harness_platform_sdk-1.0.0/README.md +169 -0
- harness_platform_sdk-1.0.0/pyproject.toml +142 -0
- harness_platform_sdk-1.0.0/setup.cfg +4 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/__init__.py +56 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/authz/__init__.py +15 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/authz/resource_groups.py +274 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/authz/role_assignments.py +274 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/authz/roles.py +271 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/base_model.py +17 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/client.py +1540 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/config.py +63 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/exceptions.py +68 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/__init__.py +19 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/workspace_approvals.py +293 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/workspace_default_pipelines.py +300 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/workspace_states.py +205 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/workspace_variables.py +341 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/iacm_api/workspaces.py +301 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/idp_api/__init__.py +15 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/idp_api/catalog_custom_properties.py +389 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/idp_api/entities.py +332 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/idp_api/scores.py +359 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/authz/__init__.py +23 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/authz/resource_groups.py +47 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/authz/role_assignments.py +37 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/authz/roles.py +43 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/__init__.py +44 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/workspace_approvals.py +82 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/workspace_default_pipelines.py +104 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/workspace_states.py +37 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/workspace_variables.py +87 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/iacm_api/workspaces.py +107 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/idp_api/__init__.py +31 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/idp_api/catalog_custom_properties.py +56 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/idp_api/entities.py +80 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/idp_api/scores.py +64 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/__init__.py +45 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/connectors.py +44 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/environments_v2.py +49 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/infrastructures.py +63 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/organizations.py +51 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/projects.py +55 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/secrets.py +45 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/service_overrides.py +78 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/services.py +55 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/user_groups.py +61 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/ng_api/variables.py +53 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/pipeline_api/__init__.py +20 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/pipeline_api/input_sets_v0.py +67 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/pipeline_api/pipelines_v0.py +76 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/pipeline_api/triggers_v0.py +98 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/template_api/__init__.py +11 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/models/template_api/templates_v0.py +59 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/__init__.py +29 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/connectors.py +269 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/environments_v2.py +314 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/infrastructures.py +378 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/organizations.py +269 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/projects.py +265 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/secrets.py +285 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/service_overrides.py +342 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/services.py +350 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/user_groups.py +270 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/ng_api/variables.py +312 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/pagination.py +19 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/pipeline_api/__init__.py +15 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/pipeline_api/input_sets_v0.py +377 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/pipeline_api/pipelines_v0.py +324 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/pipeline_api/triggers_v0.py +372 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/py.typed +0 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/scope.py +28 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/template_api/__init__.py +10 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk/template_api/templates_v0.py +576 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk.egg-info/PKG-INFO +209 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk.egg-info/SOURCES.txt +78 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk.egg-info/dependency_links.txt +1 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk.egg-info/requires.txt +20 -0
- harness_platform_sdk-1.0.0/src/harness_platform_sdk.egg-info/top_level.txt +1 -0
- harness_platform_sdk-1.0.0/tests/test_docstrings.py +150 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: harness-platform-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python SDK for the Harness Platform API
|
|
5
|
+
Author-email: Harness <platform@harness.io>
|
|
6
|
+
License-Expression: BUSL-1.1
|
|
7
|
+
Project-URL: Homepage, https://github.com/harness/harness-platform-sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/harness/harness-platform-sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/harness/harness-platform-sdk/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/harness/harness-platform-sdk/blob/main/CHANGELOG.md
|
|
11
|
+
Project-URL: Documentation, https://developer.harness.io/harness-solutions-factory/use-hsf/plugins/harness-platform-sdk
|
|
12
|
+
Project-URL: AI-Agent Docs, https://developer.harness.io/harness-solutions-factory/use-hsf/plugins/harness-platform-sdk/llms.md
|
|
13
|
+
Keywords: harness,api,sdk,iac
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: httpx>=0.25.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0
|
|
24
|
+
Requires-Dist: tenacity>=8.2.0
|
|
25
|
+
Requires-Dist: PyYAML==6.0.3
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-httpx>=0.21.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
30
|
+
Requires-Dist: Jinja2==3.1.6; extra == "dev"
|
|
31
|
+
Requires-Dist: pdoc3==0.11.6; extra == "dev"
|
|
32
|
+
Requires-Dist: black==26.5.1; extra == "dev"
|
|
33
|
+
Requires-Dist: isort==8.0.1; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy==1.20.2; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.16; extra == "dev"
|
|
36
|
+
Provides-Extra: publish
|
|
37
|
+
Requires-Dist: build>=1.0.0; extra == "publish"
|
|
38
|
+
Requires-Dist: twine>=5.0.0; extra == "publish"
|
|
39
|
+
Requires-Dist: wheel>=0.41.0; extra == "publish"
|
|
40
|
+
|
|
41
|
+
# Harness Platform SDK
|
|
42
|
+
|
|
43
|
+
A production-grade Python SDK for the Harness platform API. Built with Pydantic v2, httpx, and comprehensive test coverage.
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from harness_platform_sdk import HarnessClient
|
|
49
|
+
|
|
50
|
+
# Create a client
|
|
51
|
+
client = HarnessClient(
|
|
52
|
+
api_key="your-api-key",
|
|
53
|
+
account_id="your-account-id",
|
|
54
|
+
default_org="your-org",
|
|
55
|
+
default_project="your-project"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Use context manager for automatic cleanup
|
|
59
|
+
with client:
|
|
60
|
+
# Access resource APIs
|
|
61
|
+
orgs = client.organizations.list()
|
|
62
|
+
for org in orgs:
|
|
63
|
+
print(f"Organization: {org.identifier}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install harness-platform-sdk
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Architecture
|
|
73
|
+
|
|
74
|
+
### Core Modules
|
|
75
|
+
|
|
76
|
+
- **`HarnessClient`** — Main entry point for all API interactions
|
|
77
|
+
- HTTP methods with built-in retry (429, 503)
|
|
78
|
+
- Scope resolution (account/org/project)
|
|
79
|
+
- URL template substitution
|
|
80
|
+
- Pagination support (OFFSET and CURSOR styles)
|
|
81
|
+
|
|
82
|
+
- **`HarnessConfig`** — Configuration management
|
|
83
|
+
- API key, account ID, base URL
|
|
84
|
+
- Timeout, retry settings
|
|
85
|
+
- SSL verification control
|
|
86
|
+
|
|
87
|
+
- **`Scope`** — Request context model
|
|
88
|
+
- Frozen Pydantic model
|
|
89
|
+
- Account ID (required), org/project (optional)
|
|
90
|
+
|
|
91
|
+
- **Exception Hierarchy**
|
|
92
|
+
- `HarnessSdkError` — Base exception
|
|
93
|
+
- `ScopeNotSetError` — Missing required scope fields
|
|
94
|
+
- `ApiError` — Non-2xx responses (with status, body, headers)
|
|
95
|
+
- `AuthError` — 401/403 responses
|
|
96
|
+
|
|
97
|
+
- **`PaginationStyle`** — Pagination type enum
|
|
98
|
+
- `OFFSET` — pageIndex/pageSize pagination
|
|
99
|
+
- `CURSOR` — nextPageToken pagination
|
|
100
|
+
|
|
101
|
+
### Resource APIs
|
|
102
|
+
|
|
103
|
+
The SDK includes typed API wrappers for Harness platform resources across multiple domains:
|
|
104
|
+
|
|
105
|
+
- **Next-Gen (Core):** Organizations, Projects, Services, Service Overrides, Connectors, Secrets, Infrastructures, Variables, User Groups, Environments V2
|
|
106
|
+
- **Pipeline:** Pipelines (v0), Input Sets (v0), Triggers (v0), Templates (v0)
|
|
107
|
+
- **Authorization:** Roles, Resource Groups, Role Assignments
|
|
108
|
+
- **Infrastructure as Code:** Workspaces, Workspace Approvals, Workspace States, Workspace Variables, Workspace Default Pipelines
|
|
109
|
+
- **Internal Developer Portal:** Entities, Catalog Custom Properties, Scores
|
|
110
|
+
|
|
111
|
+
### Design Principles
|
|
112
|
+
|
|
113
|
+
1. **Single Entry Point** — All domain APIs are accessed via `HarnessClient`
|
|
114
|
+
2. **Scope Resolution** — Client automatically merges call-time and default scopes
|
|
115
|
+
3. **Type Safety** — Full Pydantic v2 models with validation
|
|
116
|
+
4. **Error Handling** — Explicit exception types with actionable messages
|
|
117
|
+
5. **Retry Logic** — Automatic retry on transient failures with exponential backoff
|
|
118
|
+
6. **No Async** — Pure sync using httpx (async support deferred to future version)
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from harness_platform_sdk import HarnessClient, HarnessConfig
|
|
124
|
+
|
|
125
|
+
# Option 1: Keyword arguments
|
|
126
|
+
client = HarnessClient(
|
|
127
|
+
api_key="key",
|
|
128
|
+
account_id="acc",
|
|
129
|
+
default_org="my-org"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Option 2: Explicit config
|
|
133
|
+
config = HarnessConfig(
|
|
134
|
+
api_key="key",
|
|
135
|
+
account_id="acc",
|
|
136
|
+
base_url="https://app.harness.io",
|
|
137
|
+
timeout=30.0,
|
|
138
|
+
max_retries=3,
|
|
139
|
+
retry_status_codes=[429, 503],
|
|
140
|
+
retry_enabled=True,
|
|
141
|
+
verify_ssl=True
|
|
142
|
+
)
|
|
143
|
+
client = HarnessClient(config=config)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Error Handling
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from harness_platform_sdk import HarnessClient, AuthError, ApiError
|
|
150
|
+
|
|
151
|
+
client = HarnessClient(api_key="key", account_id="acc")
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
result = client._get("/some/endpoint")
|
|
155
|
+
except AuthError as e:
|
|
156
|
+
print(f"Auth failed: {e.status_code}")
|
|
157
|
+
# Handle 401/403
|
|
158
|
+
except ApiError as e:
|
|
159
|
+
print(f"API error: {e.status_code}")
|
|
160
|
+
# Handle other non-2xx
|
|
161
|
+
finally:
|
|
162
|
+
client.close()
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Scope Management
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from harness_platform_sdk import HarnessClient, Scope
|
|
169
|
+
|
|
170
|
+
# Set default scope at construction
|
|
171
|
+
client = HarnessClient(
|
|
172
|
+
api_key="key",
|
|
173
|
+
account_id="acc",
|
|
174
|
+
default_org="org-1",
|
|
175
|
+
default_project="proj-1"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Update default scope
|
|
179
|
+
client.set_default_scope(org="org-2", project="proj-2")
|
|
180
|
+
|
|
181
|
+
# Override scope for a specific call (future: when domain APIs are added)
|
|
182
|
+
# resource_manager.get(resource_id, scope=Scope(account_id="acc", org="org-temp"))
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Contributing
|
|
186
|
+
|
|
187
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.
|
|
188
|
+
|
|
189
|
+
## Testing
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Run all tests
|
|
193
|
+
mise run tests
|
|
194
|
+
|
|
195
|
+
# Run with coverage report
|
|
196
|
+
mise run tests:cov
|
|
197
|
+
|
|
198
|
+
# Run specific test file
|
|
199
|
+
pytest tests/unit_tests/test_client.py -v
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Version
|
|
203
|
+
|
|
204
|
+
- **Current:** 1.0.0
|
|
205
|
+
- **Stability:** Production-ready (v1.0.0 release)
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
Business Source License 1.1 (BUSL-1.1) — See [License](License) for details.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Harness Platform SDK
|
|
2
|
+
|
|
3
|
+
A production-grade Python SDK for the Harness platform API. Built with Pydantic v2, httpx, and comprehensive test coverage.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from harness_platform_sdk import HarnessClient
|
|
9
|
+
|
|
10
|
+
# Create a client
|
|
11
|
+
client = HarnessClient(
|
|
12
|
+
api_key="your-api-key",
|
|
13
|
+
account_id="your-account-id",
|
|
14
|
+
default_org="your-org",
|
|
15
|
+
default_project="your-project"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Use context manager for automatic cleanup
|
|
19
|
+
with client:
|
|
20
|
+
# Access resource APIs
|
|
21
|
+
orgs = client.organizations.list()
|
|
22
|
+
for org in orgs:
|
|
23
|
+
print(f"Organization: {org.identifier}")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install harness-platform-sdk
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
### Core Modules
|
|
35
|
+
|
|
36
|
+
- **`HarnessClient`** — Main entry point for all API interactions
|
|
37
|
+
- HTTP methods with built-in retry (429, 503)
|
|
38
|
+
- Scope resolution (account/org/project)
|
|
39
|
+
- URL template substitution
|
|
40
|
+
- Pagination support (OFFSET and CURSOR styles)
|
|
41
|
+
|
|
42
|
+
- **`HarnessConfig`** — Configuration management
|
|
43
|
+
- API key, account ID, base URL
|
|
44
|
+
- Timeout, retry settings
|
|
45
|
+
- SSL verification control
|
|
46
|
+
|
|
47
|
+
- **`Scope`** — Request context model
|
|
48
|
+
- Frozen Pydantic model
|
|
49
|
+
- Account ID (required), org/project (optional)
|
|
50
|
+
|
|
51
|
+
- **Exception Hierarchy**
|
|
52
|
+
- `HarnessSdkError` — Base exception
|
|
53
|
+
- `ScopeNotSetError` — Missing required scope fields
|
|
54
|
+
- `ApiError` — Non-2xx responses (with status, body, headers)
|
|
55
|
+
- `AuthError` — 401/403 responses
|
|
56
|
+
|
|
57
|
+
- **`PaginationStyle`** — Pagination type enum
|
|
58
|
+
- `OFFSET` — pageIndex/pageSize pagination
|
|
59
|
+
- `CURSOR` — nextPageToken pagination
|
|
60
|
+
|
|
61
|
+
### Resource APIs
|
|
62
|
+
|
|
63
|
+
The SDK includes typed API wrappers for Harness platform resources across multiple domains:
|
|
64
|
+
|
|
65
|
+
- **Next-Gen (Core):** Organizations, Projects, Services, Service Overrides, Connectors, Secrets, Infrastructures, Variables, User Groups, Environments V2
|
|
66
|
+
- **Pipeline:** Pipelines (v0), Input Sets (v0), Triggers (v0), Templates (v0)
|
|
67
|
+
- **Authorization:** Roles, Resource Groups, Role Assignments
|
|
68
|
+
- **Infrastructure as Code:** Workspaces, Workspace Approvals, Workspace States, Workspace Variables, Workspace Default Pipelines
|
|
69
|
+
- **Internal Developer Portal:** Entities, Catalog Custom Properties, Scores
|
|
70
|
+
|
|
71
|
+
### Design Principles
|
|
72
|
+
|
|
73
|
+
1. **Single Entry Point** — All domain APIs are accessed via `HarnessClient`
|
|
74
|
+
2. **Scope Resolution** — Client automatically merges call-time and default scopes
|
|
75
|
+
3. **Type Safety** — Full Pydantic v2 models with validation
|
|
76
|
+
4. **Error Handling** — Explicit exception types with actionable messages
|
|
77
|
+
5. **Retry Logic** — Automatic retry on transient failures with exponential backoff
|
|
78
|
+
6. **No Async** — Pure sync using httpx (async support deferred to future version)
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from harness_platform_sdk import HarnessClient, HarnessConfig
|
|
84
|
+
|
|
85
|
+
# Option 1: Keyword arguments
|
|
86
|
+
client = HarnessClient(
|
|
87
|
+
api_key="key",
|
|
88
|
+
account_id="acc",
|
|
89
|
+
default_org="my-org"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Option 2: Explicit config
|
|
93
|
+
config = HarnessConfig(
|
|
94
|
+
api_key="key",
|
|
95
|
+
account_id="acc",
|
|
96
|
+
base_url="https://app.harness.io",
|
|
97
|
+
timeout=30.0,
|
|
98
|
+
max_retries=3,
|
|
99
|
+
retry_status_codes=[429, 503],
|
|
100
|
+
retry_enabled=True,
|
|
101
|
+
verify_ssl=True
|
|
102
|
+
)
|
|
103
|
+
client = HarnessClient(config=config)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Error Handling
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from harness_platform_sdk import HarnessClient, AuthError, ApiError
|
|
110
|
+
|
|
111
|
+
client = HarnessClient(api_key="key", account_id="acc")
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
result = client._get("/some/endpoint")
|
|
115
|
+
except AuthError as e:
|
|
116
|
+
print(f"Auth failed: {e.status_code}")
|
|
117
|
+
# Handle 401/403
|
|
118
|
+
except ApiError as e:
|
|
119
|
+
print(f"API error: {e.status_code}")
|
|
120
|
+
# Handle other non-2xx
|
|
121
|
+
finally:
|
|
122
|
+
client.close()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Scope Management
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from harness_platform_sdk import HarnessClient, Scope
|
|
129
|
+
|
|
130
|
+
# Set default scope at construction
|
|
131
|
+
client = HarnessClient(
|
|
132
|
+
api_key="key",
|
|
133
|
+
account_id="acc",
|
|
134
|
+
default_org="org-1",
|
|
135
|
+
default_project="proj-1"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Update default scope
|
|
139
|
+
client.set_default_scope(org="org-2", project="proj-2")
|
|
140
|
+
|
|
141
|
+
# Override scope for a specific call (future: when domain APIs are added)
|
|
142
|
+
# resource_manager.get(resource_id, scope=Scope(account_id="acc", org="org-temp"))
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Contributing
|
|
146
|
+
|
|
147
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.
|
|
148
|
+
|
|
149
|
+
## Testing
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Run all tests
|
|
153
|
+
mise run tests
|
|
154
|
+
|
|
155
|
+
# Run with coverage report
|
|
156
|
+
mise run tests:cov
|
|
157
|
+
|
|
158
|
+
# Run specific test file
|
|
159
|
+
pytest tests/unit_tests/test_client.py -v
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Version
|
|
163
|
+
|
|
164
|
+
- **Current:** 1.0.0
|
|
165
|
+
- **Stability:** Production-ready (v1.0.0 release)
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
Business Source License 1.1 (BUSL-1.1) — See [License](License) for details.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "harness-platform-sdk"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Python SDK for the Harness Platform API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "BUSL-1.1"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Harness", email = "platform@harness.io"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["harness", "api", "sdk", "iac"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
dependencies = [
|
|
26
|
+
"httpx>=0.25.0",
|
|
27
|
+
"pydantic>=2.0",
|
|
28
|
+
"tenacity>=8.2.0",
|
|
29
|
+
"PyYAML==6.0.3",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
dev = [
|
|
34
|
+
"pytest>=7.4.0",
|
|
35
|
+
"pytest-httpx>=0.21.0",
|
|
36
|
+
"pytest-cov>=4.1.0",
|
|
37
|
+
"Jinja2==3.1.6",
|
|
38
|
+
"pdoc3==0.11.6",
|
|
39
|
+
"black==26.5.1",
|
|
40
|
+
"isort==8.0.1",
|
|
41
|
+
"mypy==1.20.2",
|
|
42
|
+
"ruff>=0.16",
|
|
43
|
+
]
|
|
44
|
+
publish = [
|
|
45
|
+
"build>=1.0.0",
|
|
46
|
+
"twine>=5.0.0",
|
|
47
|
+
"wheel>=0.41.0",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Homepage = "https://github.com/harness/harness-platform-sdk"
|
|
52
|
+
Repository = "https://github.com/harness/harness-platform-sdk"
|
|
53
|
+
Issues = "https://github.com/harness/harness-platform-sdk/issues"
|
|
54
|
+
Changelog = "https://github.com/harness/harness-platform-sdk/blob/main/CHANGELOG.md"
|
|
55
|
+
Documentation = "https://developer.harness.io/harness-solutions-factory/use-hsf/plugins/harness-platform-sdk"
|
|
56
|
+
"AI-Agent Docs" = "https://developer.harness.io/harness-solutions-factory/use-hsf/plugins/harness-platform-sdk/llms.md"
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.packages.find]
|
|
59
|
+
where = ["src"]
|
|
60
|
+
|
|
61
|
+
[tool.setuptools.package-data]
|
|
62
|
+
harness_platform_sdk = ["py.typed"]
|
|
63
|
+
|
|
64
|
+
[tool.pytest.ini_options]
|
|
65
|
+
testpaths = ["tests"]
|
|
66
|
+
python_files = "test_*.py"
|
|
67
|
+
python_classes = "Test*"
|
|
68
|
+
python_functions = "test_*"
|
|
69
|
+
addopts = "-v --strict-markers"
|
|
70
|
+
markers = [
|
|
71
|
+
"unit: unit tests",
|
|
72
|
+
"integration: integration tests",
|
|
73
|
+
"regression: regression tests",
|
|
74
|
+
]
|
|
75
|
+
doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS"
|
|
76
|
+
|
|
77
|
+
[tool.coverage.run]
|
|
78
|
+
source = ["src/harness_platform_sdk"]
|
|
79
|
+
omit = [
|
|
80
|
+
"src/harness_platform_sdk/models/*",
|
|
81
|
+
"*/tests/*",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[tool.coverage.report]
|
|
85
|
+
exclude_lines = [
|
|
86
|
+
"pragma: no cover",
|
|
87
|
+
"def __repr__",
|
|
88
|
+
"raise AssertionError",
|
|
89
|
+
"raise NotImplementedError",
|
|
90
|
+
"if __name__ == .__main__.:",
|
|
91
|
+
"if TYPE_CHECKING:",
|
|
92
|
+
"^\\s*@abstractmethod",
|
|
93
|
+
]
|
|
94
|
+
fail_under = 85
|
|
95
|
+
precision = 2
|
|
96
|
+
|
|
97
|
+
[tool.black]
|
|
98
|
+
line-length = 100
|
|
99
|
+
target-version = ["py311"]
|
|
100
|
+
|
|
101
|
+
[tool.isort]
|
|
102
|
+
profile = "black"
|
|
103
|
+
line_length = 100
|
|
104
|
+
py_version = 311
|
|
105
|
+
|
|
106
|
+
[tool.mypy]
|
|
107
|
+
python_version = "3.11"
|
|
108
|
+
warn_return_any = false
|
|
109
|
+
warn_unused_configs = true
|
|
110
|
+
disallow_untyped_defs = false
|
|
111
|
+
ignore_missing_imports = true
|
|
112
|
+
check_untyped_defs = false
|
|
113
|
+
warn_incomplete_stub = false
|
|
114
|
+
|
|
115
|
+
# Suppress type checking for model files due to Pydantic field integration complexity
|
|
116
|
+
# and for API managers that work with polymorphic request/response models
|
|
117
|
+
[[tool.mypy.overrides]]
|
|
118
|
+
module = [
|
|
119
|
+
"harness_platform_sdk.models.*",
|
|
120
|
+
"harness_platform_sdk.client",
|
|
121
|
+
"harness_platform_sdk.ng_api.*",
|
|
122
|
+
"harness_platform_sdk.authz.*",
|
|
123
|
+
"harness_platform_sdk.pipeline_api.*",
|
|
124
|
+
"harness_platform_sdk.template_api.*",
|
|
125
|
+
"harness_platform_sdk.iacm_api.*",
|
|
126
|
+
"harness_platform_sdk.idp_api.*",
|
|
127
|
+
]
|
|
128
|
+
ignore_errors = true
|
|
129
|
+
|
|
130
|
+
[tool.ruff]
|
|
131
|
+
line-length = 100
|
|
132
|
+
|
|
133
|
+
[tool.ruff.lint]
|
|
134
|
+
select = [
|
|
135
|
+
"D100", "D101", "D102", "D103", "D104", "D105", "D107", # pydocstyle docstring rules
|
|
136
|
+
]
|
|
137
|
+
ignore = [
|
|
138
|
+
"D105", # Magic method docstring requirement (too strict for common methods)
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
[tool.ruff.lint.pydocstyle]
|
|
142
|
+
convention = "google"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Harness Platform SDK.
|
|
2
|
+
|
|
3
|
+
A Python SDK for interacting with the Harness Platform API.
|
|
4
|
+
Provides unified access to all Harness APIs (Organizations, Projects,
|
|
5
|
+
Pipelines, Connectors, Secrets, and more) with built-in authentication,
|
|
6
|
+
scope management, pagination, and retry handling.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .authz import *
|
|
10
|
+
from .client import HarnessClient
|
|
11
|
+
from .config import HarnessConfig
|
|
12
|
+
from .exceptions import ApiError, AuthError, HarnessSdkError, ScopeNotSetError
|
|
13
|
+
from .iacm_api import *
|
|
14
|
+
from .idp_api import *
|
|
15
|
+
from .ng_api import *
|
|
16
|
+
from .pipeline_api import *
|
|
17
|
+
from .scope import Scope
|
|
18
|
+
from .template_api import *
|
|
19
|
+
|
|
20
|
+
__version__ = "1.0.0"
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"HarnessClient",
|
|
24
|
+
"HarnessConfig",
|
|
25
|
+
"Scope",
|
|
26
|
+
"HarnessSdkError",
|
|
27
|
+
"ScopeNotSetError",
|
|
28
|
+
"ApiError",
|
|
29
|
+
"AuthError",
|
|
30
|
+
"OrganizationsApi",
|
|
31
|
+
"ProjectsApi",
|
|
32
|
+
"ServicesApi",
|
|
33
|
+
"RolesApi",
|
|
34
|
+
"ResourceGroupsApi",
|
|
35
|
+
"RoleAssignmentsApi",
|
|
36
|
+
"ConnectorsApi",
|
|
37
|
+
"SecretsApi",
|
|
38
|
+
"InfrastructuresApi",
|
|
39
|
+
"UserGroupsApi",
|
|
40
|
+
"PipelinesV0Api",
|
|
41
|
+
"InputSetsV0Api",
|
|
42
|
+
"TriggersV0Api",
|
|
43
|
+
"TemplatesV0Api",
|
|
44
|
+
"VariablesApi",
|
|
45
|
+
"ServiceOverridesApi",
|
|
46
|
+
# Infrastructure as Code
|
|
47
|
+
"WorkspacesApi",
|
|
48
|
+
"WorkspaceApprovalsApi",
|
|
49
|
+
"WorkspaceDefaultPipelinesApi",
|
|
50
|
+
"WorkspaceStatesApi",
|
|
51
|
+
"WorkspaceVariablesApi",
|
|
52
|
+
# Internal Developer Portal
|
|
53
|
+
"CatalogCustomPropertyApi",
|
|
54
|
+
"EntityApi",
|
|
55
|
+
"ScoreApi",
|
|
56
|
+
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Harness Authorization API resources.
|
|
2
|
+
|
|
3
|
+
Provides APIs for managing roles, resource groups, and role assignments
|
|
4
|
+
under the /authz/ path root.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .resource_groups import ResourceGroupsApi
|
|
8
|
+
from .role_assignments import RoleAssignmentsApi
|
|
9
|
+
from .roles import RolesApi
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"RolesApi",
|
|
13
|
+
"ResourceGroupsApi",
|
|
14
|
+
"RoleAssignmentsApi",
|
|
15
|
+
]
|