Skip to content

Commit dce049e

Browse files
Abel Milashclaude
andcommitted
Async parity: add context= kwarg to AsyncDataverseClient, fix r.json() content_type
- Add `context: Optional[OperationContext] = None` keyword argument to AsyncDataverseClient.__init__ with the same conflict validation and three-branch config initialization as the sync DataverseClient - Update AsyncDataverseClient docstring to document the context parameter - Add content_type=None to all await r.json() calls in _async_relationships.py for consistency with _async_odata.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 15bf57b commit dce049e

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

src/PowerPlatform/Dataverse/aio/async_client.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from azure.core.credentials_async import AsyncTokenCredential
1111

1212
from .core._async_auth import _AsyncAuthManager
13-
from ..core.config import DataverseConfig
13+
from ..core.config import DataverseConfig, OperationContext
1414
from .data._async_odata import _AsyncODataClient
1515
from .operations.async_dataframe import AsyncDataFrameOperations
1616
from .operations.async_records import AsyncRecordOperations
@@ -43,8 +43,14 @@ class AsyncDataverseClient:
4343
:param config: Optional configuration for language, timeouts, and retries.
4444
If not provided, defaults are loaded from :meth:`~PowerPlatform.Dataverse.core.config.DataverseConfig.from_env`.
4545
:type config: ~PowerPlatform.Dataverse.core.config.DataverseConfig or None
46+
:param context: Optional caller-defined context object appended to the
47+
outbound ``User-Agent`` header for plugin/tool attribution. Cannot be used
48+
together with ``config`` -- pass the context via
49+
:class:`~PowerPlatform.Dataverse.core.config.DataverseConfig` instead.
50+
:type context: ~PowerPlatform.Dataverse.core.config.OperationContext or None
4651
4752
:raises ValueError: If ``base_url`` is missing or empty after trimming.
53+
:raises ValueError: If both ``config`` and ``context`` are provided.
4854
4955
.. note::
5056
The client lazily initializes its internal OData client on first use,
@@ -95,12 +101,24 @@ def __init__(
95101
base_url: str,
96102
credential: AsyncTokenCredential,
97103
config: Optional[DataverseConfig] = None,
104+
*,
105+
context: Optional[OperationContext] = None,
98106
) -> None:
107+
if config is not None and context is not None:
108+
raise ValueError(
109+
"Cannot specify both 'config' and 'context'. "
110+
"Pass operation_context via DataverseConfig instead."
111+
)
99112
self.auth = _AsyncAuthManager(credential)
100113
self._base_url = (base_url or "").rstrip("/")
101114
if not self._base_url:
102115
raise ValueError("base_url is required.")
103-
self._config = config or DataverseConfig.from_env()
116+
if config is not None:
117+
self._config = config
118+
elif context is not None:
119+
self._config = DataverseConfig(operation_context=context)
120+
else:
121+
self._config = DataverseConfig.from_env()
104122
self._odata: Optional[_AsyncODataClient] = None
105123
self._session: Optional[aiohttp.ClientSession] = None
106124
self._closed: bool = False

src/PowerPlatform/Dataverse/aio/data/_async_relationships.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ async def _get_relationship(self, schema_name: str) -> Optional[Dict[str, Any]]:
144144
url = f"{self.api}/RelationshipDefinitions"
145145
params = {"$filter": f"SchemaName eq '{self._escape_odata_quotes(schema_name)}'"}
146146
r = await self._request("get", url, headers=await self._headers(), params=params)
147-
data = await r.json()
147+
data = await r.json(content_type=None)
148148
results = data.get("value", [])
149149
return results[0] if results else None
150150

@@ -179,7 +179,7 @@ async def _list_relationships(
179179
if select:
180180
params["$select"] = ",".join(select)
181181
r = await self._request("get", url, headers=await self._headers(), params=params)
182-
return (await r.json()).get("value", [])
182+
return (await r.json(content_type=None)).get("value", [])
183183

184184
async def _list_table_relationships(
185185
self,
@@ -246,7 +246,9 @@ async def _list_table_relationships(
246246
)
247247

248248
return (
249-
(await r1.json()).get("value", []) + (await r2.json()).get("value", []) + (await r3.json()).get("value", [])
249+
(await r1.json(content_type=None)).get("value", [])
250+
+ (await r2.json(content_type=None)).get("value", [])
251+
+ (await r3.json(content_type=None)).get("value", [])
250252
)
251253

252254
def _extract_id_from_header(self, header_value: Optional[str]) -> Optional[str]:

0 commit comments

Comments
 (0)