Skip to content

Commit 2c1870c

Browse files
committed
fix(httpx_header): allow httpx determine the correct header
1 parent dbc82b9 commit 2c1870c

9 files changed

Lines changed: 73 additions & 71 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath"
3-
version = "2.1.47"
3+
version = "2.1.48"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.10"

src/uipath/_cli/_utils/_studio_project.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ async def upload_file_async(
311311
files=files_data,
312312
url=f"{self.file_operations_base_url}/File/{remote_file.id}",
313313
scoped="org",
314-
infer_content_type=True,
315314
headers=headers or {},
316315
)
317316
action = "Updated"
@@ -322,7 +321,6 @@ async def upload_file_async(
322321
data={"parentId": folder.id} if folder else None,
323322
files=files_data,
324323
scoped="org",
325-
infer_content_type=True,
326324
headers=headers or {},
327325
)
328326
action = "Uploaded"
@@ -451,7 +449,6 @@ async def perform_structural_migration_async(
451449
url=f"{self.file_operations_base_url}/StructuralMigration",
452450
scoped="org",
453451
files=files,
454-
infer_content_type=True,
455452
headers=headers or {},
456453
)
457454

src/uipath/_services/_base_service.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def request(
7474
url: Union[URL, str],
7575
*,
7676
scoped: Literal["org", "tenant"] = "tenant",
77-
infer_content_type=False,
7877
**kwargs: Any,
7978
) -> Response:
8079
self._logger.debug(f"Request: {method} {url}")
@@ -106,9 +105,6 @@ def request(
106105

107106
scoped_url = self._url.scope_url(str(url), scoped)
108107

109-
if infer_content_type:
110-
self._client.headers.pop("Content-Type", None)
111-
112108
response = self._client.request(method, scoped_url, **kwargs)
113109

114110
try:
@@ -132,7 +128,6 @@ async def request_async(
132128
url: Union[URL, str],
133129
*,
134130
scoped: Literal["org", "tenant"] = "tenant",
135-
infer_content_type=False,
136131
**kwargs: Any,
137132
) -> Response:
138133
self._logger.debug(f"Request: {method} {url}")
@@ -147,9 +142,6 @@ async def request_async(
147142

148143
scoped_url = self._url.scope_url(str(url), scoped)
149144

150-
if infer_content_type:
151-
self._client_async.headers.pop("Content-Type", None)
152-
153145
response = await self._client_async.request(method, scoped_url, **kwargs)
154146

155147
try:
@@ -163,7 +155,6 @@ async def request_async(
163155
def default_headers(self) -> dict[str, str]:
164156
return {
165157
"Accept": "application/json",
166-
"Content-Type": "application/json",
167158
**self.auth_headers,
168159
**self.custom_headers,
169160
}

src/uipath/_services/actions_service.py

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
22
import uuid
3-
from json import dumps
43
from typing import Any, Dict, List, Optional, Tuple
54

65
from .._config import Config
@@ -81,30 +80,28 @@ def _create_spec(
8180
return RequestSpec(
8281
method="POST",
8382
endpoint=Endpoint("/orchestrator_/tasks/AppTasks/CreateAppTask"),
84-
content=dumps(
85-
{
86-
"appId": app_key,
87-
"appVersion": app_version,
88-
"title": title,
89-
"data": data if data is not None else {},
90-
"actionableMessageMetaData": {
91-
"fieldSet": {
92-
"id": str(uuid.uuid4()),
93-
"fields": field_list,
94-
}
95-
if len(field_list) != 0
96-
else {},
97-
"actionSet": {
98-
"id": str(uuid.uuid4()),
99-
"actions": outcome_list,
100-
}
101-
if len(outcome_list) != 0
102-
else {},
83+
json={
84+
"appId": app_key,
85+
"appVersion": app_version,
86+
"title": title,
87+
"data": data if data is not None else {},
88+
"actionableMessageMetaData": {
89+
"fieldSet": {
90+
"id": str(uuid.uuid4()),
91+
"fields": field_list,
92+
}
93+
if len(field_list) != 0
94+
else {},
95+
"actionSet": {
96+
"id": str(uuid.uuid4()),
97+
"actions": outcome_list,
10398
}
104-
if action_schema is not None
99+
if len(outcome_list) != 0
105100
else {},
106101
}
107-
),
102+
if action_schema is not None
103+
else {},
104+
},
108105
headers=folder_headers(app_folder_key, app_folder_path),
109106
)
110107

@@ -126,9 +123,7 @@ def _assign_task_spec(task_key: str, assignee: str) -> RequestSpec:
126123
endpoint=Endpoint(
127124
"/orchestrator_/odata/Tasks/UiPath.Server.Configuration.OData.AssignTasks"
128125
),
129-
content=dumps(
130-
{"taskAssignments": [{"taskId": task_key, "UserNameOrEmail": assignee}]}
131-
),
126+
json={"taskAssignments": [{"taskId": task_key, "UserNameOrEmail": assignee}]},
132127
)
133128

134129

@@ -224,12 +219,18 @@ async def create_async(
224219
)
225220

226221
response = await self.request_async(
227-
spec.method, spec.endpoint, content=spec.content, headers=spec.headers
222+
spec.method,
223+
spec.endpoint,
224+
json=spec.json,
225+
content=spec.content,
226+
headers=spec.headers,
228227
)
229228
json_response = response.json()
230229
if assignee:
231230
spec = _assign_task_spec(json_response["id"], assignee)
232-
await self.request_async(spec.method, spec.endpoint, content=spec.content)
231+
await self.request_async(
232+
spec.method, spec.endpoint, json=spec.json, content=spec.content
233+
)
233234
return Action.model_validate(json_response)
234235

235236
@traced(name="actions_create", run_type="uipath")
@@ -284,12 +285,18 @@ def create(
284285
)
285286

286287
response = self.request(
287-
spec.method, spec.endpoint, content=spec.content, headers=spec.headers
288+
spec.method,
289+
spec.endpoint,
290+
json=spec.json,
291+
content=spec.content,
292+
headers=spec.headers,
288293
)
289294
json_response = response.json()
290295
if assignee:
291296
spec = _assign_task_spec(json_response["id"], assignee)
292-
self.request(spec.method, spec.endpoint, content=spec.content)
297+
self.request(
298+
spec.method, spec.endpoint, json=spec.json, content=spec.content
299+
)
293300
return Action.model_validate(json_response)
294301

295302
@traced(name="actions_retrieve", run_type="uipath")

src/uipath/_services/api_client.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ def request(
2525
method: str,
2626
url: Union[URL, str],
2727
scoped: Literal["org", "tenant"] = "tenant",
28-
infer_content_type=False,
2928
**kwargs: Any,
3029
) -> Response:
3130
if kwargs.get("include_folder_headers", False):
@@ -37,16 +36,13 @@ def request(
3736
if "include_folder_headers" in kwargs:
3837
del kwargs["include_folder_headers"]
3938

40-
return super().request(
41-
method, url, scoped=scoped, infer_content_type=infer_content_type, **kwargs
42-
)
39+
return super().request(method, url, scoped=scoped, **kwargs)
4340

4441
async def request_async(
4542
self,
4643
method: str,
4744
url: Union[URL, str],
4845
scoped: Literal["org", "tenant"] = "tenant",
49-
infer_content_type=False,
5046
**kwargs: Any,
5147
) -> Response:
5248
if kwargs.get("include_folder_headers", False):
@@ -58,6 +54,4 @@ async def request_async(
5854
if "include_folder_headers" in kwargs:
5955
del kwargs["include_folder_headers"]
6056

61-
return await super().request_async(
62-
method, url, scoped=scoped, infer_content_type=infer_content_type, **kwargs
63-
)
57+
return await super().request_async(method, url, scoped=scoped, **kwargs)

src/uipath/_services/assets_service.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ def retrieve_credential(
170170
response = self.request(
171171
spec.method,
172172
url=spec.endpoint,
173+
params=spec.params,
174+
json=spec.json,
173175
content=spec.content,
174176
headers=spec.headers,
175177
)
@@ -223,6 +225,8 @@ async def retrieve_credential_async(
223225
response = await self.request_async(
224226
spec.method,
225227
url=spec.endpoint,
228+
params=spec.params,
229+
json=spec.json,
226230
content=spec.content,
227231
headers=spec.headers,
228232
)
@@ -267,6 +271,8 @@ def update(
267271
response = self.request(
268272
spec.method,
269273
url=spec.endpoint,
274+
params=spec.params,
275+
json=spec.json,
270276
content=spec.content,
271277
headers=spec.headers,
272278
)
@@ -298,6 +304,8 @@ async def update_async(
298304
response = await self.request_async(
299305
spec.method,
300306
url=spec.endpoint,
307+
params=spec.params,
308+
json=spec.json,
301309
content=spec.content,
302310
headers=spec.headers,
303311
)
@@ -337,7 +345,7 @@ def _retrieve_spec(
337345
endpoint=Endpoint(
338346
"/orchestrator_/odata/Assets/UiPath.Server.Configuration.OData.GetRobotAssetByNameForRobotKey"
339347
),
340-
content=str({"assetName": name, "robotKey": robot_key}),
348+
json={"assetName": name, "robotKey": robot_key},
341349
headers={
342350
**header_folder(folder_key, folder_path),
343351
},
@@ -355,12 +363,10 @@ def _update_spec(
355363
endpoint=Endpoint(
356364
"/orchestrator_/odata/Assets/UiPath.Server.Configuration.OData.SetRobotAssetByRobotKey"
357365
),
358-
content=str(
359-
{
360-
"robotKey": self._execution_context.robot_key,
361-
"robotAsset": robot_asset,
362-
}
363-
),
366+
json={
367+
"robotKey": self._execution_context.robot_key,
368+
"robotAsset": robot_asset.model_dump(by_alias=True, exclude_none=True),
369+
},
364370
headers={
365371
**header_folder(folder_key, folder_path),
366372
},

src/uipath/_services/processes_service.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ def invoke(
8787
response = self.request(
8888
spec.method,
8989
url=spec.endpoint,
90+
params=spec.params,
91+
json=spec.json,
9092
content=spec.content,
9193
headers=spec.headers,
9294
)
@@ -146,6 +148,8 @@ async def main():
146148
response = await self.request_async(
147149
spec.method,
148150
url=spec.endpoint,
151+
params=spec.params,
152+
json=spec.json,
149153
content=spec.content,
150154
headers=spec.headers,
151155
)
@@ -230,18 +234,18 @@ def _invoke_spec(
230234
folder_key: Optional[str] = None,
231235
folder_path: Optional[str] = None,
232236
) -> RequestSpec:
233-
input_dict = {"startInfo": {"ReleaseName": name, **(input_data or {})}}
234-
request_scope = RequestSpec(
237+
request_spec = RequestSpec(
235238
method="POST",
236239
endpoint=Endpoint(
237240
"/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
238241
),
239-
content=str(input_dict),
242+
json={"startInfo": {"ReleaseName": name, **(input_data or {})}},
240243
headers={
241244
**header_folder(folder_key, folder_path),
242245
},
243246
)
244247
job_key = os.environ.get(ENV_JOB_KEY, None)
245248
if job_key:
246-
request_scope.headers[HEADER_JOB_KEY] = job_key
247-
return request_scope
249+
request_spec.headers[HEADER_JOB_KEY] = job_key
250+
251+
return request_spec

tests/sdk/services/test_base_service.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ def test_init_base_service(self, service: BaseService):
1919
def test_base_service_default_headers(self, service: BaseService, secret: str):
2020
assert service.default_headers == {
2121
"Accept": "application/json",
22-
"Content-Type": "application/json",
2322
"Authorization": f"Bearer {secret}",
2423
}
2524

tests/sdk/services/test_processes_service.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@ def test_invoke(
7373
sent_request.url
7474
== f"{base_url}{org}{tenant}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
7575
)
76-
assert sent_request.content.decode("utf-8") == str(
76+
assert sent_request.content.decode("utf-8") == json.dumps(
7777
{
7878
"startInfo": {
7979
"ReleaseName": process_name,
8080
"InputArguments": json.dumps(input_arguments),
8181
}
82-
}
82+
},
83+
separators=(",", ":"),
8384
)
8485

8586
assert HEADER_USER_AGENT in sent_request.headers
@@ -130,13 +131,14 @@ def test_invoke_without_input_arguments(
130131
sent_request.url
131132
== f"{base_url}{org}{tenant}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
132133
)
133-
assert sent_request.content.decode("utf-8") == str(
134+
assert sent_request.content.decode("utf-8") == json.dumps(
134135
{
135136
"startInfo": {
136137
"ReleaseName": process_name,
137138
"InputArguments": "{}",
138139
}
139-
}
140+
},
141+
separators=(",", ":"),
140142
)
141143

142144
assert HEADER_USER_AGENT in sent_request.headers
@@ -286,13 +288,14 @@ async def test_invoke_async(
286288
sent_request.url
287289
== f"{base_url}{org}{tenant}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
288290
)
289-
assert sent_request.content.decode("utf-8") == str(
291+
assert sent_request.content.decode("utf-8") == json.dumps(
290292
{
291293
"startInfo": {
292294
"ReleaseName": process_name,
293295
"InputArguments": json.dumps(input_arguments),
294296
}
295-
}
297+
},
298+
separators=(",", ":"),
296299
)
297300

298301
assert HEADER_USER_AGENT in sent_request.headers
@@ -344,13 +347,14 @@ async def test_invoke_async_without_input_arguments(
344347
sent_request.url
345348
== f"{base_url}{org}{tenant}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
346349
)
347-
assert sent_request.content.decode("utf-8") == str(
350+
assert sent_request.content.decode("utf-8") == json.dumps(
348351
{
349352
"startInfo": {
350353
"ReleaseName": process_name,
351354
"InputArguments": "{}",
352355
}
353-
}
356+
},
357+
separators=(",", ":"),
354358
)
355359

356360
assert HEADER_USER_AGENT in sent_request.headers

0 commit comments

Comments
 (0)