Repository navigation
Expand file tree
/
Copy pathtest_declared_errors.py
More file actions
148 lines (123 loc) · 4.99 KB
/
Copy pathtest_declared_errors.py
File metadata and controls
148 lines (123 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import asyncio
import json
import httpx
import pytest
from unstructured_client import UnstructuredClient
from unstructured_client.models.errors import (
HTTPValidationError,
HTTPValidationErrorData,
ResponseValidationError,
SDKError,
ServerError,
ServerErrorData,
)
from unstructured_client.utils import BackoffStrategy, RetryConfig
from unstructured_client.utils.declared_errors import (
DeclaredErrorFields,
parse_declared_error_fields,
)
DECLARED_BODY = {
"detail": "OCR timed out",
"retryable": False,
"error_type": "timeout",
"error_reason": "ocr_timeout",
"audience": "platform",
}
DECLARED_FIELDS = DeclaredErrorFields(
retryable=False, error_type="timeout", error_reason="ocr_timeout", audience="platform"
)
def _response(status_code: int, **kwargs) -> httpx.Response:
return httpx.Response(
status_code,
request=httpx.Request("POST", "http://test.invalid/general/v0/general"),
**kwargs,
)
def _declared(error) -> DeclaredErrorFields:
return DeclaredErrorFields(
retryable=error.retryable,
error_type=error.error_type,
error_reason=error.error_reason,
audience=error.audience,
)
@pytest.mark.parametrize(
"text,expected",
[
('{"detail":"x","retryable":false,"error_type":"timeout",'
'"error_reason":"ocr_timeout","audience":"platform"}', DECLARED_FIELDS),
('{"retryable":true}', DeclaredErrorFields(retryable=True)),
('{"detail":"x","retryable":false,"audience":null}', DeclaredErrorFields(retryable=False)),
('{"detail":"Internal server error"}', DeclaredErrorFields()),
('{"retryable":"false","error_type":5,"error_reason":" ","audience":[]}',
DeclaredErrorFields()),
('{"retryable":0}', DeclaredErrorFields()),
('[{"retryable":false}]', DeclaredErrorFields()),
("false", DeclaredErrorFields()),
("{broken", DeclaredErrorFields()),
("upstream error", DeclaredErrorFields()),
("", DeclaredErrorFields()),
(None, DeclaredErrorFields()),
pytest.param(
'{"retryable":false,"detail":' + "[" * 100_000 + "]" * 100_000 + "}",
DeclaredErrorFields(),
id="deeply-nested",
),
],
)
def test_parse_declared_error_fields(text, expected):
assert parse_declared_error_fields(text) == expected
@pytest.mark.parametrize(
"build",
[
lambda r: ServerError(ServerErrorData(detail="OCR timed out"), r),
lambda r: SDKError("API error occurred", r, r.text),
lambda r: HTTPValidationError(HTTPValidationErrorData(detail="OCR timed out"), r),
],
ids=["ServerError", "SDKError", "HTTPValidationError"],
)
@pytest.mark.parametrize(
"content",
[
json.dumps(DECLARED_BODY).encode(),
b"\xef\xbb\xbf" + json.dumps(DECLARED_BODY).encode(),
json.dumps(DECLARED_BODY).encode("utf-16"),
],
ids=["utf-8", "utf-8-bom", "utf-16"],
)
def test_error_classes_expose_declared_fields(build, content):
response = _response(503, content=content, headers={"Content-Type": "application/json"})
assert _declared(build(response)) == DECLARED_FIELDS
def test_unread_stream_falls_back_to_body():
class Stream(httpx.SyncByteStream):
def __iter__(self):
pytest.fail("error construction read an unread stream")
yield b""
response = _response(503, stream=Stream())
error = SDKError("API error occurred", response, json.dumps(DECLARED_BODY))
assert _declared(error) == DECLARED_FIELDS
def test_success_response_declares_nothing():
response = _response(200, json=DECLARED_BODY)
error = ResponseValidationError("Response validation failed", response, ValueError())
assert _declared(error) == DeclaredErrorFields()
@pytest.mark.parametrize("async_mode", [False, True])
@pytest.mark.parametrize("status_code,error_class", [(400, SDKError), (503, ServerError)])
def test_public_partition_raises_declared_fields(async_mode, status_code, error_class):
def respond(request):
return httpx.Response(status_code, json=DECLARED_BODY)
transport = httpx.MockTransport(respond)
request = {"partition_parameters": {
"files": {"content": b"hello", "file_name": "test.txt"},
"split_pdf_page": False,
}}
retries = RetryConfig("none", BackoffStrategy(1, 1, 1.0, 1), False)
async def run_async():
async with httpx.AsyncClient(transport=transport) as async_client:
sdk = UnstructuredClient(server_url="http://test.invalid", async_client=async_client)
await sdk.general.partition_async(request=request, retries=retries)
with pytest.raises(error_class) as exc:
if async_mode:
asyncio.run(run_async())
else:
with httpx.Client(transport=transport) as client:
sdk = UnstructuredClient(server_url="http://test.invalid", client=client)
sdk.general.partition(request=request, retries=retries)
assert _declared(exc.value) == DECLARED_FIELDS