clerk-sdk 0.4.5__py3-none-any.whl → 0.4.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
clerk/__init__.py CHANGED
@@ -1 +1,4 @@
1
1
  from .client import Clerk
2
+
3
+
4
+ __version__ = "0.4.6"
clerk/client.py CHANGED
@@ -14,6 +14,78 @@ class Clerk(BaseClerk):
14
14
  )
15
15
  return Document(**res.data[0])
16
16
 
17
+ def cancel_document_run(self, document_id: str) -> Document:
18
+ endpoint = f"/document/{document_id}/cancel"
19
+ res = self.post_request(endpoint=endpoint)
20
+ return Document(**res.data[0])
21
+
22
+ def update_document_structured_data(
23
+ self, document_id: str, updated_structured_data: Dict[str, Any]
24
+ ) -> Document:
25
+ endpoint = f"/document/{document_id}"
26
+ payload = dict(structured_data=updated_structured_data)
27
+ res = self.put_request(endpoint, json=payload)
28
+
29
+ return Document(**res.data[0])
30
+
31
+ def get_document(self, document_id: str) -> Document:
32
+ endpoint = f"/document/{document_id}"
33
+ res = self.get_request(endpoint=endpoint)
34
+ return Document(**res.data[0])
35
+
36
+ def get_documents(self, request: GetDocumentsRequest) -> List[Document]:
37
+ if not any(
38
+ [
39
+ request.organization_id,
40
+ request.project_id,
41
+ request.start_date,
42
+ request.end_date,
43
+ request.query,
44
+ request.include_statuses,
45
+ ]
46
+ ):
47
+ raise ValueError(
48
+ "At least one query parameter (organization_id, project_id, start_date, end_date, query, or include_statuses) must be provided."
49
+ )
50
+
51
+ endpoint = f"/documents"
52
+ params = request.model_dump(mode="json")
53
+ res = self.get_request(endpoint, params=params)
54
+
55
+ return [Document(**d) for d in res.data]
56
+
57
+ def get_files_document(self, document_id: str) -> List[ParsedFile]:
58
+ endpoint = f"/document/{document_id}/files"
59
+ res = self.get_request(endpoint=endpoint)
60
+ return [ParsedFile(**d) for d in res.data]
61
+
62
+ def add_files_to_document(
63
+ self,
64
+ document_id: str,
65
+ type: Literal["input", "output"],
66
+ files: List[UploadFile],
67
+ ):
68
+ endpoint = f"/document/{document_id}/files/upload"
69
+ params = {"type": type}
70
+ files_data = [f.to_multipart_format() for f in files]
71
+ self.post_request(endpoint, params=params, files=files_data)
72
+
73
+
74
+ class ClerkDocument(BaseClerk):
75
+ endpoint: str = "/document"
76
+
77
+ def upload_document(self, request: UploadDocumentRequest) -> Document:
78
+ endpoint = "/document"
79
+ res = self.post_request(
80
+ endpoint=endpoint, data=request.data, files=request.files_
81
+ )
82
+ return Document(**res.data[0])
83
+
84
+ def cancel_document_run(self, document_id: str) -> Document:
85
+ endpoint = f"/document/{document_id}/cancel"
86
+ res = self.post_request(endpoint=endpoint)
87
+ return Document(**res.data[0])
88
+
17
89
  def update_document_structured_data(
18
90
  self, document_id: str, updated_structured_data: Dict[str, Any]
19
91
  ) -> Document:
clerk/utils/logger.py CHANGED
@@ -6,7 +6,10 @@ import sys
6
6
  if sys.platform == "win32":
7
7
  base_path = os.path.join(os.getcwd(), "data", "artifacts")
8
8
  else:
9
- base_path = "/app/data/artifacts"
9
+ if os.getenv("__TEST"):
10
+ base_path = os.path.join(os.getcwd(), "data", "artifacts")
11
+ else:
12
+ base_path = "/app/data/artifacts"
10
13
 
11
14
  os.makedirs(base_path, exist_ok=True)
12
15
 
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.4
2
+ Name: clerk-sdk
3
+ Version: 0.4.6
4
+ Summary: Library for interacting with Clerk
5
+ Home-page: https://github.com/F-ONE-Group/clerk_pypi
6
+ Author: F-ONE Group
7
+ Author-email: admin@f-one.group
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
15
+ Requires-Dist: backoff<3.0.0,>=2.0.0
16
+ Requires-Dist: requests<3.0.0,>=2.32.3
17
+ Provides-Extra: all
18
+ Requires-Dist: pydantic<3.0.0,>=2.0.0; extra == "all"
19
+ Requires-Dist: backoff<3.0.0,>=2.0.0; extra == "all"
20
+ Requires-Dist: requests<3.0.0,>=2.32.3; extra == "all"
21
+ Requires-Dist: networkx<4.0.0,>=3.5.0; extra == "all"
22
+ Requires-Dist: websockets>=15.0.1; extra == "all"
23
+ Provides-Extra: gui-automation
24
+ Requires-Dist: networkx<4.0.0,>=3.5.0; extra == "gui-automation"
25
+ Requires-Dist: websockets>=15.0.1; extra == "gui-automation"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license-file
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ # Clerk Python SDK
39
+
40
+ A production-ready Python client for the Clerk API. The SDK wraps Clerk's REST endpoints, rich document models, automation helpers, and structured task decorators so that your applications can create, update, and process Clerk documents with minimal boilerplate.
41
+
42
+ ## Table of Contents
43
+ - [Overview](#overview)
44
+ - [Key Features](#key-features)
45
+ - [Requirements](#requirements)
46
+ - [Installation](#installation)
47
+ - [Configuration](#configuration)
48
+ - [Quick Start](#quick-start)
49
+ - [Instantiate a Client](#instantiate-a-client)
50
+ - [Fetch Documents](#fetch-documents)
51
+ - [Upload a Document](#upload-a-document)
52
+ - [Update Structured Data](#update-structured-data)
53
+ - [Work with Files](#work-with-files)
54
+ - [Automation Utilities](#automation-utilities)
55
+ - [Task Decorator](#task-decorator)
56
+ - [GUI Automation Toolkit](#gui-automation-toolkit)
57
+ - [Error Handling](#error-handling)
58
+ - [Development Workflow](#development-workflow)
59
+ - [Contributing](#contributing)
60
+ - [License](#license)
61
+
62
+ ## Overview
63
+ The Clerk SDK centers around the `Clerk` client (`clerk.client.Clerk`), which extends a resilient `BaseClerk` transport layer with automatic retries and typed responses. Models under `clerk.models` provide Pydantic-powered validation for documents, files, and API payloads, ensuring type safety across network boundaries. Additional modules cover automated task execution via the `clerk.decorator` package and UI workflows under `clerk.gui_automation`.
64
+
65
+ ## Key Features
66
+ - **Document lifecycle management** – Create, fetch, list, and update Clerk documents with first-class models.
67
+ - **File handling** – Upload binary files or parsed base64 payloads and attach them to documents.
68
+ - **Robust networking** – Automatic retries for transient HTTP issues, configurable base URLs, and bearer authentication out of the box.
69
+ - **Structured task execution** – Decorators for running Clerk tasks locally or inside worker environments with consistent pickle-based I/O.
70
+ - **GUI automations** – Utilities for orchestrating low-level UI actions, state machines, and operator interactions when human-in-the-loop steps are required.
71
+
72
+ ## Requirements
73
+ - Python 3.10+
74
+ - Dependencies listed in [`requirements.txt`](requirements.txt), including `pydantic` and `backoff`.
75
+
76
+ ## Installation
77
+ Install the SDK from PyPI:
78
+
79
+ ```bash
80
+ pip install clerk-sdk
81
+ ```
82
+
83
+ For local development inside this repository, install the dependencies in editable mode:
84
+
85
+ ```bash
86
+ pip install -e .[dev]
87
+ ```
88
+
89
+ ## Configuration
90
+ The client reads configuration from keyword arguments or environment variables.
91
+
92
+ | Setting | Environment Variable | Description |
93
+ | --- | --- | --- |
94
+ | API key | `CLERK_API_KEY` | Required secret used for bearer authentication. |
95
+ | Base URL | `CLERK_BASE_URL` | Optional override of the default API host (`https://api.clerk-app.com`). |
96
+
97
+ ```bash
98
+ export CLERK_API_KEY="sk_live_123"
99
+ export CLERK_BASE_URL="https://staging.clerk-app.com" # optional
100
+ ```
101
+
102
+ You can also pass the API key directly when instantiating `Clerk`:
103
+
104
+ ```python
105
+ from clerk import Clerk
106
+
107
+ client = Clerk(api_key="sk_live_123")
108
+ ```
109
+
110
+ ## Quick Start
111
+ The following snippets demonstrate the core document operations supported by the SDK.
112
+
113
+ ### Instantiate a Client
114
+ ```python
115
+ from clerk import Clerk
116
+
117
+ client = Clerk(api_key="sk_live_123")
118
+ ```
119
+
120
+ ### Fetch Documents
121
+ Retrieve a single document by its identifier or list documents with query filters.
122
+
123
+ ```python
124
+ from clerk.models.document import GetDocumentsRequest
125
+
126
+ # Single document
127
+ invoice = client.get_document(document_id="doc_123")
128
+ print(invoice.title, invoice.status)
129
+
130
+ # Query multiple documents
131
+ request = GetDocumentsRequest(project_id="proj_456", limit=25)
132
+ documents = client.get_documents(request)
133
+ for doc in documents:
134
+ print(doc.id, doc.status)
135
+ ```
136
+
137
+ ### Upload a Document
138
+ Use `UploadDocumentRequest` to send metadata and file attachments. Files can be supplied as paths or `ParsedFile` instances.
139
+
140
+ ```python
141
+ from clerk.models.document import UploadDocumentRequest
142
+
143
+ upload_request = UploadDocumentRequest(
144
+ project_id="proj_456",
145
+ message_subject="Invoice 2024-01",
146
+ files=["/path/to/invoice.pdf"],
147
+ input_structured_data={"customer_id": "cust_789"},
148
+ )
149
+
150
+ created = client.upload_document(upload_request)
151
+ print(f"Created document: {created.id}")
152
+ ```
153
+
154
+ ### Update Structured Data
155
+ Patch a document's structured payload without re-uploading files.
156
+
157
+ ```python
158
+ updated = client.update_document_structured_data(
159
+ document_id="doc_123",
160
+ updated_structured_data={"status": "processed", "processed_by": "automation"},
161
+ )
162
+ print(updated.structured_data)
163
+ ```
164
+
165
+ ### Work with Files
166
+ Retrieve parsed file metadata or attach additional files to existing documents.
167
+
168
+ ```python
169
+ from clerk.models.file import UploadFile
170
+
171
+ # List associated files
172
+ files = client.get_files_document(document_id="doc_123")
173
+ for file in files:
174
+ print(file.name, file.mimetype)
175
+
176
+ # Append output files
177
+ client.add_files_to_document(
178
+ document_id="doc_123",
179
+ type="output",
180
+ files=[
181
+ UploadFile(name="summary.txt", mimetype="text/plain", content=b"Processed")
182
+ ],
183
+ )
184
+ ```
185
+
186
+ ## Custom Code Utilities
187
+ ### Task Decorator
188
+ The `@clerk_code` decorator standardizes how Clerk tasks load inputs and persist outputs when executed by the Clerk workflow. It automatically reads a pickled `ClerkCodePayload` from `/app/data/input/input.pkl`, executes your function, and writes the result (or an `ApplicationException`) to `/app/data/output/output.pkl`.
189
+
190
+ ```python
191
+ from clerk.decorator import clerk_code
192
+ from clerk.decorator.models import ClerkCodePayload, Document
193
+
194
+ @clerk_code()
195
+ def handle_document(payload: ClerkCodePayload) -> ClerkCodePayload:
196
+ document: Document = payload.document
197
+ payload.structured_data = payload.structured_data or {}
198
+ payload.structured_data["status"] = f"Processed {document.id}"
199
+ return payload
200
+
201
+ if __name__ == "__main__":
202
+ handle_document() # Auto-loads from pickle files when payload is omitted
203
+ ```
204
+
205
+ For unit testing, you can bypass the pickle integration by passing an explicit payload instance:
206
+
207
+ ```python
208
+ from datetime import datetime
209
+ from clerk.decorator.models import ClerkCodePayload, Document
210
+ from clerk.models.document_statuses import DocumentStatuses
211
+
212
+ sample_payload = ClerkCodePayload(
213
+ document=Document(
214
+ id="doc_123",
215
+ project_id="proj_456",
216
+ title="Sample",
217
+ upload_date=datetime.utcnow(),
218
+ status=DocumentStatuses.draft,
219
+ created_at=datetime.utcnow(),
220
+ updated_at=datetime.utcnow(),
221
+ ),
222
+ structured_data={},
223
+ )
224
+ result = handle_document(sample_payload)
225
+ assert "Processed" in result.structured_data["status"]
226
+ ```
227
+
228
+ > **Note:** Refer to `tests/test_task_decorator.py` for additional usage examples covering error propagation and pickle round-trips.
229
+
230
+ ### GUI Automation Toolkit
231
+ The `clerk.gui_automation` package contains models, actions, and state machines for orchestrating UI interactions. Highlights include:
232
+
233
+ - `BaseAction` and concrete actions for cursor movement, clicks, and keyboard input.
234
+ - `ActionModel` builders that translate payloads into executable UI sequences.
235
+ - State machine primitives (`ui_state_machine`) to coordinate multi-step automations.
236
+ - Helpers for safely reading files, validating anchors, and converting payload flags.
237
+
238
+ These utilities are designed to be composed with your own automation runners or integrated into Clerk tasks. Review the tests in `tests/test_gui_automation.py` for patterns on stubbing operator clients and verifying payload transformations.
239
+
240
+ ## Error Handling
241
+ All network helpers raise `requests` exceptions for HTTP errors. When using the task decorator, runtime failures are wrapped in `ApplicationException` objects that capture the exception type, message, and traceback for easier debugging. Deserialize the returned payload or inspect the pickle output to handle errors gracefully.
242
+
243
+ ## Development Workflow
244
+ 1. **Clone the repository** and install dependencies with `pip install -e .[dev]`.
245
+ 2. **Run the test suite** using `pytest`. The CI workflow executes these tests before packaging releases.
246
+ 3. **Add type-safe models** or extend the client in `clerk/client.py` and `clerk/models` as needed.
247
+ 4. **Contribute automations** under `clerk/gui_automation` by following the established action/state machine patterns.
248
+ 5. **Commit and open a pull request** once tests pass and documentation is updated.
249
+
250
+ ## Contributing
251
+ Contributions are welcome! Please open an issue to discuss substantial changes, follow the existing code style (Pydantic models, typed functions, and pytest fixtures), and ensure the test suite passes before submitting a pull request.
252
+
253
+ ## License
254
+ This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
@@ -1,6 +1,6 @@
1
- clerk/__init__.py,sha256=LWpbImG7352mUJYC1tRm_zsn5rnt4sFl5ldoq5f0dlo,26
1
+ clerk/__init__.py,sha256=ubAUuMPlxiWOVmwL7aMXdRDmiXjmyqibfKLX5ZcLZR4,50
2
2
  clerk/base.py,sha256=S1RKc2pBw2FPlVjefJzsNtyTDPB0UG46C2K_QVV1opA,4008
3
- clerk/client.py,sha256=Ma6nCICRBjgdcntPaEJv8baMBr7zftKeLcEzfD634eA,2368
3
+ clerk/client.py,sha256=RdOvC23WK9ZtIXDOYaoSFk9debh3UTmstBXjAswAH6E,4981
4
4
  clerk/decorator/__init__.py,sha256=yGGcS17VsZ7cZ-hVGCm3I3vGDJMiJIAqmDGzriIi0DI,65
5
5
  clerk/decorator/models.py,sha256=PiAugPvX1c6BQBWtfhyh5k9Uau2OJNDIx7T1TLz7ZFY,409
6
6
  clerk/decorator/task_decorator.py,sha256=H8caRvNvvl-IRwyREP66gBGVM-SpQJ1W7oAFImO-6Jw,3769
@@ -44,10 +44,10 @@ clerk/models/remote_device.py,sha256=2jijS-9WWq7y6xIbAaDaPnzZo3-tjp2-dCQvNKP8YSU
44
44
  clerk/models/response_model.py,sha256=R62daUN1YVOwgnrh_epvFRsQcOwT7R4u97l73egvm-c,232
45
45
  clerk/models/ui_operator.py,sha256=mKTJUFZgv7PeEt5oys28HVZxHOJsofmRQOcRpqj0dbU,293
46
46
  clerk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- clerk/utils/logger.py,sha256=vHbp-lUK3W3c5fhyPsp05p9LGyDHj95v8XM_XQ_FlLc,3691
47
+ clerk/utils/logger.py,sha256=NrMIlJfVmRjjRw_N_Jngkl0qqv7btXUbg5wxcRmFEH4,3800
48
48
  clerk/utils/save_artifact.py,sha256=94aYkYNVGcSUaSWZmdjiY6Oc-3yCKb2XWCZ56IAXQqk,1158
49
- clerk_sdk-0.4.5.dist-info/licenses/LICENSE,sha256=GTVQl3vH6ht70wJXKC0yMT8CmXKHxv_YyO_utAgm7EA,1065
50
- clerk_sdk-0.4.5.dist-info/METADATA,sha256=KmIcyeV5XxdLTtq4m3gAtB9S-zYp2yI4l5ZP4EcrBlY,3508
51
- clerk_sdk-0.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
- clerk_sdk-0.4.5.dist-info/top_level.txt,sha256=99eQiU6d05_-f41tmSFanfI_SIJeAdh7u9m3LNSfcv4,6
53
- clerk_sdk-0.4.5.dist-info/RECORD,,
49
+ clerk_sdk-0.4.6.dist-info/licenses/LICENSE,sha256=GTVQl3vH6ht70wJXKC0yMT8CmXKHxv_YyO_utAgm7EA,1065
50
+ clerk_sdk-0.4.6.dist-info/METADATA,sha256=gn2Ih5DuBL3CSIvPbu5HPEmw5DunhRv8GcpqGkUEqDU,9936
51
+ clerk_sdk-0.4.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
+ clerk_sdk-0.4.6.dist-info/top_level.txt,sha256=99eQiU6d05_-f41tmSFanfI_SIJeAdh7u9m3LNSfcv4,6
53
+ clerk_sdk-0.4.6.dist-info/RECORD,,
@@ -1,128 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: clerk-sdk
3
- Version: 0.4.5
4
- Summary: Library for interacting with Clerk
5
- Home-page: https://github.com/F-ONE-Group/clerk_pypi
6
- Author: F-ONE Group
7
- Author-email: admin@f-one.group
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.10
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: pydantic<3.0.0,>=2.0.0
15
- Requires-Dist: backoff<3.0.0,>=2.0.0
16
- Requires-Dist: requests<3.0.0,>=2.32.3
17
- Provides-Extra: all
18
- Requires-Dist: pydantic<3.0.0,>=2.0.0; extra == "all"
19
- Requires-Dist: backoff<3.0.0,>=2.0.0; extra == "all"
20
- Requires-Dist: requests<3.0.0,>=2.32.3; extra == "all"
21
- Requires-Dist: networkx<4.0.0,>=3.5.0; extra == "all"
22
- Requires-Dist: websockets>=15.0.1; extra == "all"
23
- Provides-Extra: gui-automation
24
- Requires-Dist: networkx<4.0.0,>=3.5.0; extra == "gui-automation"
25
- Requires-Dist: websockets>=15.0.1; extra == "gui-automation"
26
- Dynamic: author
27
- Dynamic: author-email
28
- Dynamic: classifier
29
- Dynamic: description
30
- Dynamic: description-content-type
31
- Dynamic: home-page
32
- Dynamic: license-file
33
- Dynamic: provides-extra
34
- Dynamic: requires-dist
35
- Dynamic: requires-python
36
- Dynamic: summary
37
-
38
- # CLERK
39
-
40
- `clerk-sdk` is a Python library designed to simplify interactions with the Clerk API. It provides a robust and user-friendly interface for managing documents, handling API requests, and integrating structured data models into your workflows. `clerk-sdk` is ideal for developers looking to streamline their integration with Clerk.
41
-
42
- ## Features
43
-
44
- - **Document Management**: Retrieve and manage documents and their associated files.
45
- - **API Request Handling**: Simplified GET and POST requests with automatic retries and error handling.
46
- - **Data Models**: Predefined Pydantic models for structured data validation and serialization.
47
- - **Task Flow Integration**: Decorator for creating and managing task flows.
48
- - **Extensibility**: Easily extend and customize the library to fit your specific use case.
49
-
50
- ## Installation
51
-
52
- Install the library using pip:
53
-
54
- ```bash
55
- pip install clerk-sdk
56
- ```
57
-
58
- ## Usage
59
-
60
- ### Initialize the Client
61
-
62
- ```python
63
- from clerk import Clerk
64
-
65
- clerk_client = Clerk(api_key="your_api_key")
66
- ```
67
-
68
- ### Retrieve a Document
69
-
70
- ```python
71
- document = clerk_client.get_document(document_id="12345")
72
- print(document.title)
73
- ```
74
-
75
- ### Retrieve Files Associated with a Document
76
-
77
- ```python
78
- files = clerk_client.get_files_document(document_id="12345")
79
- for file in files:
80
- print(file.name)
81
- ```
82
-
83
- ### Use the Task Decorator
84
-
85
- #### PROD
86
-
87
- ```python
88
- from clerk.decorator import clerk_code
89
- from clerk.decorator.models import ClerkCodePayload
90
-
91
- @clerk_code()
92
- def main(payload: ClerkCodePayload) -> ClerkCodePayload:
93
- payload.structured_data["status"] = "ok"
94
- return payload
95
-
96
- main()
97
- ```
98
-
99
- #### TEST
100
-
101
- ```python
102
- from clerk.decorator.models import ClerkCodePayload, Document
103
-
104
- def test_main():
105
- test_payload = ClerkCodePayload(
106
- document=Document(id="doc-123", message_subject="Hello"),
107
- structured_data={}
108
- )
109
-
110
- result = main(test_payload) # ✅ Just pass it!
111
- assert result.structured_data["status"] == "ok"
112
- ```
113
-
114
-
115
- ## Requirements
116
-
117
- - Python 3.10+
118
- - Dependencies listed in `requirements.txt`:
119
- - `pydantic>2.0.0`
120
- - `backoff>2.0.0`
121
-
122
- ## License
123
-
124
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
125
-
126
- ## Contributing
127
-
128
- Contributions are welcome! Please submit a pull request or open an issue to discuss your ideas.