@planqk/planqk-service-sdk 2.2.1 → 2.3.0
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.
- package/README-node.md +1 -0
- package/README-python.md +7 -7
- package/README.md +1 -0
- package/notebooks/python-sdk.ipynb +33 -113
- package/package.json +1 -1
- package/planqk/service/_version.py +1 -1
- package/planqk/service/client.py +13 -12
- package/planqk/service/sdk/__init__.py +4 -30
- package/planqk/service/sdk/client.py +20 -19
- package/planqk/service/sdk/core/__init__.py +5 -0
- package/planqk/service/sdk/core/api_error.py +12 -6
- package/planqk/service/sdk/core/client_wrapper.py +12 -4
- package/planqk/service/sdk/core/datetime_utils.py +1 -3
- package/planqk/service/sdk/core/file.py +2 -5
- package/planqk/service/sdk/core/force_multipart.py +16 -0
- package/planqk/service/sdk/core/http_client.py +86 -118
- package/planqk/service/sdk/core/http_response.py +55 -0
- package/planqk/service/sdk/core/jsonable_encoder.py +1 -4
- package/planqk/service/sdk/core/pydantic_utilities.py +79 -147
- package/planqk/service/sdk/core/query_encoder.py +1 -3
- package/planqk/service/sdk/core/serialization.py +10 -10
- package/planqk/service/sdk/environment.py +1 -1
- package/planqk/service/sdk/service_api/__init__.py +4 -12
- package/planqk/service/sdk/service_api/client.py +138 -860
- package/planqk/service/sdk/service_api/raw_client.py +606 -0
- package/planqk/service/sdk/service_api/types/__init__.py +3 -7
- package/planqk/service/sdk/service_api/types/get_result_response.py +7 -11
- package/planqk/service/sdk/service_api/types/get_result_response_embedded.py +4 -6
- package/planqk/service/sdk/service_api/types/get_result_response_links.py +4 -6
- package/planqk/service/sdk/types/__init__.py +3 -11
- package/planqk/service/sdk/types/hal_link.py +3 -5
- package/planqk/service/sdk/types/service_execution.py +8 -16
- package/planqk/service/sdk/types/service_execution_status.py +1 -2
- package/pyproject.toml +1 -1
- package/uv.lock +488 -494
- package/planqk/service/sdk/errors/__init__.py +0 -15
- package/planqk/service/sdk/errors/bad_request_error.py +0 -9
- package/planqk/service/sdk/errors/forbidden_error.py +0 -9
- package/planqk/service/sdk/errors/internal_server_error.py +0 -9
- package/planqk/service/sdk/errors/not_found_error.py +0 -9
- package/planqk/service/sdk/errors/unauthorized_error.py +0 -9
- package/planqk/service/sdk/service_api/types/health_check_response.py +0 -24
- package/planqk/service/sdk/types/input_data.py +0 -5
- package/planqk/service/sdk/types/input_data_ref.py +0 -27
- package/planqk/service/sdk/types/input_params.py +0 -5
package/README-node.md
CHANGED
|
@@ -15,6 +15,7 @@ const serviceEndpoint = "..."
|
|
|
15
15
|
const consumerKey = "..."
|
|
16
16
|
const consumerSecret = "..."
|
|
17
17
|
|
|
18
|
+
// Create a new PlanqkServiceClient instance
|
|
18
19
|
const client = new PlanqkServiceClient(serviceEndpoint, consumerKey, consumerSecret)
|
|
19
20
|
|
|
20
21
|
// List all service executions
|
package/README-python.md
CHANGED
|
@@ -18,14 +18,14 @@ consumer_key = "..."
|
|
|
18
18
|
consumer_secret = "..."
|
|
19
19
|
service_endpoint = "..."
|
|
20
20
|
|
|
21
|
-
# Create a
|
|
21
|
+
# Create a new PlanqkServiceClient instance
|
|
22
22
|
client = PlanqkServiceClient(service_endpoint, consumer_key, consumer_secret)
|
|
23
23
|
|
|
24
24
|
# Prepare your input data and parameters
|
|
25
|
-
data = {"
|
|
26
|
-
params = {"
|
|
25
|
+
data = {"values": [2]}
|
|
26
|
+
params = {"shots": 100}
|
|
27
27
|
|
|
28
|
-
# Start a service execution
|
|
28
|
+
# Start a new service execution
|
|
29
29
|
service_execution = client.run(request={"data": data, "params": params})
|
|
30
30
|
|
|
31
31
|
# Wait for the service execution to finish (blocking)
|
|
@@ -35,13 +35,13 @@ status = service_execution.status
|
|
|
35
35
|
ended_at = service_execution.ended_at
|
|
36
36
|
print(f"Service execution finished at '{ended_at}' with status '{status}'")
|
|
37
37
|
|
|
38
|
-
# Use the client to retrieve a service execution by its
|
|
38
|
+
# Use the client to retrieve a service execution by its ID
|
|
39
39
|
service_execution = client.get_service_execution("0030737b-35cb-46a8-88c2-f59d4885484d")
|
|
40
40
|
|
|
41
|
-
#
|
|
41
|
+
# Get the results of the service execution
|
|
42
42
|
result = service_execution.result()
|
|
43
43
|
|
|
44
|
-
#
|
|
44
|
+
# Get the logs of the service execution
|
|
45
45
|
logs = service_execution.logs()
|
|
46
46
|
|
|
47
47
|
# List the result files
|
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ const serviceEndpoint = "..."
|
|
|
15
15
|
const consumerKey = "..."
|
|
16
16
|
const consumerSecret = "..."
|
|
17
17
|
|
|
18
|
+
// Create a new PlanqkServiceClient instance
|
|
18
19
|
const client = new PlanqkServiceClient(serviceEndpoint, consumerKey, consumerSecret)
|
|
19
20
|
|
|
20
21
|
// List all service executions
|
|
@@ -52,14 +52,28 @@
|
|
|
52
52
|
"source": [
|
|
53
53
|
"from planqk.service.client import PlanqkServiceClient\n",
|
|
54
54
|
"\n",
|
|
55
|
-
"# Create a
|
|
55
|
+
"# Create a new PlanqkServiceClient instance\n",
|
|
56
56
|
"client = PlanqkServiceClient(\n",
|
|
57
57
|
" service_endpoint, consumer_key, consumer_secret, token_endpoint\n",
|
|
58
58
|
")\n",
|
|
59
59
|
"\n",
|
|
60
|
-
"#
|
|
61
|
-
"
|
|
62
|
-
"
|
|
60
|
+
"# List all service executions\n",
|
|
61
|
+
"service_executions = client.get_service_executions()\n",
|
|
62
|
+
"print(f\"Found {len(service_executions)} service executions\")"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"cell_type": "code",
|
|
67
|
+
"execution_count": null,
|
|
68
|
+
"metadata": {},
|
|
69
|
+
"outputs": [],
|
|
70
|
+
"source": [
|
|
71
|
+
"# Prepare your input data and parameters\n",
|
|
72
|
+
"data = {\"values\": [2]}\n",
|
|
73
|
+
"params = {\"shots\": 100}\n",
|
|
74
|
+
"\n",
|
|
75
|
+
"# Start a new service execution\n",
|
|
76
|
+
"service_execution = client.run(request={\"data\": data, \"params\": params})\n",
|
|
63
77
|
"\n",
|
|
64
78
|
"# Wait for the service execution to finish (blocking)\n",
|
|
65
79
|
"service_execution.wait_for_final_state()\n",
|
|
@@ -71,17 +85,9 @@
|
|
|
71
85
|
},
|
|
72
86
|
{
|
|
73
87
|
"cell_type": "code",
|
|
74
|
-
"execution_count":
|
|
88
|
+
"execution_count": null,
|
|
75
89
|
"metadata": {},
|
|
76
|
-
"outputs": [
|
|
77
|
-
{
|
|
78
|
-
"name": "stdout",
|
|
79
|
-
"output_type": "stream",
|
|
80
|
-
"text": [
|
|
81
|
-
"Service execution finished at '2025-03-14 06:35:36' with status 'SUCCEEDED'\n"
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
],
|
|
90
|
+
"outputs": [],
|
|
85
91
|
"source": [
|
|
86
92
|
"# You may perform other operations while waiting for the service execution to finish\n",
|
|
87
93
|
"while not service_execution.has_finished:\n",
|
|
@@ -98,20 +104,12 @@
|
|
|
98
104
|
},
|
|
99
105
|
{
|
|
100
106
|
"cell_type": "code",
|
|
101
|
-
"execution_count":
|
|
107
|
+
"execution_count": null,
|
|
102
108
|
"metadata": {},
|
|
103
|
-
"outputs": [
|
|
104
|
-
{
|
|
105
|
-
"name": "stdout",
|
|
106
|
-
"output_type": "stream",
|
|
107
|
-
"text": [
|
|
108
|
-
"Service execution finished at '2025-03-14 06:35:36' with status 'SUCCEEDED'\n"
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
],
|
|
109
|
+
"outputs": [],
|
|
112
110
|
"source": [
|
|
113
111
|
"# Use the client to retrieve a service execution by its id\n",
|
|
114
|
-
"service_execution = client.get_service_execution(\"
|
|
112
|
+
"service_execution = client.get_service_execution(\"3063bd47-1b73-414f-96da-95a95d8fdb0c\")\n",
|
|
115
113
|
"\n",
|
|
116
114
|
"status = service_execution.status\n",
|
|
117
115
|
"ended_at = service_execution.ended_at\n",
|
|
@@ -120,44 +118,23 @@
|
|
|
120
118
|
},
|
|
121
119
|
{
|
|
122
120
|
"cell_type": "code",
|
|
123
|
-
"execution_count":
|
|
121
|
+
"execution_count": null,
|
|
124
122
|
"metadata": {},
|
|
125
|
-
"outputs": [
|
|
126
|
-
{
|
|
127
|
-
"name": "stdout",
|
|
128
|
-
"output_type": "stream",
|
|
129
|
-
"text": [
|
|
130
|
-
"{'000': 10, '001': 7, '010': 18, '011': 14, '100': 16, '101': 7, '110': 14, '111': 14}\n"
|
|
131
|
-
]
|
|
132
|
-
}
|
|
133
|
-
],
|
|
123
|
+
"outputs": [],
|
|
134
124
|
"source": [
|
|
135
|
-
"#
|
|
125
|
+
"# Get the results of the service execution\n",
|
|
136
126
|
"result = service_execution.result()\n",
|
|
137
127
|
"\n",
|
|
138
|
-
"print(result
|
|
128
|
+
"print(result)"
|
|
139
129
|
]
|
|
140
130
|
},
|
|
141
131
|
{
|
|
142
132
|
"cell_type": "code",
|
|
143
|
-
"execution_count":
|
|
133
|
+
"execution_count": null,
|
|
144
134
|
"metadata": {},
|
|
145
|
-
"outputs": [
|
|
146
|
-
{
|
|
147
|
-
"name": "stdout",
|
|
148
|
-
"output_type": "stream",
|
|
149
|
-
"text": [
|
|
150
|
-
"...\n",
|
|
151
|
-
"PlanQK:Job:MultilineResult\n",
|
|
152
|
-
"2025-03-14 06:35:35.424 | DEBUG | qsharp.telemetry:callHandlers:1706 - In on_exit handler\n",
|
|
153
|
-
"2025-03-14 06:35:35.424 | DEBUG | qsharp.telemetry:callHandlers:1706 - Exiting telemetry thread\n",
|
|
154
|
-
"2025-03-14 06:35:35.424 | DEBUG | qsharp.telemetry:callHandlers:1706 - Sending telemetry request: b'[{\"ver\": 1, \"name\": \"Microsoft.ApplicationInsights.Metric\", \"time\": \"2025-03-14T06:35:35.424270Z\", \"sampleRate\": 100.0, \"iKey\": \"95d25b22-8b6d-448e-9677-78ad4047a95a\", \"tags\": {\"ai.device.locale\": \"en_US\", \"ai.device.osVersion\": \"#1 SMP PREEMPT_DYNAMIC Thu Jan 16 17:10:14 UTC 2025\"}, \"data\": {\"baseType\": \"MetricData\", \"baseData\": {\"ver\": 2, \"metrics\": [{\"name\": \"qsharp.import\", \"value\": 1, \"count\": 1}], \"properties\": {\"qsharp.version\": \"1.13.2\"}}}}]'\n",
|
|
155
|
-
"2025-03-14 06:35:36.073 | DEBUG | qsharp.telemetry:callHandlers:1706 - Telemetry response: 200\n"
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
],
|
|
135
|
+
"outputs": [],
|
|
159
136
|
"source": [
|
|
160
|
-
"#
|
|
137
|
+
"# Get the logs of the service execution\n",
|
|
161
138
|
"logs = service_execution.logs()\n",
|
|
162
139
|
"\n",
|
|
163
140
|
"print(\"...\")\n",
|
|
@@ -167,17 +144,9 @@
|
|
|
167
144
|
},
|
|
168
145
|
{
|
|
169
146
|
"cell_type": "code",
|
|
170
|
-
"execution_count":
|
|
147
|
+
"execution_count": null,
|
|
171
148
|
"metadata": {},
|
|
172
|
-
"outputs": [
|
|
173
|
-
{
|
|
174
|
-
"name": "stdout",
|
|
175
|
-
"output_type": "stream",
|
|
176
|
-
"text": [
|
|
177
|
-
"['hello.jpg', 'hello.txt', 'output.json']\n"
|
|
178
|
-
]
|
|
179
|
-
}
|
|
180
|
-
],
|
|
149
|
+
"outputs": [],
|
|
181
150
|
"source": [
|
|
182
151
|
"import os\n",
|
|
183
152
|
"\n",
|
|
@@ -205,60 +174,11 @@
|
|
|
205
174
|
" for chunk in file_stream:\n",
|
|
206
175
|
" f.write(chunk)"
|
|
207
176
|
]
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
"cell_type": "markdown",
|
|
211
|
-
"metadata": {},
|
|
212
|
-
"source": [
|
|
213
|
-
"### Use a Data Pool as Input Data"
|
|
214
|
-
]
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
"cell_type": "code",
|
|
218
|
-
"execution_count": null,
|
|
219
|
-
"metadata": {},
|
|
220
|
-
"outputs": [],
|
|
221
|
-
"source": [
|
|
222
|
-
"from planqk.service.sdk.types.input_data_ref import InputDataRef\n",
|
|
223
|
-
"\n",
|
|
224
|
-
"# Create a client\n",
|
|
225
|
-
"client = PlanqkServiceClient(\n",
|
|
226
|
-
" service_endpoint, consumer_key, consumer_secret, token_endpoint\n",
|
|
227
|
-
")\n",
|
|
228
|
-
"\n",
|
|
229
|
-
"# Use the InputDataRef class to define a reference to a file in a data pool.\n",
|
|
230
|
-
"# Create a data pools, and upload a file called 'data.json'. Use the \"Copy File Reference\"\n",
|
|
231
|
-
"# button in the PLANQK Data Pool UI to copy the data pool id, data source descriptor id, and file id.\n",
|
|
232
|
-
"file_reference = {\n",
|
|
233
|
-
" \"dataPoolId\": \"9b943af3-ca78-4d6e-87fd-33129f5330a2\",\n",
|
|
234
|
-
" \"dataSourceDescriptorId\": \"a1e4f7ab-82d5-4158-98c3-3562635cedd2\",\n",
|
|
235
|
-
" \"fileId\": \"f9b5c9a2-0101-46a8-9958-383670a2cef4\",\n",
|
|
236
|
-
"}\n",
|
|
237
|
-
"\n",
|
|
238
|
-
"data = InputDataRef.model_validate(\n",
|
|
239
|
-
" {\n",
|
|
240
|
-
" \"data_pool_id\": file_reference[\"dataPoolId\"],\n",
|
|
241
|
-
" \"data_source_descriptor_id\": file_reference[\"dataSourceDescriptorId\"],\n",
|
|
242
|
-
" \"file_id\": file_reference[\"fileId\"],\n",
|
|
243
|
-
" }\n",
|
|
244
|
-
")\n",
|
|
245
|
-
"params = {\"some_attribute\": True}\n",
|
|
246
|
-
"\n",
|
|
247
|
-
"# Start a service execution\n",
|
|
248
|
-
"service_execution = client.run({\"dataRef\": data, \"params\": params})\n",
|
|
249
|
-
"\n",
|
|
250
|
-
"# Wait for the service execution to finish (blocking)\n",
|
|
251
|
-
"service_execution.wait_for_final_state()\n",
|
|
252
|
-
"\n",
|
|
253
|
-
"status = service_execution.status\n",
|
|
254
|
-
"ended_at = service_execution.ended_at\n",
|
|
255
|
-
"print(f\"Service execution finished at '{ended_at}' with status '{status}'\")"
|
|
256
|
-
]
|
|
257
177
|
}
|
|
258
178
|
],
|
|
259
179
|
"metadata": {
|
|
260
180
|
"kernelspec": {
|
|
261
|
-
"display_name": "
|
|
181
|
+
"display_name": "planqk-service-sdk",
|
|
262
182
|
"language": "python",
|
|
263
183
|
"name": "python3"
|
|
264
184
|
},
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.
|
|
1
|
+
__version__ = "2.3.0"
|
package/planqk/service/client.py
CHANGED
|
@@ -5,7 +5,7 @@ import time
|
|
|
5
5
|
import typing
|
|
6
6
|
|
|
7
7
|
from planqk.service.auth import DEFAULT_TOKEN_ENDPOINT, PlanqkServiceAuth
|
|
8
|
-
from planqk.service.sdk import PlanqkServiceApi,
|
|
8
|
+
from planqk.service.sdk import PlanqkServiceApi, ServiceExecution, GetResultResponse
|
|
9
9
|
from planqk.service.sdk.service_api.client import ServiceApiClient
|
|
10
10
|
from planqk.service.sdk.types.service_execution_status import ServiceExecutionStatus
|
|
11
11
|
|
|
@@ -69,7 +69,7 @@ class PlanqkServiceExecution:
|
|
|
69
69
|
try:
|
|
70
70
|
result = self._client.api.get_result(id=self.id)
|
|
71
71
|
break # If the operation succeeds, break out of the loop
|
|
72
|
-
except
|
|
72
|
+
except Exception as e:
|
|
73
73
|
time.sleep(delay) # If the operation fails, wait
|
|
74
74
|
delay *= 2 # Double the delay
|
|
75
75
|
if delay >= max_delay:
|
|
@@ -103,7 +103,7 @@ class PlanqkServiceExecution:
|
|
|
103
103
|
f.write(chunk)
|
|
104
104
|
|
|
105
105
|
def cancel(self) -> None:
|
|
106
|
-
self._client.api.
|
|
106
|
+
self._client.api.cancel_execution(id=self.id)
|
|
107
107
|
|
|
108
108
|
def logs(self) -> typing.List[str]:
|
|
109
109
|
return self._client.api.get_logs(id=self.id)
|
|
@@ -111,11 +111,11 @@ class PlanqkServiceExecution:
|
|
|
111
111
|
|
|
112
112
|
class PlanqkServiceClient:
|
|
113
113
|
def __init__(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
self,
|
|
115
|
+
service_endpoint: str,
|
|
116
|
+
consumer_key: typing.Union[str, None],
|
|
117
|
+
consumer_secret: typing.Union[str, None],
|
|
118
|
+
token_endpoint: str = DEFAULT_TOKEN_ENDPOINT,
|
|
119
119
|
):
|
|
120
120
|
self._service_endpoint = service_endpoint
|
|
121
121
|
self._consumer_key = consumer_key
|
|
@@ -139,13 +139,14 @@ class PlanqkServiceClient:
|
|
|
139
139
|
def api(self) -> ServiceApiClient:
|
|
140
140
|
return self._api.service_api
|
|
141
141
|
|
|
142
|
-
def health_check(self) -> HealthCheckResponse:
|
|
143
|
-
return self.api.health_check()
|
|
144
|
-
|
|
145
142
|
def run(self, request: typing.Dict[str, typing.Dict[str, typing.Optional[typing.Any]]]) -> PlanqkServiceExecution:
|
|
146
|
-
service_execution = self.api.
|
|
143
|
+
service_execution = self.api.start_execution(request=request)
|
|
147
144
|
return PlanqkServiceExecution(client=self, service_execution=service_execution)
|
|
148
145
|
|
|
149
146
|
def get_service_execution(self, service_execution_id: str) -> PlanqkServiceExecution:
|
|
150
147
|
service_execution = self.api.get_status(id=service_execution_id)
|
|
151
148
|
return PlanqkServiceExecution(client=self, service_execution=service_execution)
|
|
149
|
+
|
|
150
|
+
def get_service_executions(self) -> typing.List[PlanqkServiceExecution]:
|
|
151
|
+
service_executions = self.api.get_service_executions()
|
|
152
|
+
return [PlanqkServiceExecution(client=self, service_execution=e) for e in service_executions]
|
|
@@ -1,48 +1,22 @@
|
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
InputDataRef,
|
|
7
|
-
InputParams,
|
|
8
|
-
ServiceExecution,
|
|
9
|
-
ServiceExecutionStatus,
|
|
10
|
-
)
|
|
11
|
-
from .errors import (
|
|
12
|
-
BadRequestError,
|
|
13
|
-
ForbiddenError,
|
|
14
|
-
InternalServerError,
|
|
15
|
-
NotFoundError,
|
|
16
|
-
UnauthorizedError,
|
|
17
|
-
)
|
|
3
|
+
# isort: skip_file
|
|
4
|
+
|
|
5
|
+
from .types import HalLink, ServiceExecution, ServiceExecutionStatus
|
|
18
6
|
from . import service_api
|
|
19
7
|
from .client import AsyncPlanqkServiceApi, PlanqkServiceApi
|
|
20
8
|
from .environment import PlanqkServiceApiEnvironment
|
|
21
|
-
from .service_api import
|
|
22
|
-
GetResultResponse,
|
|
23
|
-
GetResultResponseEmbedded,
|
|
24
|
-
GetResultResponseLinks,
|
|
25
|
-
HealthCheckResponse,
|
|
26
|
-
)
|
|
9
|
+
from .service_api import GetResultResponse, GetResultResponseEmbedded, GetResultResponseLinks
|
|
27
10
|
|
|
28
11
|
__all__ = [
|
|
29
12
|
"AsyncPlanqkServiceApi",
|
|
30
|
-
"BadRequestError",
|
|
31
|
-
"ForbiddenError",
|
|
32
13
|
"GetResultResponse",
|
|
33
14
|
"GetResultResponseEmbedded",
|
|
34
15
|
"GetResultResponseLinks",
|
|
35
16
|
"HalLink",
|
|
36
|
-
"HealthCheckResponse",
|
|
37
|
-
"InputData",
|
|
38
|
-
"InputDataRef",
|
|
39
|
-
"InputParams",
|
|
40
|
-
"InternalServerError",
|
|
41
|
-
"NotFoundError",
|
|
42
17
|
"PlanqkServiceApi",
|
|
43
18
|
"PlanqkServiceApiEnvironment",
|
|
44
19
|
"ServiceExecution",
|
|
45
20
|
"ServiceExecutionStatus",
|
|
46
|
-
"UnauthorizedError",
|
|
47
21
|
"service_api",
|
|
48
22
|
]
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import httpx
|
|
6
|
-
from .core.client_wrapper import SyncClientWrapper
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .service_api.client import AsyncServiceApiClient
|
|
6
|
+
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
|
|
7
|
+
from .environment import PlanqkServiceApiEnvironment
|
|
8
|
+
from .service_api.client import AsyncServiceApiClient, ServiceApiClient
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class PlanqkServiceApi:
|
|
@@ -28,6 +27,9 @@ class PlanqkServiceApi:
|
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
token : typing.Union[str, typing.Callable[[], str]]
|
|
30
|
+
headers : typing.Optional[typing.Dict[str, str]]
|
|
31
|
+
Additional headers to send with every request.
|
|
32
|
+
|
|
31
33
|
timeout : typing.Optional[float]
|
|
32
34
|
The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
|
|
33
35
|
|
|
@@ -52,21 +54,21 @@ class PlanqkServiceApi:
|
|
|
52
54
|
base_url: typing.Optional[str] = None,
|
|
53
55
|
environment: PlanqkServiceApiEnvironment = PlanqkServiceApiEnvironment.DEFAULT,
|
|
54
56
|
token: typing.Union[str, typing.Callable[[], str]],
|
|
57
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
55
58
|
timeout: typing.Optional[float] = None,
|
|
56
59
|
follow_redirects: typing.Optional[bool] = True,
|
|
57
60
|
httpx_client: typing.Optional[httpx.Client] = None,
|
|
58
61
|
):
|
|
59
62
|
_defaulted_timeout = (
|
|
60
|
-
timeout if timeout is not None else 60 if httpx_client is None else
|
|
63
|
+
timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
|
|
61
64
|
)
|
|
62
65
|
self._client_wrapper = SyncClientWrapper(
|
|
63
66
|
base_url=_get_base_url(base_url=base_url, environment=environment),
|
|
64
67
|
token=token,
|
|
68
|
+
headers=headers,
|
|
65
69
|
httpx_client=httpx_client
|
|
66
70
|
if httpx_client is not None
|
|
67
|
-
else httpx.Client(
|
|
68
|
-
timeout=_defaulted_timeout, follow_redirects=follow_redirects
|
|
69
|
-
)
|
|
71
|
+
else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
|
|
70
72
|
if follow_redirects is not None
|
|
71
73
|
else httpx.Client(timeout=_defaulted_timeout),
|
|
72
74
|
timeout=_defaulted_timeout,
|
|
@@ -93,6 +95,9 @@ class AsyncPlanqkServiceApi:
|
|
|
93
95
|
|
|
94
96
|
|
|
95
97
|
token : typing.Union[str, typing.Callable[[], str]]
|
|
98
|
+
headers : typing.Optional[typing.Dict[str, str]]
|
|
99
|
+
Additional headers to send with every request.
|
|
100
|
+
|
|
96
101
|
timeout : typing.Optional[float]
|
|
97
102
|
The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
|
|
98
103
|
|
|
@@ -117,21 +122,21 @@ class AsyncPlanqkServiceApi:
|
|
|
117
122
|
base_url: typing.Optional[str] = None,
|
|
118
123
|
environment: PlanqkServiceApiEnvironment = PlanqkServiceApiEnvironment.DEFAULT,
|
|
119
124
|
token: typing.Union[str, typing.Callable[[], str]],
|
|
125
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
120
126
|
timeout: typing.Optional[float] = None,
|
|
121
127
|
follow_redirects: typing.Optional[bool] = True,
|
|
122
128
|
httpx_client: typing.Optional[httpx.AsyncClient] = None,
|
|
123
129
|
):
|
|
124
130
|
_defaulted_timeout = (
|
|
125
|
-
timeout if timeout is not None else 60 if httpx_client is None else
|
|
131
|
+
timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
|
|
126
132
|
)
|
|
127
133
|
self._client_wrapper = AsyncClientWrapper(
|
|
128
134
|
base_url=_get_base_url(base_url=base_url, environment=environment),
|
|
129
135
|
token=token,
|
|
136
|
+
headers=headers,
|
|
130
137
|
httpx_client=httpx_client
|
|
131
138
|
if httpx_client is not None
|
|
132
|
-
else httpx.AsyncClient(
|
|
133
|
-
timeout=_defaulted_timeout, follow_redirects=follow_redirects
|
|
134
|
-
)
|
|
139
|
+
else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
|
|
135
140
|
if follow_redirects is not None
|
|
136
141
|
else httpx.AsyncClient(timeout=_defaulted_timeout),
|
|
137
142
|
timeout=_defaulted_timeout,
|
|
@@ -139,14 +144,10 @@ class AsyncPlanqkServiceApi:
|
|
|
139
144
|
self.service_api = AsyncServiceApiClient(client_wrapper=self._client_wrapper)
|
|
140
145
|
|
|
141
146
|
|
|
142
|
-
def _get_base_url(
|
|
143
|
-
*, base_url: typing.Optional[str] = None, environment: PlanqkServiceApiEnvironment
|
|
144
|
-
) -> str:
|
|
147
|
+
def _get_base_url(*, base_url: typing.Optional[str] = None, environment: PlanqkServiceApiEnvironment) -> str:
|
|
145
148
|
if base_url is not None:
|
|
146
149
|
return base_url
|
|
147
150
|
elif environment is not None:
|
|
148
151
|
return environment.value
|
|
149
152
|
else:
|
|
150
|
-
raise Exception(
|
|
151
|
-
"Please pass in either base_url or environment to construct the client"
|
|
152
|
-
)
|
|
153
|
+
raise Exception("Please pass in either base_url or environment to construct the client")
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
|
2
2
|
|
|
3
|
+
# isort: skip_file
|
|
4
|
+
|
|
3
5
|
from .api_error import ApiError
|
|
4
6
|
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
|
|
5
7
|
from .datetime_utils import serialize_datetime
|
|
6
8
|
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
|
|
7
9
|
from .http_client import AsyncHttpClient, HttpClient
|
|
10
|
+
from .http_response import AsyncHttpResponse, HttpResponse
|
|
8
11
|
from .jsonable_encoder import jsonable_encoder
|
|
9
12
|
from .pydantic_utilities import (
|
|
10
13
|
IS_PYDANTIC_V2,
|
|
@@ -24,10 +27,12 @@ __all__ = [
|
|
|
24
27
|
"ApiError",
|
|
25
28
|
"AsyncClientWrapper",
|
|
26
29
|
"AsyncHttpClient",
|
|
30
|
+
"AsyncHttpResponse",
|
|
27
31
|
"BaseClientWrapper",
|
|
28
32
|
"FieldMetadata",
|
|
29
33
|
"File",
|
|
30
34
|
"HttpClient",
|
|
35
|
+
"HttpResponse",
|
|
31
36
|
"IS_PYDANTIC_V2",
|
|
32
37
|
"RequestOptions",
|
|
33
38
|
"SyncClientWrapper",
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class ApiError(Exception):
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
headers: Optional[Dict[str, str]]
|
|
8
|
+
status_code: Optional[int]
|
|
9
|
+
body: Any
|
|
9
10
|
|
|
10
11
|
def __init__(
|
|
11
|
-
self,
|
|
12
|
-
|
|
12
|
+
self,
|
|
13
|
+
*,
|
|
14
|
+
headers: Optional[Dict[str, str]] = None,
|
|
15
|
+
status_code: Optional[int] = None,
|
|
16
|
+
body: Any = None,
|
|
17
|
+
) -> None:
|
|
18
|
+
self.headers = headers
|
|
13
19
|
self.status_code = status_code
|
|
14
20
|
self.body = body
|
|
15
21
|
|
|
16
22
|
def __str__(self) -> str:
|
|
17
|
-
return f"status_code: {self.status_code}, body: {self.body}"
|
|
23
|
+
return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
|
+
|
|
4
5
|
import httpx
|
|
5
|
-
from .http_client import HttpClient
|
|
6
|
-
from .http_client import AsyncHttpClient
|
|
6
|
+
from .http_client import AsyncHttpClient, HttpClient
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class BaseClientWrapper:
|
|
@@ -11,16 +11,19 @@ class BaseClientWrapper:
|
|
|
11
11
|
self,
|
|
12
12
|
*,
|
|
13
13
|
token: typing.Union[str, typing.Callable[[], str]],
|
|
14
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
14
15
|
base_url: str,
|
|
15
16
|
timeout: typing.Optional[float] = None,
|
|
16
17
|
):
|
|
17
18
|
self._token = token
|
|
19
|
+
self._headers = headers
|
|
18
20
|
self._base_url = base_url
|
|
19
21
|
self._timeout = timeout
|
|
20
22
|
|
|
21
23
|
def get_headers(self) -> typing.Dict[str, str]:
|
|
22
24
|
headers: typing.Dict[str, str] = {
|
|
23
25
|
"X-Fern-Language": "Python",
|
|
26
|
+
**(self.get_custom_headers() or {}),
|
|
24
27
|
}
|
|
25
28
|
headers["Authorization"] = f"Bearer {self._get_token()}"
|
|
26
29
|
return headers
|
|
@@ -31,6 +34,9 @@ class BaseClientWrapper:
|
|
|
31
34
|
else:
|
|
32
35
|
return self._token()
|
|
33
36
|
|
|
37
|
+
def get_custom_headers(self) -> typing.Optional[typing.Dict[str, str]]:
|
|
38
|
+
return self._headers
|
|
39
|
+
|
|
34
40
|
def get_base_url(self) -> str:
|
|
35
41
|
return self._base_url
|
|
36
42
|
|
|
@@ -43,11 +49,12 @@ class SyncClientWrapper(BaseClientWrapper):
|
|
|
43
49
|
self,
|
|
44
50
|
*,
|
|
45
51
|
token: typing.Union[str, typing.Callable[[], str]],
|
|
52
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
46
53
|
base_url: str,
|
|
47
54
|
timeout: typing.Optional[float] = None,
|
|
48
55
|
httpx_client: httpx.Client,
|
|
49
56
|
):
|
|
50
|
-
super().__init__(token=token, base_url=base_url, timeout=timeout)
|
|
57
|
+
super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout)
|
|
51
58
|
self.httpx_client = HttpClient(
|
|
52
59
|
httpx_client=httpx_client,
|
|
53
60
|
base_headers=self.get_headers,
|
|
@@ -61,11 +68,12 @@ class AsyncClientWrapper(BaseClientWrapper):
|
|
|
61
68
|
self,
|
|
62
69
|
*,
|
|
63
70
|
token: typing.Union[str, typing.Callable[[], str]],
|
|
71
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
64
72
|
base_url: str,
|
|
65
73
|
timeout: typing.Optional[float] = None,
|
|
66
74
|
httpx_client: httpx.AsyncClient,
|
|
67
75
|
):
|
|
68
|
-
super().__init__(token=token, base_url=base_url, timeout=timeout)
|
|
76
|
+
super().__init__(token=token, headers=headers, base_url=base_url, timeout=timeout)
|
|
69
77
|
self.httpx_client = AsyncHttpClient(
|
|
70
78
|
httpx_client=httpx_client,
|
|
71
79
|
base_headers=self.get_headers,
|
|
@@ -13,9 +13,7 @@ def serialize_datetime(v: dt.datetime) -> str:
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
def _serialize_zoned_datetime(v: dt.datetime) -> str:
|
|
16
|
-
if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(
|
|
17
|
-
None
|
|
18
|
-
):
|
|
16
|
+
if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(None):
|
|
19
17
|
# UTC is a special case where we use "Z" at the end instead of "+00:00"
|
|
20
18
|
return v.isoformat().replace("+00:00", "Z")
|
|
21
19
|
else:
|
|
@@ -53,15 +53,12 @@ def with_content_type(*, file: File, default_content_type: str) -> File:
|
|
|
53
53
|
filename, content = cast(Tuple[Optional[str], FileContent], file) # type: ignore
|
|
54
54
|
return (filename, content, default_content_type)
|
|
55
55
|
elif len(file) == 3:
|
|
56
|
-
filename, content, file_content_type = cast(
|
|
57
|
-
Tuple[Optional[str], FileContent, Optional[str]], file
|
|
58
|
-
) # type: ignore
|
|
56
|
+
filename, content, file_content_type = cast(Tuple[Optional[str], FileContent, Optional[str]], file) # type: ignore
|
|
59
57
|
out_content_type = file_content_type or default_content_type
|
|
60
58
|
return (filename, content, out_content_type)
|
|
61
59
|
elif len(file) == 4:
|
|
62
60
|
filename, content, file_content_type, headers = cast( # type: ignore
|
|
63
|
-
Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]],
|
|
64
|
-
file,
|
|
61
|
+
Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], file
|
|
65
62
|
)
|
|
66
63
|
out_content_type = file_content_type or default_content_type
|
|
67
64
|
return (filename, content, out_content_type, headers)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ForceMultipartDict(dict):
|
|
5
|
+
"""
|
|
6
|
+
A dictionary subclass that always evaluates to True in boolean contexts.
|
|
7
|
+
|
|
8
|
+
This is used to force multipart/form-data encoding in HTTP requests even when
|
|
9
|
+
the dictionary is empty, which would normally evaluate to False.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __bool__(self):
|
|
13
|
+
return True
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
FORCE_MULTIPART = ForceMultipartDict()
|