Skip to content

Commit 919b6ca

Browse files
chore: Python v2 migration (#135)
After merging these changes there are steps if you're using custom hooks. Please see: https://www.speakeasy.com/docs/python-migration#4-adjust-imports-for-python-v2 --------- Co-authored-by: Austin Walker <[email protected]>
1 parent 5f99db3 commit 919b6ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3253
-1753
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
steps:
3737
- uses: actions/checkout@v4
3838
- name: Install dependencies
39-
run: pip install .[dev]
39+
run: pip install pylint
4040
- name: Lint
4141
run: make lint
4242

.github/workflows/speakeasy_sdk_generation.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,11 @@ jobs:
2424
github_access_token: ${{ secrets.GITHUB_TOKEN }}
2525
pypi_token: ${{ secrets.PYPI_TOKEN }}
2626
speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
27+
# We don't need this unless we're modifying the generated code
28+
patch-custom-code:
29+
runs-on: ubuntu-latest
30+
needs: [generate]
31+
steps:
32+
- name: Patch in custom code after regenerating
33+
run: make patch-custom-code
34+

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
pyrightconfig.json
12
venv/
23
src/*.egg-info/
34
__pycache__/
45
.pytest_cache/
56
.python-version
67
.DS_Store
7-
88
# human-added igore files
99
.ipynb_checkpoints/
1010
.idea/

.speakeasy/gen.lock

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,76 @@
11
lockVersion: 2.0.0
22
id: 8b5fa338-9106-4734-abf0-e30d67044a90
33
management:
4-
docChecksum: 17bd23e4247d7b65a92813afd1252693
4+
docChecksum: a6ff17ff485bb4b5884d75af244e18a1
55
docVersion: 1.0.44
6-
speakeasyVersion: 1.361.1
7-
generationVersion: 2.393.4
8-
releaseVersion: 0.25.5
9-
configChecksum: 6b4c1555edde75f4f1e422e49a07c208
6+
speakeasyVersion: 1.346.0
7+
generationVersion: 2.379.3
8+
releaseVersion: 0.26.0-beta
9+
configChecksum: 96c9dbe127b795111b840819ebcc996d
1010
repoURL: https://github.com/Unstructured-IO/unstructured-python-client.git
1111
repoSubDirectory: .
1212
installationURL: https://github.com/Unstructured-IO/unstructured-python-client.git
1313
published: true
1414
features:
1515
python:
16-
additionalDependencies: 0.1.0
17-
constsAndDefaults: 0.1.4
18-
core: 4.8.4
19-
examples: 2.81.3
20-
globalSecurity: 2.83.7
21-
globalSecurityCallbacks: 0.1.0
22-
globalSecurityFlattening: 0.1.0
23-
globalServerURLs: 2.82.2
24-
nameOverrides: 2.81.2
25-
nullables: 0.1.0
26-
openEnums: 0.1.0
27-
responseFormat: 0.1.0
28-
retries: 2.82.2
29-
sdkHooks: 0.1.0
30-
serverIDs: 2.81.1
31-
unions: 2.82.9
16+
additionalDependencies: 1.0.0
17+
constsAndDefaults: 1.0.0
18+
core: 5.2.4
19+
defaultEnabledRetries: 0.2.0
20+
envVarSecurityUsage: 0.2.0
21+
examples: 3.0.0
22+
globalSecurity: 3.0.0
23+
globalSecurityCallbacks: 1.0.0
24+
globalSecurityFlattening: 1.0.0
25+
globalServerURLs: 3.0.0
26+
multipartFileContentType: 1.0.0
27+
nameOverrides: 3.0.0
28+
nullables: 1.0.0
29+
openEnums: 1.0.0
30+
responseFormat: 1.0.0
31+
retries: 3.0.0
32+
sdkHooks: 1.0.0
33+
serverIDs: 3.0.0
34+
unions: 3.0.1
35+
uploadStreams: 1.0.0
3236
generatedFiles:
3337
- src/unstructured_client/sdkconfiguration.py
3438
- src/unstructured_client/general.py
3539
- src/unstructured_client/sdk.py
40+
- .vscode/settings.json
3641
- py.typed
3742
- pylintrc
43+
- pyproject.toml
3844
- scripts/publish.sh
39-
- setup.py
4045
- src/unstructured_client/__init__.py
46+
- src/unstructured_client/basesdk.py
47+
- src/unstructured_client/httpclient.py
48+
- src/unstructured_client/py.typed
49+
- src/unstructured_client/types/__init__.py
50+
- src/unstructured_client/types/basemodel.py
4151
- src/unstructured_client/utils/__init__.py
52+
- src/unstructured_client/utils/annotations.py
4253
- src/unstructured_client/utils/enums.py
54+
- src/unstructured_client/utils/eventstreaming.py
55+
- src/unstructured_client/utils/forms.py
56+
- src/unstructured_client/utils/headers.py
57+
- src/unstructured_client/utils/metadata.py
58+
- src/unstructured_client/utils/queryparams.py
59+
- src/unstructured_client/utils/requestbodies.py
4360
- src/unstructured_client/utils/retries.py
44-
- src/unstructured_client/utils/utils.py
61+
- src/unstructured_client/utils/security.py
62+
- src/unstructured_client/utils/serializers.py
63+
- src/unstructured_client/utils/url.py
64+
- src/unstructured_client/utils/values.py
4565
- src/unstructured_client/models/errors/sdkerror.py
4666
- src/unstructured_client/models/operations/partition.py
67+
- src/unstructured_client/models/operations/__init__.py
4768
- src/unstructured_client/models/errors/httpvalidationerror.py
4869
- src/unstructured_client/models/errors/servererror.py
70+
- src/unstructured_client/models/errors/__init__.py
4971
- src/unstructured_client/models/shared/validationerror.py
5072
- src/unstructured_client/models/shared/partition_parameters.py
5173
- src/unstructured_client/models/shared/security.py
52-
- src/unstructured_client/models/__init__.py
53-
- src/unstructured_client/models/errors/__init__.py
54-
- src/unstructured_client/models/operations/__init__.py
5574
- src/unstructured_client/models/shared/__init__.py
5675
- docs/models/operations/partitionrequest.md
5776
- docs/models/operations/partitionresponse.md

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ client-generate-local:
6767
speakeasy overlay apply -s ./openapi.json -o ./overlay_client.yaml > ./openapi_client.json
6868
speakeasy generate sdk -s ./openapi_client.json -o ./ -l python
6969

70+
.PHONY: patch-custom-code
71+
patch-custom-code:
72+
git apply _custom_code.patch
73+
7074
.PHONY: publish
7175
publish:
7276
./scripts/publish.sh

README.md

Lines changed: 151 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,15 @@ Please refer to the [Unstructured docs](https://docs.unstructured.io/api-referen
3030
<!-- Start SDK Installation [installation] -->
3131
## SDK Installation
3232

33+
PIP
3334
```bash
3435
pip install unstructured-client
3536
```
37+
38+
Poetry
39+
```bash
40+
poetry add unstructured-client
41+
```
3642
<!-- End SDK Installation [installation] -->
3743

3844
## SDK Example Usage
@@ -131,28 +137,30 @@ Some of the endpoints in this SDK support retries. If you use the SDK without an
131137

132138
To change the default retry strategy for a single API call, simply provide a `RetryConfig` object to the call:
133139
```python
134-
import unstructured_client
135-
from unstructured_client.models import operations, shared
140+
from unstructured_client import UnstructuredClient
141+
from unstructured_client.models import shared
136142
from unstructured_client.utils import BackoffStrategy, RetryConfig
137143

138-
s = unstructured_client.UnstructuredClient()
144+
s = UnstructuredClient(
145+
api_key_auth="YOUR_API_KEY",
146+
)
139147

140148

141-
res = s.general.partition(request=operations.PartitionRequest(
142-
partition_parameters=shared.PartitionParameters(
143-
files=shared.Files(
144-
content='0x2cC94b2FEF'.encode(),
145-
file_name='your_file_here',
146-
),
147-
chunking_strategy=shared.ChunkingStrategy.BY_TITLE,
148-
split_pdf_page_range=[
149+
res = s.general.partition(request={
150+
"partition_parameters": {
151+
"files": {
152+
"content": open("<file_path>", "rb"),
153+
"file_name": "your_file_here",
154+
},
155+
"chunking_strategy": shared.ChunkingStrategy.BY_TITLE,
156+
"split_pdf_page_range": [
149157
1,
150158
10,
151159
],
152-
strategy=shared.Strategy.HI_RES,
153-
),
154-
),
155-
RetryConfig('backoff', BackoffStrategy(1, 50, 1.1, 100), False))
160+
"strategy": shared.Strategy.HI_RES,
161+
},
162+
},
163+
RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False))
156164

157165
if res.elements is not None:
158166
# handle response
@@ -162,29 +170,30 @@ if res.elements is not None:
162170

163171
If you'd like to override the default retry strategy for all operations that support retries, you can use the `retry_config` optional parameter when initializing the SDK:
164172
```python
165-
import unstructured_client
166-
from unstructured_client.models import operations, shared
173+
from unstructured_client import UnstructuredClient
174+
from unstructured_client.models import shared
167175
from unstructured_client.utils import BackoffStrategy, RetryConfig
168176

169-
s = unstructured_client.UnstructuredClient(
170-
retry_config=RetryConfig('backoff', BackoffStrategy(1, 50, 1.1, 100), False),
177+
s = UnstructuredClient(
178+
retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False),
179+
api_key_auth="YOUR_API_KEY",
171180
)
172181

173182

174-
res = s.general.partition(request=operations.PartitionRequest(
175-
partition_parameters=shared.PartitionParameters(
176-
files=shared.Files(
177-
content='0x2cC94b2FEF'.encode(),
178-
file_name='your_file_here',
179-
),
180-
chunking_strategy=shared.ChunkingStrategy.BY_TITLE,
181-
split_pdf_page_range=[
183+
res = s.general.partition(request={
184+
"partition_parameters": {
185+
"files": {
186+
"content": open("<file_path>", "rb"),
187+
"file_name": "your_file_here",
188+
},
189+
"chunking_strategy": shared.ChunkingStrategy.BY_TITLE,
190+
"split_pdf_page_range": [
182191
1,
183192
10,
184193
],
185-
strategy=shared.Strategy.HI_RES,
186-
),
187-
))
194+
"strategy": shared.Strategy.HI_RES,
195+
},
196+
})
188197

189198
if res.elements is not None:
190199
# handle response
@@ -196,16 +205,81 @@ if res.elements is not None:
196205
<!-- Start Custom HTTP Client [http-client] -->
197206
## Custom HTTP Client
198207

199-
The Python SDK makes API calls using the [requests](https://pypi.org/project/requests/) HTTP library. In order to provide a convenient way to configure timeouts, cookies, proxies, custom headers, and other low-level configuration, you can initialize the SDK client with a custom `requests.Session` object.
208+
The Python SDK makes API calls using the [httpx](https://www.python-httpx.org/) HTTP library. In order to provide a convenient way to configure timeouts, cookies, proxies, custom headers, and other low-level configuration, you can initialize the SDK client with your own HTTP client instance.
209+
Depending on whether you are using the sync or async version of the SDK, you can pass an instance of `HttpClient` or `AsyncHttpClient` respectively, which are Protocol's ensuring that the client has the necessary methods to make API calls.
210+
This allows you to wrap the client with your own custom logic, such as adding custom headers, logging, or error handling, or you can just pass an instance of `httpx.Client` or `httpx.AsyncClient` directly.
200211

201212
For example, you could specify a header for every request that this sdk makes as follows:
202213
```python
203-
import unstructured_client
204-
import requests
214+
from unstructured_client import UnstructuredClient
215+
import httpx
216+
217+
http_client = httpx.Client(headers={"x-custom-header": "someValue"})
218+
s = UnstructuredClient(client=http_client)
219+
```
205220

206-
http_client = requests.Session()
207-
http_client.headers.update({'x-custom-header': 'someValue'})
208-
s = unstructured_client.UnstructuredClient(client=http_client)
221+
or you could wrap the client with your own custom logic:
222+
```python
223+
from unstructured_client import UnstructuredClient
224+
from unstructured_client.httpclient import AsyncHttpClient
225+
import httpx
226+
227+
class CustomClient(AsyncHttpClient):
228+
client: AsyncHttpClient
229+
230+
def __init__(self, client: AsyncHttpClient):
231+
self.client = client
232+
233+
async def send(
234+
self,
235+
request: httpx.Request,
236+
*,
237+
stream: bool = False,
238+
auth: Union[
239+
httpx._types.AuthTypes, httpx._client.UseClientDefault, None
240+
] = httpx.USE_CLIENT_DEFAULT,
241+
follow_redirects: Union[
242+
bool, httpx._client.UseClientDefault
243+
] = httpx.USE_CLIENT_DEFAULT,
244+
) -> httpx.Response:
245+
request.headers["Client-Level-Header"] = "added by client"
246+
247+
return await self.client.send(
248+
request, stream=stream, auth=auth, follow_redirects=follow_redirects
249+
)
250+
251+
def build_request(
252+
self,
253+
method: str,
254+
url: httpx._types.URLTypes,
255+
*,
256+
content: Optional[httpx._types.RequestContent] = None,
257+
data: Optional[httpx._types.RequestData] = None,
258+
files: Optional[httpx._types.RequestFiles] = None,
259+
json: Optional[Any] = None,
260+
params: Optional[httpx._types.QueryParamTypes] = None,
261+
headers: Optional[httpx._types.HeaderTypes] = None,
262+
cookies: Optional[httpx._types.CookieTypes] = None,
263+
timeout: Union[
264+
httpx._types.TimeoutTypes, httpx._client.UseClientDefault
265+
] = httpx.USE_CLIENT_DEFAULT,
266+
extensions: Optional[httpx._types.RequestExtensions] = None,
267+
) -> httpx.Request:
268+
return self.client.build_request(
269+
method,
270+
url,
271+
content=content,
272+
data=data,
273+
files=files,
274+
json=json,
275+
params=params,
276+
headers=headers,
277+
cookies=cookies,
278+
timeout=timeout,
279+
extensions=extensions,
280+
)
281+
282+
s = UnstructuredClient(async_client=CustomClient(httpx.AsyncClient()))
209283
```
210284
<!-- End Custom HTTP Client [http-client] -->
211285

@@ -216,6 +290,47 @@ s = unstructured_client.UnstructuredClient(client=http_client)
216290
<!-- No Server Selection -->
217291
<!-- No Authentication -->
218292

293+
<!-- Start File uploads [file-upload] -->
294+
## File uploads
295+
296+
Certain SDK methods accept file objects as part of a request body or multi-part request. It is possible and typically recommended to upload files as a stream rather than reading the entire contents into memory. This avoids excessive memory consumption and potentially crashing with out-of-memory errors when working with very large files. The following example demonstrates how to attach a file stream to a request.
297+
298+
> [!TIP]
299+
>
300+
> For endpoints that handle file uploads bytes arrays can also be used. However, using streams is recommended for large files.
301+
>
302+
303+
```python
304+
from unstructured_client import UnstructuredClient
305+
from unstructured_client.models import shared
306+
307+
s = UnstructuredClient(
308+
api_key_auth="YOUR_API_KEY",
309+
)
310+
311+
312+
res = s.general.partition(request={
313+
"partition_parameters": {
314+
"files": {
315+
"content": open("<file_path>", "rb"),
316+
"file_name": "your_file_here",
317+
},
318+
"chunking_strategy": shared.ChunkingStrategy.BY_TITLE,
319+
"split_pdf_page_range": [
320+
1,
321+
10,
322+
],
323+
"strategy": shared.Strategy.HI_RES,
324+
},
325+
})
326+
327+
if res.elements is not None:
328+
# handle response
329+
pass
330+
331+
```
332+
<!-- End File uploads [file-upload] -->
333+
219334
<!-- Placeholder for Future Speakeasy SDK Sections -->
220335

221336
### Maturity

0 commit comments

Comments
 (0)