inferencesh 0.4.1__tar.gz → 0.4.2__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.
Potentially problematic release.
This version of inferencesh might be problematic. Click here for more details.
- {inferencesh-0.4.1/src/inferencesh.egg-info → inferencesh-0.4.2}/PKG-INFO +77 -36
- inferencesh-0.4.2/README.md +172 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/pyproject.toml +1 -1
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/models/file.py +6 -9
- {inferencesh-0.4.1 → inferencesh-0.4.2/src/inferencesh.egg-info}/PKG-INFO +77 -36
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh.egg-info/SOURCES.txt +0 -1
- inferencesh-0.4.1/README.md +0 -128
- inferencesh-0.4.1/setup.py +0 -22
- {inferencesh-0.4.1 → inferencesh-0.4.2}/LICENSE +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/setup.cfg +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/__init__.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/client.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/models/__init__.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/models/base.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/models/llm.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/utils/__init__.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/utils/download.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh/utils/storage.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh.egg-info/dependency_links.txt +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh.egg-info/entry_points.txt +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh.egg-info/requires.txt +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/src/inferencesh.egg-info/top_level.txt +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/tests/test_client.py +0 -0
- {inferencesh-0.4.1 → inferencesh-0.4.2}/tests/test_sdk.py +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: inferencesh
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: inference.sh Python SDK
|
|
5
|
-
Author: Inference Shell Inc.
|
|
6
5
|
Author-email: "Inference Shell Inc." <hello@inference.sh>
|
|
7
6
|
Project-URL: Homepage, https://github.com/inference-sh/sdk
|
|
8
7
|
Project-URL: Bug Tracker, https://github.com/inference-sh/sdk/issues
|
|
@@ -21,9 +20,7 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
|
21
20
|
Provides-Extra: async
|
|
22
21
|
Requires-Dist: aiohttp>=3.9.0; python_version >= "3.8" and extra == "async"
|
|
23
22
|
Requires-Dist: aiofiles>=23.2.1; python_version >= "3.8" and extra == "async"
|
|
24
|
-
Dynamic: author
|
|
25
23
|
Dynamic: license-file
|
|
26
|
-
Dynamic: requires-python
|
|
27
24
|
|
|
28
25
|
# inference.sh sdk
|
|
29
26
|
|
|
@@ -38,47 +35,91 @@ pip install infsh
|
|
|
38
35
|
## client usage
|
|
39
36
|
|
|
40
37
|
```python
|
|
41
|
-
from
|
|
38
|
+
from inferencesh import Inference, TaskStatus
|
|
42
39
|
|
|
43
|
-
#
|
|
40
|
+
# Create client
|
|
44
41
|
client = Inference(api_key="your-api-key")
|
|
45
42
|
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# get task info without waiting
|
|
55
|
-
task = client.run(params, wait=False)
|
|
56
|
-
print(f"task id: {task['id']}")
|
|
57
|
-
|
|
58
|
-
# stream updates (recommended)
|
|
59
|
-
for update in client.run(params, stream=True):
|
|
60
|
-
status = update.get("status")
|
|
61
|
-
print(f"status: {TaskStatus(status).name}")
|
|
43
|
+
# Simple synchronous usage
|
|
44
|
+
try:
|
|
45
|
+
task = client.run({
|
|
46
|
+
"app": "your-app",
|
|
47
|
+
"input": {"key": "value"},
|
|
48
|
+
"infra": "cloud",
|
|
49
|
+
"variant": "default"
|
|
50
|
+
})
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
print(f"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
print(f"Task ID: {task.get('id')}")
|
|
53
|
+
|
|
54
|
+
if task.get("status") == TaskStatus.COMPLETED:
|
|
55
|
+
print("✓ Task completed successfully!")
|
|
56
|
+
print(f"Output: {task.get('output')}")
|
|
57
|
+
else:
|
|
58
|
+
status = task.get("status")
|
|
59
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
60
|
+
print(f"✗ Task did not complete. Final status: {status_name}")
|
|
61
|
+
|
|
62
|
+
except Exception as exc:
|
|
63
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
64
|
+
raise # Re-raise to see full traceback
|
|
65
|
+
|
|
66
|
+
# Streaming updates (recommended)
|
|
67
|
+
try:
|
|
68
|
+
for update in client.run(
|
|
69
|
+
{
|
|
70
|
+
"app": "your-app",
|
|
71
|
+
"input": {"key": "value"},
|
|
72
|
+
"infra": "cloud",
|
|
73
|
+
"variant": "default"
|
|
74
|
+
},
|
|
75
|
+
stream=True # Enable streaming updates
|
|
76
|
+
):
|
|
77
|
+
status = update.get("status")
|
|
78
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
79
|
+
print(f"Status: {status_name}")
|
|
80
|
+
|
|
81
|
+
if status == TaskStatus.COMPLETED:
|
|
82
|
+
print("✓ Task completed!")
|
|
83
|
+
print(f"Output: {update.get('output')}")
|
|
84
|
+
break
|
|
85
|
+
elif status == TaskStatus.FAILED:
|
|
86
|
+
print(f"✗ Task failed: {update.get('error')}")
|
|
87
|
+
break
|
|
88
|
+
elif status == TaskStatus.CANCELLED:
|
|
89
|
+
print("✗ Task was cancelled")
|
|
90
|
+
break
|
|
91
|
+
|
|
92
|
+
except Exception as exc:
|
|
93
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
94
|
+
raise # Re-raise to see full traceback
|
|
95
|
+
|
|
96
|
+
# Async support
|
|
71
97
|
async def run_async():
|
|
72
|
-
from
|
|
98
|
+
from inferencesh import AsyncInference
|
|
73
99
|
|
|
74
100
|
client = AsyncInference(api_key="your-api-key")
|
|
75
101
|
|
|
76
|
-
#
|
|
77
|
-
result = await client.run(
|
|
102
|
+
# Simple usage
|
|
103
|
+
result = await client.run({
|
|
104
|
+
"app": "your-app",
|
|
105
|
+
"input": {"key": "value"},
|
|
106
|
+
"infra": "cloud",
|
|
107
|
+
"variant": "default"
|
|
108
|
+
})
|
|
78
109
|
|
|
79
|
-
#
|
|
80
|
-
async for update in await client.run(
|
|
81
|
-
|
|
110
|
+
# Stream updates
|
|
111
|
+
async for update in await client.run(
|
|
112
|
+
{
|
|
113
|
+
"app": "your-app",
|
|
114
|
+
"input": {"key": "value"},
|
|
115
|
+
"infra": "cloud",
|
|
116
|
+
"variant": "default"
|
|
117
|
+
},
|
|
118
|
+
stream=True
|
|
119
|
+
):
|
|
120
|
+
status = update.get("status")
|
|
121
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
122
|
+
print(f"Status: {status_name}")
|
|
82
123
|
```
|
|
83
124
|
|
|
84
125
|
## file handling
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# inference.sh sdk
|
|
2
|
+
|
|
3
|
+
helper package for inference.sh python applications.
|
|
4
|
+
|
|
5
|
+
## installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install infsh
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## client usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from inferencesh import Inference, TaskStatus
|
|
15
|
+
|
|
16
|
+
# Create client
|
|
17
|
+
client = Inference(api_key="your-api-key")
|
|
18
|
+
|
|
19
|
+
# Simple synchronous usage
|
|
20
|
+
try:
|
|
21
|
+
task = client.run({
|
|
22
|
+
"app": "your-app",
|
|
23
|
+
"input": {"key": "value"},
|
|
24
|
+
"infra": "cloud",
|
|
25
|
+
"variant": "default"
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
print(f"Task ID: {task.get('id')}")
|
|
29
|
+
|
|
30
|
+
if task.get("status") == TaskStatus.COMPLETED:
|
|
31
|
+
print("✓ Task completed successfully!")
|
|
32
|
+
print(f"Output: {task.get('output')}")
|
|
33
|
+
else:
|
|
34
|
+
status = task.get("status")
|
|
35
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
36
|
+
print(f"✗ Task did not complete. Final status: {status_name}")
|
|
37
|
+
|
|
38
|
+
except Exception as exc:
|
|
39
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
40
|
+
raise # Re-raise to see full traceback
|
|
41
|
+
|
|
42
|
+
# Streaming updates (recommended)
|
|
43
|
+
try:
|
|
44
|
+
for update in client.run(
|
|
45
|
+
{
|
|
46
|
+
"app": "your-app",
|
|
47
|
+
"input": {"key": "value"},
|
|
48
|
+
"infra": "cloud",
|
|
49
|
+
"variant": "default"
|
|
50
|
+
},
|
|
51
|
+
stream=True # Enable streaming updates
|
|
52
|
+
):
|
|
53
|
+
status = update.get("status")
|
|
54
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
55
|
+
print(f"Status: {status_name}")
|
|
56
|
+
|
|
57
|
+
if status == TaskStatus.COMPLETED:
|
|
58
|
+
print("✓ Task completed!")
|
|
59
|
+
print(f"Output: {update.get('output')}")
|
|
60
|
+
break
|
|
61
|
+
elif status == TaskStatus.FAILED:
|
|
62
|
+
print(f"✗ Task failed: {update.get('error')}")
|
|
63
|
+
break
|
|
64
|
+
elif status == TaskStatus.CANCELLED:
|
|
65
|
+
print("✗ Task was cancelled")
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
except Exception as exc:
|
|
69
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
70
|
+
raise # Re-raise to see full traceback
|
|
71
|
+
|
|
72
|
+
# Async support
|
|
73
|
+
async def run_async():
|
|
74
|
+
from inferencesh import AsyncInference
|
|
75
|
+
|
|
76
|
+
client = AsyncInference(api_key="your-api-key")
|
|
77
|
+
|
|
78
|
+
# Simple usage
|
|
79
|
+
result = await client.run({
|
|
80
|
+
"app": "your-app",
|
|
81
|
+
"input": {"key": "value"},
|
|
82
|
+
"infra": "cloud",
|
|
83
|
+
"variant": "default"
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
# Stream updates
|
|
87
|
+
async for update in await client.run(
|
|
88
|
+
{
|
|
89
|
+
"app": "your-app",
|
|
90
|
+
"input": {"key": "value"},
|
|
91
|
+
"infra": "cloud",
|
|
92
|
+
"variant": "default"
|
|
93
|
+
},
|
|
94
|
+
stream=True
|
|
95
|
+
):
|
|
96
|
+
status = update.get("status")
|
|
97
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
98
|
+
print(f"Status: {status_name}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## file handling
|
|
102
|
+
|
|
103
|
+
the `File` class provides a standardized way to handle files in the inference.sh ecosystem:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from infsh import File
|
|
107
|
+
|
|
108
|
+
# Basic file creation
|
|
109
|
+
file = File(path="/path/to/file.png")
|
|
110
|
+
|
|
111
|
+
# File with explicit metadata
|
|
112
|
+
file = File(
|
|
113
|
+
path="/path/to/file.png",
|
|
114
|
+
content_type="image/png",
|
|
115
|
+
filename="custom_name.png",
|
|
116
|
+
size=1024 # in bytes
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Create from path (automatically populates metadata)
|
|
120
|
+
file = File.from_path("/path/to/file.png")
|
|
121
|
+
|
|
122
|
+
# Check if file exists
|
|
123
|
+
exists = file.exists()
|
|
124
|
+
|
|
125
|
+
# Access file metadata
|
|
126
|
+
print(file.content_type) # automatically detected if not specified
|
|
127
|
+
print(file.size) # file size in bytes
|
|
128
|
+
print(file.filename) # basename of the file
|
|
129
|
+
|
|
130
|
+
# Refresh metadata (useful if file has changed)
|
|
131
|
+
file.refresh_metadata()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
the `File` class automatically handles:
|
|
135
|
+
- mime type detection
|
|
136
|
+
- file size calculation
|
|
137
|
+
- filename extraction from path
|
|
138
|
+
- file existence checking
|
|
139
|
+
|
|
140
|
+
## creating an app
|
|
141
|
+
|
|
142
|
+
to create an inference app, inherit from `BaseApp` and define your input/output types:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from infsh import BaseApp, BaseAppInput, BaseAppOutput, File
|
|
146
|
+
|
|
147
|
+
class AppInput(BaseAppInput):
|
|
148
|
+
image: str # URL or file path to image
|
|
149
|
+
mask: str # URL or file path to mask
|
|
150
|
+
|
|
151
|
+
class AppOutput(BaseAppOutput):
|
|
152
|
+
image: File
|
|
153
|
+
|
|
154
|
+
class MyApp(BaseApp):
|
|
155
|
+
async def setup(self):
|
|
156
|
+
# Initialize your model here
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
async def run(self, app_input: AppInput) -> AppOutput:
|
|
160
|
+
# Process input and return output
|
|
161
|
+
result_path = "/tmp/result.png"
|
|
162
|
+
return AppOutput(image=File(path=result_path))
|
|
163
|
+
|
|
164
|
+
async def unload(self):
|
|
165
|
+
# Clean up resources
|
|
166
|
+
pass
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
app lifecycle has three main methods:
|
|
170
|
+
- `setup()`: called when the app starts, use it to initialize models
|
|
171
|
+
- `run()`: called for each inference request
|
|
172
|
+
- `unload()`: called when shutting down, use it to free resources
|
|
@@ -4,7 +4,6 @@ import mimetypes
|
|
|
4
4
|
import os
|
|
5
5
|
import urllib.request
|
|
6
6
|
import urllib.parse
|
|
7
|
-
import tempfile
|
|
8
7
|
import hashlib
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
from tqdm import tqdm
|
|
@@ -119,12 +118,10 @@ class File(BaseModel):
|
|
|
119
118
|
return
|
|
120
119
|
|
|
121
120
|
print(f"Downloading URL: {original_url} to {cache_path}")
|
|
122
|
-
tmp_file = None
|
|
123
121
|
try:
|
|
124
|
-
# Download to temporary
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
self._tmp_path = tmp_file.name
|
|
122
|
+
# Download to a temporary filename in the final directory
|
|
123
|
+
tmp_path = str(cache_path) + '.tmp'
|
|
124
|
+
self._tmp_path = tmp_path
|
|
128
125
|
|
|
129
126
|
# Set up request with user agent
|
|
130
127
|
headers = {
|
|
@@ -176,8 +173,8 @@ class File(BaseModel):
|
|
|
176
173
|
# If we read the whole body at once, exit loop
|
|
177
174
|
break
|
|
178
175
|
|
|
179
|
-
#
|
|
180
|
-
os.
|
|
176
|
+
# Rename the temporary file to the final name
|
|
177
|
+
os.rename(self._tmp_path, cache_path)
|
|
181
178
|
self._tmp_path = None # Prevent deletion in __del__
|
|
182
179
|
self.path = str(cache_path)
|
|
183
180
|
except (urllib.error.URLError, urllib.error.HTTPError) as e:
|
|
@@ -186,7 +183,7 @@ class File(BaseModel):
|
|
|
186
183
|
raise RuntimeError(f"Failed to write downloaded file to {self._tmp_path}: {str(e)}")
|
|
187
184
|
except Exception as e:
|
|
188
185
|
# Clean up temp file if something went wrong
|
|
189
|
-
if
|
|
186
|
+
if hasattr(self, '_tmp_path') and self._tmp_path:
|
|
190
187
|
try:
|
|
191
188
|
os.unlink(self._tmp_path)
|
|
192
189
|
except (OSError, IOError):
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: inferencesh
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: inference.sh Python SDK
|
|
5
|
-
Author: Inference Shell Inc.
|
|
6
5
|
Author-email: "Inference Shell Inc." <hello@inference.sh>
|
|
7
6
|
Project-URL: Homepage, https://github.com/inference-sh/sdk
|
|
8
7
|
Project-URL: Bug Tracker, https://github.com/inference-sh/sdk/issues
|
|
@@ -21,9 +20,7 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
|
21
20
|
Provides-Extra: async
|
|
22
21
|
Requires-Dist: aiohttp>=3.9.0; python_version >= "3.8" and extra == "async"
|
|
23
22
|
Requires-Dist: aiofiles>=23.2.1; python_version >= "3.8" and extra == "async"
|
|
24
|
-
Dynamic: author
|
|
25
23
|
Dynamic: license-file
|
|
26
|
-
Dynamic: requires-python
|
|
27
24
|
|
|
28
25
|
# inference.sh sdk
|
|
29
26
|
|
|
@@ -38,47 +35,91 @@ pip install infsh
|
|
|
38
35
|
## client usage
|
|
39
36
|
|
|
40
37
|
```python
|
|
41
|
-
from
|
|
38
|
+
from inferencesh import Inference, TaskStatus
|
|
42
39
|
|
|
43
|
-
#
|
|
40
|
+
# Create client
|
|
44
41
|
client = Inference(api_key="your-api-key")
|
|
45
42
|
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# get task info without waiting
|
|
55
|
-
task = client.run(params, wait=False)
|
|
56
|
-
print(f"task id: {task['id']}")
|
|
57
|
-
|
|
58
|
-
# stream updates (recommended)
|
|
59
|
-
for update in client.run(params, stream=True):
|
|
60
|
-
status = update.get("status")
|
|
61
|
-
print(f"status: {TaskStatus(status).name}")
|
|
43
|
+
# Simple synchronous usage
|
|
44
|
+
try:
|
|
45
|
+
task = client.run({
|
|
46
|
+
"app": "your-app",
|
|
47
|
+
"input": {"key": "value"},
|
|
48
|
+
"infra": "cloud",
|
|
49
|
+
"variant": "default"
|
|
50
|
+
})
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
print(f"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
print(f"Task ID: {task.get('id')}")
|
|
53
|
+
|
|
54
|
+
if task.get("status") == TaskStatus.COMPLETED:
|
|
55
|
+
print("✓ Task completed successfully!")
|
|
56
|
+
print(f"Output: {task.get('output')}")
|
|
57
|
+
else:
|
|
58
|
+
status = task.get("status")
|
|
59
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
60
|
+
print(f"✗ Task did not complete. Final status: {status_name}")
|
|
61
|
+
|
|
62
|
+
except Exception as exc:
|
|
63
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
64
|
+
raise # Re-raise to see full traceback
|
|
65
|
+
|
|
66
|
+
# Streaming updates (recommended)
|
|
67
|
+
try:
|
|
68
|
+
for update in client.run(
|
|
69
|
+
{
|
|
70
|
+
"app": "your-app",
|
|
71
|
+
"input": {"key": "value"},
|
|
72
|
+
"infra": "cloud",
|
|
73
|
+
"variant": "default"
|
|
74
|
+
},
|
|
75
|
+
stream=True # Enable streaming updates
|
|
76
|
+
):
|
|
77
|
+
status = update.get("status")
|
|
78
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
79
|
+
print(f"Status: {status_name}")
|
|
80
|
+
|
|
81
|
+
if status == TaskStatus.COMPLETED:
|
|
82
|
+
print("✓ Task completed!")
|
|
83
|
+
print(f"Output: {update.get('output')}")
|
|
84
|
+
break
|
|
85
|
+
elif status == TaskStatus.FAILED:
|
|
86
|
+
print(f"✗ Task failed: {update.get('error')}")
|
|
87
|
+
break
|
|
88
|
+
elif status == TaskStatus.CANCELLED:
|
|
89
|
+
print("✗ Task was cancelled")
|
|
90
|
+
break
|
|
91
|
+
|
|
92
|
+
except Exception as exc:
|
|
93
|
+
print(f"Error: {type(exc).__name__}: {exc}")
|
|
94
|
+
raise # Re-raise to see full traceback
|
|
95
|
+
|
|
96
|
+
# Async support
|
|
71
97
|
async def run_async():
|
|
72
|
-
from
|
|
98
|
+
from inferencesh import AsyncInference
|
|
73
99
|
|
|
74
100
|
client = AsyncInference(api_key="your-api-key")
|
|
75
101
|
|
|
76
|
-
#
|
|
77
|
-
result = await client.run(
|
|
102
|
+
# Simple usage
|
|
103
|
+
result = await client.run({
|
|
104
|
+
"app": "your-app",
|
|
105
|
+
"input": {"key": "value"},
|
|
106
|
+
"infra": "cloud",
|
|
107
|
+
"variant": "default"
|
|
108
|
+
})
|
|
78
109
|
|
|
79
|
-
#
|
|
80
|
-
async for update in await client.run(
|
|
81
|
-
|
|
110
|
+
# Stream updates
|
|
111
|
+
async for update in await client.run(
|
|
112
|
+
{
|
|
113
|
+
"app": "your-app",
|
|
114
|
+
"input": {"key": "value"},
|
|
115
|
+
"infra": "cloud",
|
|
116
|
+
"variant": "default"
|
|
117
|
+
},
|
|
118
|
+
stream=True
|
|
119
|
+
):
|
|
120
|
+
status = update.get("status")
|
|
121
|
+
status_name = TaskStatus(status).name if status is not None else "UNKNOWN"
|
|
122
|
+
print(f"Status: {status_name}")
|
|
82
123
|
```
|
|
83
124
|
|
|
84
125
|
## file handling
|
inferencesh-0.4.1/README.md
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# inference.sh sdk
|
|
2
|
-
|
|
3
|
-
helper package for inference.sh python applications.
|
|
4
|
-
|
|
5
|
-
## installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install infsh
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## client usage
|
|
12
|
-
|
|
13
|
-
```python
|
|
14
|
-
from infsh import Inference, TaskStatus
|
|
15
|
-
|
|
16
|
-
# create client
|
|
17
|
-
client = Inference(api_key="your-api-key")
|
|
18
|
-
|
|
19
|
-
# simple usage - wait for result
|
|
20
|
-
result = client.run({
|
|
21
|
-
"app": "your-app",
|
|
22
|
-
"input": {"key": "value"},
|
|
23
|
-
"variant": "default"
|
|
24
|
-
})
|
|
25
|
-
print(f"output: {result['output']}")
|
|
26
|
-
|
|
27
|
-
# get task info without waiting
|
|
28
|
-
task = client.run(params, wait=False)
|
|
29
|
-
print(f"task id: {task['id']}")
|
|
30
|
-
|
|
31
|
-
# stream updates (recommended)
|
|
32
|
-
for update in client.run(params, stream=True):
|
|
33
|
-
status = update.get("status")
|
|
34
|
-
print(f"status: {TaskStatus(status).name}")
|
|
35
|
-
|
|
36
|
-
if status == TaskStatus.COMPLETED:
|
|
37
|
-
print(f"output: {update.get('output')}")
|
|
38
|
-
break
|
|
39
|
-
elif status == TaskStatus.FAILED:
|
|
40
|
-
print(f"error: {update.get('error')}")
|
|
41
|
-
break
|
|
42
|
-
|
|
43
|
-
# async support
|
|
44
|
-
async def run_async():
|
|
45
|
-
from infsh import AsyncInference
|
|
46
|
-
|
|
47
|
-
client = AsyncInference(api_key="your-api-key")
|
|
48
|
-
|
|
49
|
-
# simple usage
|
|
50
|
-
result = await client.run(params)
|
|
51
|
-
|
|
52
|
-
# stream updates
|
|
53
|
-
async for update in await client.run(params, stream=True):
|
|
54
|
-
print(f"status: {TaskStatus(update['status']).name}")
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## file handling
|
|
58
|
-
|
|
59
|
-
the `File` class provides a standardized way to handle files in the inference.sh ecosystem:
|
|
60
|
-
|
|
61
|
-
```python
|
|
62
|
-
from infsh import File
|
|
63
|
-
|
|
64
|
-
# Basic file creation
|
|
65
|
-
file = File(path="/path/to/file.png")
|
|
66
|
-
|
|
67
|
-
# File with explicit metadata
|
|
68
|
-
file = File(
|
|
69
|
-
path="/path/to/file.png",
|
|
70
|
-
content_type="image/png",
|
|
71
|
-
filename="custom_name.png",
|
|
72
|
-
size=1024 # in bytes
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
# Create from path (automatically populates metadata)
|
|
76
|
-
file = File.from_path("/path/to/file.png")
|
|
77
|
-
|
|
78
|
-
# Check if file exists
|
|
79
|
-
exists = file.exists()
|
|
80
|
-
|
|
81
|
-
# Access file metadata
|
|
82
|
-
print(file.content_type) # automatically detected if not specified
|
|
83
|
-
print(file.size) # file size in bytes
|
|
84
|
-
print(file.filename) # basename of the file
|
|
85
|
-
|
|
86
|
-
# Refresh metadata (useful if file has changed)
|
|
87
|
-
file.refresh_metadata()
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
the `File` class automatically handles:
|
|
91
|
-
- mime type detection
|
|
92
|
-
- file size calculation
|
|
93
|
-
- filename extraction from path
|
|
94
|
-
- file existence checking
|
|
95
|
-
|
|
96
|
-
## creating an app
|
|
97
|
-
|
|
98
|
-
to create an inference app, inherit from `BaseApp` and define your input/output types:
|
|
99
|
-
|
|
100
|
-
```python
|
|
101
|
-
from infsh import BaseApp, BaseAppInput, BaseAppOutput, File
|
|
102
|
-
|
|
103
|
-
class AppInput(BaseAppInput):
|
|
104
|
-
image: str # URL or file path to image
|
|
105
|
-
mask: str # URL or file path to mask
|
|
106
|
-
|
|
107
|
-
class AppOutput(BaseAppOutput):
|
|
108
|
-
image: File
|
|
109
|
-
|
|
110
|
-
class MyApp(BaseApp):
|
|
111
|
-
async def setup(self):
|
|
112
|
-
# Initialize your model here
|
|
113
|
-
pass
|
|
114
|
-
|
|
115
|
-
async def run(self, app_input: AppInput) -> AppOutput:
|
|
116
|
-
# Process input and return output
|
|
117
|
-
result_path = "/tmp/result.png"
|
|
118
|
-
return AppOutput(image=File(path=result_path))
|
|
119
|
-
|
|
120
|
-
async def unload(self):
|
|
121
|
-
# Clean up resources
|
|
122
|
-
pass
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
app lifecycle has three main methods:
|
|
126
|
-
- `setup()`: called when the app starts, use it to initialize models
|
|
127
|
-
- `run()`: called for each inference request
|
|
128
|
-
- `unload()`: called when shutting down, use it to free resources
|
inferencesh-0.4.1/setup.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
|
|
3
|
-
setup(
|
|
4
|
-
name="inferencesh",
|
|
5
|
-
version="0.1.2",
|
|
6
|
-
description="inference.sh Python SDK",
|
|
7
|
-
author="Inference Shell Inc.",
|
|
8
|
-
author_email="hello@inference.sh",
|
|
9
|
-
packages=find_packages(where="src"),
|
|
10
|
-
package_dir={"": "src"},
|
|
11
|
-
install_requires=[
|
|
12
|
-
"pydantic>=2.0.0",
|
|
13
|
-
"tqdm>=4.67.0",
|
|
14
|
-
"requests>=2.31.0",
|
|
15
|
-
],
|
|
16
|
-
python_requires=">=3.7",
|
|
17
|
-
classifiers=[
|
|
18
|
-
"Programming Language :: Python :: 3",
|
|
19
|
-
"License :: OSI Approved :: MIT License",
|
|
20
|
-
"Operating System :: OS Independent",
|
|
21
|
-
],
|
|
22
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|