inferencesh 0.2.23__py3-none-any.whl → 0.4.29__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.
- inferencesh/__init__.py +5 -0
- inferencesh/client.py +1081 -0
- inferencesh/models/base.py +81 -3
- inferencesh/models/file.py +120 -21
- inferencesh/models/llm.py +485 -136
- inferencesh/utils/download.py +15 -7
- inferencesh-0.4.29.dist-info/METADATA +196 -0
- inferencesh-0.4.29.dist-info/RECORD +15 -0
- inferencesh-0.2.23.dist-info/METADATA +0 -105
- inferencesh-0.2.23.dist-info/RECORD +0 -14
- {inferencesh-0.2.23.dist-info → inferencesh-0.4.29.dist-info}/WHEEL +0 -0
- {inferencesh-0.2.23.dist-info → inferencesh-0.4.29.dist-info}/entry_points.txt +0 -0
- {inferencesh-0.2.23.dist-info → inferencesh-0.4.29.dist-info}/licenses/LICENSE +0 -0
- {inferencesh-0.2.23.dist-info → inferencesh-0.4.29.dist-info}/top_level.txt +0 -0
inferencesh/utils/download.py
CHANGED
|
@@ -24,16 +24,24 @@ def download(url: str, directory: Union[str, Path, StorageDir]) -> str:
|
|
|
24
24
|
dir_path = Path(directory)
|
|
25
25
|
dir_path.mkdir(exist_ok=True)
|
|
26
26
|
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
hash_dir = dir_path / url_hash
|
|
30
|
-
hash_dir.mkdir(exist_ok=True)
|
|
27
|
+
# Parse URL components
|
|
28
|
+
parsed_url = urllib.parse.urlparse(url)
|
|
31
29
|
|
|
32
|
-
#
|
|
33
|
-
|
|
30
|
+
# Create hash from URL path and query parameters for uniqueness
|
|
31
|
+
url_components = parsed_url.netloc + parsed_url.path
|
|
32
|
+
if parsed_url.query:
|
|
33
|
+
url_components += '?' + parsed_url.query
|
|
34
|
+
url_hash = hashlib.sha256(url_components.encode()).hexdigest()[:12]
|
|
35
|
+
|
|
36
|
+
# Keep original filename or use a default
|
|
37
|
+
filename = os.path.basename(parsed_url.path)
|
|
34
38
|
if not filename:
|
|
35
39
|
filename = 'download'
|
|
36
|
-
|
|
40
|
+
|
|
41
|
+
# Create hash directory and store file
|
|
42
|
+
hash_dir = dir_path / url_hash
|
|
43
|
+
hash_dir.mkdir(exist_ok=True)
|
|
44
|
+
|
|
37
45
|
output_path = hash_dir / filename
|
|
38
46
|
|
|
39
47
|
# If file exists in directory and it's not a temp directory, return it
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inferencesh
|
|
3
|
+
Version: 0.4.29
|
|
4
|
+
Summary: inference.sh Python SDK
|
|
5
|
+
Author-email: "Inference Shell Inc." <hello@inference.sh>
|
|
6
|
+
Project-URL: Homepage, https://github.com/inference-sh/sdk
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/inference-sh/sdk/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pydantic>=2.0.0
|
|
15
|
+
Requires-Dist: tqdm>=4.67.0
|
|
16
|
+
Requires-Dist: requests>=2.31.0
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
19
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
20
|
+
Provides-Extra: async
|
|
21
|
+
Requires-Dist: aiohttp>=3.9.0; python_version >= "3.8" and extra == "async"
|
|
22
|
+
Requires-Dist: aiofiles>=23.2.1; python_version >= "3.8" and extra == "async"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# inference.sh sdk
|
|
26
|
+
|
|
27
|
+
helper package for inference.sh python applications.
|
|
28
|
+
|
|
29
|
+
## installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install infsh
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## client usage
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from inferencesh import Inference, TaskStatus
|
|
39
|
+
|
|
40
|
+
# Create client
|
|
41
|
+
client = Inference(api_key="your-api-key")
|
|
42
|
+
|
|
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
|
+
})
|
|
51
|
+
|
|
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
|
|
97
|
+
async def run_async():
|
|
98
|
+
from inferencesh import AsyncInference
|
|
99
|
+
|
|
100
|
+
client = AsyncInference(api_key="your-api-key")
|
|
101
|
+
|
|
102
|
+
# Simple usage
|
|
103
|
+
result = await client.run({
|
|
104
|
+
"app": "your-app",
|
|
105
|
+
"input": {"key": "value"},
|
|
106
|
+
"infra": "cloud",
|
|
107
|
+
"variant": "default"
|
|
108
|
+
})
|
|
109
|
+
|
|
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}")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## file handling
|
|
126
|
+
|
|
127
|
+
the `File` class provides a standardized way to handle files in the inference.sh ecosystem:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from infsh import File
|
|
131
|
+
|
|
132
|
+
# Basic file creation
|
|
133
|
+
file = File(path="/path/to/file.png")
|
|
134
|
+
|
|
135
|
+
# File with explicit metadata
|
|
136
|
+
file = File(
|
|
137
|
+
path="/path/to/file.png",
|
|
138
|
+
content_type="image/png",
|
|
139
|
+
filename="custom_name.png",
|
|
140
|
+
size=1024 # in bytes
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Create from path (automatically populates metadata)
|
|
144
|
+
file = File.from_path("/path/to/file.png")
|
|
145
|
+
|
|
146
|
+
# Check if file exists
|
|
147
|
+
exists = file.exists()
|
|
148
|
+
|
|
149
|
+
# Access file metadata
|
|
150
|
+
print(file.content_type) # automatically detected if not specified
|
|
151
|
+
print(file.size) # file size in bytes
|
|
152
|
+
print(file.filename) # basename of the file
|
|
153
|
+
|
|
154
|
+
# Refresh metadata (useful if file has changed)
|
|
155
|
+
file.refresh_metadata()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
the `File` class automatically handles:
|
|
159
|
+
- mime type detection
|
|
160
|
+
- file size calculation
|
|
161
|
+
- filename extraction from path
|
|
162
|
+
- file existence checking
|
|
163
|
+
|
|
164
|
+
## creating an app
|
|
165
|
+
|
|
166
|
+
to create an inference app, inherit from `BaseApp` and define your input/output types:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from infsh import BaseApp, BaseAppInput, BaseAppOutput, File
|
|
170
|
+
|
|
171
|
+
class AppInput(BaseAppInput):
|
|
172
|
+
image: str # URL or file path to image
|
|
173
|
+
mask: str # URL or file path to mask
|
|
174
|
+
|
|
175
|
+
class AppOutput(BaseAppOutput):
|
|
176
|
+
image: File
|
|
177
|
+
|
|
178
|
+
class MyApp(BaseApp):
|
|
179
|
+
async def setup(self):
|
|
180
|
+
# Initialize your model here
|
|
181
|
+
pass
|
|
182
|
+
|
|
183
|
+
async def run(self, app_input: AppInput) -> AppOutput:
|
|
184
|
+
# Process input and return output
|
|
185
|
+
result_path = "/tmp/result.png"
|
|
186
|
+
return AppOutput(image=File(path=result_path))
|
|
187
|
+
|
|
188
|
+
async def unload(self):
|
|
189
|
+
# Clean up resources
|
|
190
|
+
pass
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
app lifecycle has three main methods:
|
|
194
|
+
- `setup()`: called when the app starts, use it to initialize models
|
|
195
|
+
- `run()`: called for each inference request
|
|
196
|
+
- `unload()`: called when shutting down, use it to free resources
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
inferencesh/__init__.py,sha256=dY3l3yCkWoMtGX0gNXgxFnrprFRl6PPWjH8V7Qedx5g,772
|
|
2
|
+
inferencesh/client.py,sha256=ilYbiM6TEIJK4HwoECbxkb2hP5GVx6-S6EJ5DXVrDKU,41035
|
|
3
|
+
inferencesh/models/__init__.py,sha256=FDwcdtT6c4hbRitymjmN-hZMlQa8RbKSftkZZyjtUXA,536
|
|
4
|
+
inferencesh/models/base.py,sha256=eTwRvXAjMGh6b8AUXWKSGpRyeScAkPs6bNYY8AXKSz8,5505
|
|
5
|
+
inferencesh/models/file.py,sha256=H4s-A2RWfNTMCcLqSLpqNHvGfSvYEnbZaJj-rWftrL0,11743
|
|
6
|
+
inferencesh/models/llm.py,sha256=M7GTFj83-byEZ-TMSj4_M5ZT_2KVe4sUypf2G_bwoBI,34407
|
|
7
|
+
inferencesh/utils/__init__.py,sha256=-xiD6uo2XzcrPAWFb_fUbaimmnW4KFKc-8IvBzaxNd4,148
|
|
8
|
+
inferencesh/utils/download.py,sha256=DRGBudiPVa5bDS35KfR-DYeGRk7gO03WOelnisecwMo,1815
|
|
9
|
+
inferencesh/utils/storage.py,sha256=E4J8emd4eFKdmdDgAqzz3TpaaDd3n0l8gYlMHuY8yIU,519
|
|
10
|
+
inferencesh-0.4.29.dist-info/licenses/LICENSE,sha256=OsgqEWIh2el_QMj0y8O1A5Q5Dl-dxqqYbFE6fszuR4s,1086
|
|
11
|
+
inferencesh-0.4.29.dist-info/METADATA,sha256=kYjHVsh1-hnIutItB64ptKcxFCULtg-Kixthji53hjA,5406
|
|
12
|
+
inferencesh-0.4.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
+
inferencesh-0.4.29.dist-info/entry_points.txt,sha256=6IC-fyozAqW3ljsMLGCXxJ0_ui2Jb-2fLHtoH1RTnEE,45
|
|
14
|
+
inferencesh-0.4.29.dist-info/top_level.txt,sha256=TSMHg3T1ThMl1HGAWmzBClwOYH1ump5neof9BfHIwaA,12
|
|
15
|
+
inferencesh-0.4.29.dist-info/RECORD,,
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: inferencesh
|
|
3
|
-
Version: 0.2.23
|
|
4
|
-
Summary: inference.sh Python SDK
|
|
5
|
-
Author: Inference Shell Inc.
|
|
6
|
-
Author-email: "Inference Shell Inc." <hello@inference.sh>
|
|
7
|
-
Project-URL: Homepage, https://github.com/inference-sh/sdk
|
|
8
|
-
Project-URL: Bug Tracker, https://github.com/inference-sh/sdk/issues
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.7
|
|
13
|
-
Description-Content-Type: text/markdown
|
|
14
|
-
License-File: LICENSE
|
|
15
|
-
Requires-Dist: pydantic>=2.0.0
|
|
16
|
-
Requires-Dist: tqdm>=4.67.0
|
|
17
|
-
Provides-Extra: test
|
|
18
|
-
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
19
|
-
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
20
|
-
Dynamic: author
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
Dynamic: requires-python
|
|
23
|
-
|
|
24
|
-
# inference.sh CLI
|
|
25
|
-
|
|
26
|
-
Helper package for inference.sh Python applications.
|
|
27
|
-
|
|
28
|
-
## Installation
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
pip install infsh
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## File Handling
|
|
35
|
-
|
|
36
|
-
The `File` class provides a standardized way to handle files in the inference.sh ecosystem:
|
|
37
|
-
|
|
38
|
-
```python
|
|
39
|
-
from infsh import File
|
|
40
|
-
|
|
41
|
-
# Basic file creation
|
|
42
|
-
file = File(path="/path/to/file.png")
|
|
43
|
-
|
|
44
|
-
# File with explicit metadata
|
|
45
|
-
file = File(
|
|
46
|
-
path="/path/to/file.png",
|
|
47
|
-
content_type="image/png",
|
|
48
|
-
filename="custom_name.png",
|
|
49
|
-
size=1024 # in bytes
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
# Create from path (automatically populates metadata)
|
|
53
|
-
file = File.from_path("/path/to/file.png")
|
|
54
|
-
|
|
55
|
-
# Check if file exists
|
|
56
|
-
exists = file.exists()
|
|
57
|
-
|
|
58
|
-
# Access file metadata
|
|
59
|
-
print(file.content_type) # automatically detected if not specified
|
|
60
|
-
print(file.size) # file size in bytes
|
|
61
|
-
print(file.filename) # basename of the file
|
|
62
|
-
|
|
63
|
-
# Refresh metadata (useful if file has changed)
|
|
64
|
-
file.refresh_metadata()
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
The `File` class automatically handles:
|
|
68
|
-
- MIME type detection
|
|
69
|
-
- File size calculation
|
|
70
|
-
- Filename extraction from path
|
|
71
|
-
- File existence checking
|
|
72
|
-
|
|
73
|
-
## Creating an App
|
|
74
|
-
|
|
75
|
-
To create an inference app, inherit from `BaseApp` and define your input/output types:
|
|
76
|
-
|
|
77
|
-
```python
|
|
78
|
-
from infsh import BaseApp, BaseAppInput, BaseAppOutput, File
|
|
79
|
-
|
|
80
|
-
class AppInput(BaseAppInput):
|
|
81
|
-
image: str # URL or file path to image
|
|
82
|
-
mask: str # URL or file path to mask
|
|
83
|
-
|
|
84
|
-
class AppOutput(BaseAppOutput):
|
|
85
|
-
image: File
|
|
86
|
-
|
|
87
|
-
class MyApp(BaseApp):
|
|
88
|
-
async def setup(self):
|
|
89
|
-
# Initialize your model here
|
|
90
|
-
pass
|
|
91
|
-
|
|
92
|
-
async def run(self, app_input: AppInput) -> AppOutput:
|
|
93
|
-
# Process input and return output
|
|
94
|
-
result_path = "/tmp/result.png"
|
|
95
|
-
return AppOutput(image=File(path=result_path))
|
|
96
|
-
|
|
97
|
-
async def unload(self):
|
|
98
|
-
# Clean up resources
|
|
99
|
-
pass
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
The app lifecycle has three main methods:
|
|
103
|
-
- `setup()`: Called when the app starts, use it to initialize models
|
|
104
|
-
- `run()`: Called for each inference request
|
|
105
|
-
- `unload()`: Called when shutting down, use it to free resources
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
inferencesh/__init__.py,sha256=WdADtOhfa3HDOunoE9HLFCTFlXRykYstBIH1FpyWvj8,613
|
|
2
|
-
inferencesh/models/__init__.py,sha256=FDwcdtT6c4hbRitymjmN-hZMlQa8RbKSftkZZyjtUXA,536
|
|
3
|
-
inferencesh/models/base.py,sha256=4gZQRi8J7y9U6PrGD9pRIehd1MJVJAqGakPQDs2AKFM,3251
|
|
4
|
-
inferencesh/models/file.py,sha256=5xnpypcRahM1YcEjj64rv9g2gTimxrZb41YT4r440hU,7393
|
|
5
|
-
inferencesh/models/llm.py,sha256=knvwpKECQb67rG8VIt-VmZu0aDVpABzQiifrytAfv9s,20932
|
|
6
|
-
inferencesh/utils/__init__.py,sha256=-xiD6uo2XzcrPAWFb_fUbaimmnW4KFKc-8IvBzaxNd4,148
|
|
7
|
-
inferencesh/utils/download.py,sha256=7n5twvoNYDcFnKJyefImaj2YfzRI7vddQw4usZbj38c,1521
|
|
8
|
-
inferencesh/utils/storage.py,sha256=E4J8emd4eFKdmdDgAqzz3TpaaDd3n0l8gYlMHuY8yIU,519
|
|
9
|
-
inferencesh-0.2.23.dist-info/licenses/LICENSE,sha256=OsgqEWIh2el_QMj0y8O1A5Q5Dl-dxqqYbFE6fszuR4s,1086
|
|
10
|
-
inferencesh-0.2.23.dist-info/METADATA,sha256=w5AOt2foy30CdqgfcivGhBflpWOvtm1B7tHEJo_ipVE,2757
|
|
11
|
-
inferencesh-0.2.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
inferencesh-0.2.23.dist-info/entry_points.txt,sha256=6IC-fyozAqW3ljsMLGCXxJ0_ui2Jb-2fLHtoH1RTnEE,45
|
|
13
|
-
inferencesh-0.2.23.dist-info/top_level.txt,sha256=TSMHg3T1ThMl1HGAWmzBClwOYH1ump5neof9BfHIwaA,12
|
|
14
|
-
inferencesh-0.2.23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|