oomol-cloud-task-sdk 0.1.0__tar.gz

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.
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: oomol-cloud-task-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for Oomol Cloud Task API
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: requests>=2.25.0
9
+
10
+ # Oomol Cloud Task SDK (Python)
11
+
12
+ A lightweight, developer-friendly Python SDK for `https://cloud-task.oomol.com/v1`.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install oomol-cloud-task-sdk
18
+ ```
19
+
20
+ (Note: You need to build the package locally first or publish it to PyPI)
21
+
22
+ ## Usage
23
+
24
+ ```python
25
+ from oomol_cloud_task import OomolTaskClient, BackoffStrategy
26
+
27
+ client = OomolTaskClient(api_key="YOUR_API_KEY")
28
+
29
+ task_id, result = client.create_and_wait(
30
+ applet_id="54dfbca0-6b2a-4738-bc38-c602981d9be6",
31
+ input_values={
32
+ "input_pdf": "...",
33
+ "output_path": "..."
34
+ },
35
+ interval_ms=2000,
36
+ backoff_strategy=BackoffStrategy.EXPONENTIAL
37
+ )
38
+
39
+ print(result)
40
+ ```
41
+
42
+ ## Features
43
+
44
+ - **Automatic Polling**: `create_and_wait` handles creation and polling in one step.
45
+ - **Backoff Strategies**: Supports `Fixed` and `Exponential` backoff to reduce server load.
46
+ - **Type Hints**: Fully typed for better IDE support.
@@ -0,0 +1,37 @@
1
+ # Oomol Cloud Task SDK (Python)
2
+
3
+ A lightweight, developer-friendly Python SDK for `https://cloud-task.oomol.com/v1`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install oomol-cloud-task-sdk
9
+ ```
10
+
11
+ (Note: You need to build the package locally first or publish it to PyPI)
12
+
13
+ ## Usage
14
+
15
+ ```python
16
+ from oomol_cloud_task import OomolTaskClient, BackoffStrategy
17
+
18
+ client = OomolTaskClient(api_key="YOUR_API_KEY")
19
+
20
+ task_id, result = client.create_and_wait(
21
+ applet_id="54dfbca0-6b2a-4738-bc38-c602981d9be6",
22
+ input_values={
23
+ "input_pdf": "...",
24
+ "output_path": "..."
25
+ },
26
+ interval_ms=2000,
27
+ backoff_strategy=BackoffStrategy.EXPONENTIAL
28
+ )
29
+
30
+ print(result)
31
+ ```
32
+
33
+ ## Features
34
+
35
+ - **Automatic Polling**: `create_and_wait` handles creation and polling in one step.
36
+ - **Backoff Strategies**: Supports `Fixed` and `Exponential` backoff to reduce server load.
37
+ - **Type Hints**: Fully typed for better IDE support.
@@ -0,0 +1,14 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "oomol-cloud-task-sdk"
7
+ version = "0.1.0"
8
+ description = "Python SDK for Oomol Cloud Task API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ license = "MIT"
12
+ dependencies = [
13
+ "requests>=2.25.0",
14
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,12 @@
1
+ from .client import OomolTaskClient
2
+ from .errors import ApiError, TaskFailedError, TimeoutError
3
+ from .types import BackoffStrategy, TaskStatus
4
+
5
+ __all__ = [
6
+ "OomolTaskClient",
7
+ "ApiError",
8
+ "TaskFailedError",
9
+ "TimeoutError",
10
+ "BackoffStrategy",
11
+ "TaskStatus",
12
+ ]
@@ -0,0 +1,154 @@
1
+ import time
2
+ import requests
3
+ from typing import Optional, Callable, Dict, Any, Tuple
4
+ from .errors import ApiError, TaskFailedError, TimeoutError
5
+ from .types import BackoffStrategy, TaskStatus, InputValues, Metadata
6
+
7
+ DEFAULT_BASE_URL = "https://cloud-task.oomol.com/v1"
8
+
9
+ class OomolTaskClient:
10
+ def __init__(
11
+ self,
12
+ api_key: str,
13
+ base_url: str = DEFAULT_BASE_URL,
14
+ default_headers: Optional[Dict[str, str]] = None
15
+ ):
16
+ self.api_key = api_key
17
+ self.base_url = base_url.rstrip("/")
18
+ self.default_headers = default_headers or {}
19
+ self.session = requests.Session()
20
+
21
+ def create_task(
22
+ self,
23
+ applet_id: str,
24
+ input_values: InputValues,
25
+ webhook_url: Optional[str] = None,
26
+ metadata: Optional[Metadata] = None
27
+ ) -> str:
28
+ """
29
+ Creates a task and returns the task ID.
30
+ """
31
+ url = f"{self.base_url}/task/applet"
32
+
33
+ body = {
34
+ "appletID": applet_id,
35
+ "inputValues": input_values
36
+ }
37
+ if webhook_url:
38
+ body["webhookUrl"] = webhook_url
39
+ if metadata:
40
+ body["metadata"] = metadata
41
+
42
+ headers = self._get_headers()
43
+
44
+ response = self.session.post(url, json=body, headers=headers)
45
+
46
+ if not response.ok:
47
+ self._handle_error(response)
48
+
49
+ data = response.json()
50
+ return data["taskID"]
51
+
52
+ def get_task_result(self, task_id: str) -> Dict[str, Any]:
53
+ """
54
+ Fetches the result of a task.
55
+ """
56
+ url = f"{self.base_url}/task/{task_id}/result"
57
+ headers = self._get_headers()
58
+
59
+ response = self.session.get(url, headers=headers)
60
+
61
+ if not response.ok:
62
+ self._handle_error(response)
63
+
64
+ return response.json()
65
+
66
+ def await_result(
67
+ self,
68
+ task_id: str,
69
+ interval_ms: int = 2000,
70
+ timeout_ms: Optional[int] = None,
71
+ backoff_strategy: BackoffStrategy = BackoffStrategy.FIXED,
72
+ max_interval_ms: int = 15000,
73
+ on_progress: Optional[Callable[[Optional[float], str], None]] = None
74
+ ) -> Dict[str, Any]:
75
+ """
76
+ Polls for the task result until completion or timeout.
77
+ """
78
+ start_time = time.time()
79
+ attempt = 0
80
+ current_interval = interval_ms / 1000.0
81
+ max_interval = max_interval_ms / 1000.0
82
+
83
+ while True:
84
+ # Check timeout
85
+ if timeout_ms is not None:
86
+ elapsed = (time.time() - start_time) * 1000
87
+ if elapsed > timeout_ms:
88
+ raise TimeoutError()
89
+
90
+ result = self.get_task_result(task_id)
91
+ status = result.get("status")
92
+ progress = result.get("progress")
93
+
94
+ if status == TaskStatus.SUCCESS.value:
95
+ return result
96
+
97
+ if status == TaskStatus.FAILED.value:
98
+ raise TaskFailedError(task_id, result.get("error") or result)
99
+
100
+ if on_progress:
101
+ on_progress(progress, status)
102
+
103
+ attempt += 1
104
+
105
+ # Backoff logic
106
+ if backoff_strategy == BackoffStrategy.EXPONENTIAL:
107
+ # 1.5x multiplier
108
+ next_interval = min(max_interval, (interval_ms / 1000.0) * (1.5 ** attempt))
109
+ else:
110
+ next_interval = current_interval
111
+
112
+ time.sleep(next_interval)
113
+
114
+ def create_and_wait(
115
+ self,
116
+ applet_id: str,
117
+ input_values: InputValues,
118
+ webhook_url: Optional[str] = None,
119
+ metadata: Optional[Metadata] = None,
120
+ interval_ms: int = 2000,
121
+ timeout_ms: Optional[int] = None,
122
+ backoff_strategy: BackoffStrategy = BackoffStrategy.FIXED,
123
+ max_interval_ms: int = 15000,
124
+ on_progress: Optional[Callable[[Optional[float], str], None]] = None
125
+ ) -> Tuple[str, Dict[str, Any]]:
126
+ """
127
+ Creates a task and waits for its completion.
128
+ Returns (task_id, result).
129
+ """
130
+ task_id = self.create_task(applet_id, input_values, webhook_url, metadata)
131
+ result = self.await_result(
132
+ task_id=task_id,
133
+ interval_ms=interval_ms,
134
+ timeout_ms=timeout_ms,
135
+ backoff_strategy=backoff_strategy,
136
+ max_interval_ms=max_interval_ms,
137
+ on_progress=on_progress
138
+ )
139
+ return task_id, result
140
+
141
+ def _get_headers(self) -> Dict[str, str]:
142
+ headers = {
143
+ "Content-Type": "application/json",
144
+ "Authorization": f"Bearer {self.api_key}",
145
+ }
146
+ headers.update(self.default_headers)
147
+ return headers
148
+
149
+ def _handle_error(self, response: requests.Response):
150
+ try:
151
+ body = response.json()
152
+ except ValueError:
153
+ body = response.text
154
+ raise ApiError(f"Request failed: {response.status_code}", response.status_code, body)
@@ -0,0 +1,17 @@
1
+ class ApiError(Exception):
2
+ def __init__(self, message: str, status: int, body: any = None):
3
+ super().__init__(message)
4
+ self.status = status
5
+ self.body = body
6
+
7
+
8
+ class TaskFailedError(Exception):
9
+ def __init__(self, task_id: str, detail: any = None):
10
+ super().__init__(f"Task execution failed: {task_id}")
11
+ self.task_id = task_id
12
+ self.detail = detail
13
+
14
+
15
+ class TimeoutError(Exception):
16
+ def __init__(self, message: str = "Operation timed out"):
17
+ super().__init__(message)
@@ -0,0 +1,16 @@
1
+ from enum import Enum
2
+ from typing import Dict, Optional, Any, Union
3
+
4
+ class BackoffStrategy(Enum):
5
+ FIXED = "fixed"
6
+ EXPONENTIAL = "exp"
7
+
8
+ class TaskStatus(str, Enum):
9
+ PENDING = "pending"
10
+ RUNNING = "running"
11
+ SUCCESS = "success"
12
+ FAILED = "failed"
13
+
14
+ # Type aliases for better readability
15
+ InputValues = Dict[str, Any]
16
+ Metadata = Dict[str, Any]
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: oomol-cloud-task-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for Oomol Cloud Task API
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: requests>=2.25.0
9
+
10
+ # Oomol Cloud Task SDK (Python)
11
+
12
+ A lightweight, developer-friendly Python SDK for `https://cloud-task.oomol.com/v1`.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install oomol-cloud-task-sdk
18
+ ```
19
+
20
+ (Note: You need to build the package locally first or publish it to PyPI)
21
+
22
+ ## Usage
23
+
24
+ ```python
25
+ from oomol_cloud_task import OomolTaskClient, BackoffStrategy
26
+
27
+ client = OomolTaskClient(api_key="YOUR_API_KEY")
28
+
29
+ task_id, result = client.create_and_wait(
30
+ applet_id="54dfbca0-6b2a-4738-bc38-c602981d9be6",
31
+ input_values={
32
+ "input_pdf": "...",
33
+ "output_path": "..."
34
+ },
35
+ interval_ms=2000,
36
+ backoff_strategy=BackoffStrategy.EXPONENTIAL
37
+ )
38
+
39
+ print(result)
40
+ ```
41
+
42
+ ## Features
43
+
44
+ - **Automatic Polling**: `create_and_wait` handles creation and polling in one step.
45
+ - **Backoff Strategies**: Supports `Fixed` and `Exponential` backoff to reduce server load.
46
+ - **Type Hints**: Fully typed for better IDE support.
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/oomol_cloud_task/__init__.py
4
+ src/oomol_cloud_task/client.py
5
+ src/oomol_cloud_task/errors.py
6
+ src/oomol_cloud_task/types.py
7
+ src/oomol_cloud_task_sdk.egg-info/PKG-INFO
8
+ src/oomol_cloud_task_sdk.egg-info/SOURCES.txt
9
+ src/oomol_cloud_task_sdk.egg-info/dependency_links.txt
10
+ src/oomol_cloud_task_sdk.egg-info/requires.txt
11
+ src/oomol_cloud_task_sdk.egg-info/top_level.txt