Skip to content

Commit 7b712a9

Browse files
tpellissierclaude
andcommitted
Fix tuple unpacking for _request() calls returning telemetry data
Update internal _request() call sites to unpack (response, telemetry) tuples after Phase 1 changes. Also use duck typing instead of isinstance(x, list) for OperationResult compatibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7a3e6bc commit 7b712a9

3 files changed

Lines changed: 19 additions & 34 deletions

File tree

examples/advanced/file_upload.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def log(call: str):
6868
_FILE_HASH_CACHE = {}
6969
ATTRIBUTE_VISIBILITY_DELAYS = (0, 3, 10, 20, 35, 50, 70, 90, 120)
7070

71+
7172
def file_sha256(path: Path): # returns (hex_digest, size_bytes)
7273
try:
7374
m = _FILE_HASH_CACHE.get(path)
@@ -166,19 +167,15 @@ def backoff(op, *, delays=(0, 2, 5, 10, 20, 20)):
166167
result = op()
167168
if attempts > 1:
168169
retry_count = attempts - 1
169-
print(
170-
f" [INFO] Backoff succeeded after {retry_count} retry(s); waited {total_delay}s total."
171-
)
170+
print(f" [INFO] Backoff succeeded after {retry_count} retry(s); waited {total_delay}s total.")
172171
return result
173172
except Exception as ex: # noqa: BLE001
174173
last = ex
175174
continue
176175
if last:
177176
if attempts:
178177
retry_count = max(attempts - 1, 0)
179-
print(
180-
f" [WARN] Backoff exhausted after {retry_count} retry(s); waited {total_delay}s total."
181-
)
178+
print(f" [WARN] Backoff exhausted after {retry_count} retry(s); waited {total_delay}s total.")
182179
raise last
183180

184181

@@ -227,7 +224,7 @@ def ensure_file_attribute_generic(schema_name: str, label: str, key_prefix: str)
227224
f"{odata.api}/EntityDefinitions({meta_id})/Attributes?$select=SchemaName&$filter="
228225
f"SchemaName eq '{schema_name}'"
229226
)
230-
r = backoff(lambda: odata._request("get", url), delays=ATTRIBUTE_VISIBILITY_DELAYS)
227+
r, _ = backoff(lambda: odata._request("get", url), delays=ATTRIBUTE_VISIBILITY_DELAYS)
231228
val = []
232229
try:
233230
val = r.json().get("value", [])
@@ -255,7 +252,7 @@ def ensure_file_attribute_generic(schema_name: str, label: str, key_prefix: str)
255252
}
256253
try:
257254
url = f"{odata.api}/EntityDefinitions({meta_id})/Attributes"
258-
backoff(lambda: odata._request("post", url, json=payload), delays=ATTRIBUTE_VISIBILITY_DELAYS)
255+
backoff(lambda: odata._request("post", url, json=payload)[0], delays=ATTRIBUTE_VISIBILITY_DELAYS)
259256
print({f"{key_prefix}_file_attribute_created": True})
260257
time.sleep(2)
261258
return True
@@ -285,7 +282,7 @@ def wait_for_attribute_visibility(logical_name: str, label: str):
285282
time.sleep(delay)
286283
waited += delay
287284
try:
288-
resp = odata._request("get", probe_url)
285+
resp, _ = odata._request("get", probe_url)
289286
try:
290287
resp.json()
291288
except Exception: # noqa: BLE001
@@ -313,7 +310,7 @@ def wait_for_attribute_visibility(logical_name: str, label: str):
313310
payload = {name_attr: "File Sample Record"}
314311
log(f"client.create('{table_schema_name}', payload)")
315312
created_ids = backoff(lambda: client.create(table_schema_name, payload))
316-
if isinstance(created_ids, list) and created_ids:
313+
if created_ids and len(created_ids) > 0:
317314
record_id = created_ids[0]
318315
else:
319316
raise RuntimeError("Unexpected create return; expected list[str] with at least one GUID")
@@ -363,7 +360,7 @@ def get_dataset_info(file_path: Path):
363360
dl_url_single = (
364361
f"{odata.api}/{entity_set}({record_id})/{small_file_attr_logical}/$value" # raw entity_set URL OK
365362
)
366-
resp_single = backoff(lambda: odata._request("get", dl_url_single))
363+
resp_single, _ = backoff(lambda: odata._request("get", dl_url_single))
367364
content_single = resp_single.content or b""
368365
import hashlib # noqa: WPS433
369366

@@ -393,7 +390,7 @@ def get_dataset_info(file_path: Path):
393390
)
394391
)
395392
print({"small_replace_upload_completed": True, "small_replace_source_size": replace_size_small})
396-
resp_single_replace = backoff(lambda: odata._request("get", dl_url_single))
393+
resp_single_replace, _ = backoff(lambda: odata._request("get", dl_url_single))
397394
content_single_replace = resp_single_replace.content or b""
398395
downloaded_hash_replace = hashlib.sha256(content_single_replace).hexdigest() if content_single_replace else None
399396
hash_match_replace = (
@@ -435,7 +432,7 @@ def get_dataset_info(file_path: Path):
435432
dl_url_chunk = (
436433
f"{odata.api}/{entity_set}({record_id})/{chunk_file_attr_logical}/$value" # raw entity_set for download
437434
)
438-
resp_chunk = backoff(lambda: odata._request("get", dl_url_chunk))
435+
resp_chunk, _ = backoff(lambda: odata._request("get", dl_url_chunk))
439436
content_chunk = resp_chunk.content or b""
440437
import hashlib # noqa: WPS433
441438

@@ -464,7 +461,7 @@ def get_dataset_info(file_path: Path):
464461
)
465462
)
466463
print({"chunk_replace_upload_completed": True})
467-
resp_chunk_replace = backoff(lambda: odata._request("get", dl_url_chunk))
464+
resp_chunk_replace, _ = backoff(lambda: odata._request("get", dl_url_chunk))
468465
content_chunk_replace = resp_chunk_replace.content or b""
469466
dst_hash_chunk_replace = hashlib.sha256(content_chunk_replace).hexdigest() if content_chunk_replace else None
470467
hash_match_chunk_replace = (

examples/basic/functional_testing.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,16 @@ def wait_for_table_metadata(
9191
odata._entity_set_from_schema_name(table_schema_name)
9292

9393
if attempt > 1:
94-
print(
95-
f" [OK] Table metadata available after {attempt} attempts."
96-
)
94+
print(f" [OK] Table metadata available after {attempt} attempts.")
9795
return info
9896
except Exception:
9997
pass
10098

10199
if attempt < retries:
102-
print(
103-
f" Waiting for table metadata to publish (attempt {attempt}/{retries})..."
104-
)
100+
print(f" Waiting for table metadata to publish (attempt {attempt}/{retries})...")
105101
time.sleep(delay_seconds)
106102

107-
raise RuntimeError(
108-
"Table metadata did not become available in time. Please retry later."
109-
)
103+
raise RuntimeError("Table metadata did not become available in time. Please retry later.")
110104

111105

112106
def ensure_test_table(client: DataverseClient) -> Dict[str, Any]:
@@ -190,7 +184,7 @@ def test_create_record(client: DataverseClient, table_info: Dict[str, Any]) -> s
190184
continue
191185
raise
192186

193-
if isinstance(created_ids, list) and created_ids:
187+
if created_ids and len(created_ids) > 0:
194188
record_id = created_ids[0]
195189
print(f"[OK] Record created successfully!")
196190
print(f" Record ID: {record_id}")
@@ -229,9 +223,7 @@ def test_read_record(client: DataverseClient, table_info: Dict[str, Any], record
229223
break
230224
except HttpError as err:
231225
if getattr(err, "status_code", None) == 404 and attempt < retries:
232-
print(
233-
f" Record not queryable yet (attempt {attempt}/{retries}). Retrying in {delay_seconds}s..."
234-
)
226+
print(f" Record not queryable yet (attempt {attempt}/{retries}). Retrying in {delay_seconds}s...")
235227
time.sleep(delay_seconds)
236228
continue
237229
raise
@@ -301,9 +293,7 @@ def test_query_records(client: DataverseClient, table_info: Dict[str, Any]) -> N
301293
break
302294
except HttpError as err:
303295
if getattr(err, "status_code", None) == 404 and attempt < retries:
304-
print(
305-
f" Query retry {attempt}/{retries} after metadata 404 ({err}). Waiting {delay_seconds}s..."
306-
)
296+
print(f" Query retry {attempt}/{retries} after metadata 404 ({err}). Waiting {delay_seconds}s...")
307297
time.sleep(delay_seconds)
308298
continue
309299
raise
@@ -373,9 +363,7 @@ def cleanup_test_data(client: DataverseClient, table_info: Dict[str, Any], recor
373363
print("[OK] Test table deleted successfully (404 reported).")
374364
break
375365
if attempt < retries:
376-
print(
377-
f" Table delete retry {attempt}/{retries} after error ({err}). Waiting {delay_seconds}s..."
378-
)
366+
print(f" Table delete retry {attempt}/{retries} after error ({err}). Waiting {delay_seconds}s...")
379367
time.sleep(delay_seconds)
380368
continue
381369
print(f"[WARN] Failed to delete test table: {err}")

src/PowerPlatform/Dataverse/data/_upload.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def _upload_file_chunk(
145145
headers["If-None-Match"] = "null"
146146
else:
147147
headers["If-Match"] = "*"
148-
r_init = self._request("patch", init_url, headers=headers, data=b"")
148+
r_init, _ = self._request("patch", init_url, headers=headers, data=b"")
149149
location = r_init.headers.get("Location") or r_init.headers.get("location")
150150
if not location:
151151
raise RuntimeError("Missing Location header with sessiontoken for chunked upload")

0 commit comments

Comments
 (0)