spaces 0.52.0.dev0__tar.gz → 0.52.0.dev2__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.
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/PKG-INFO +1 -1
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/pyproject.toml +1 -1
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/__init__.py +2 -2
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/client.py +25 -22
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/context.py +10 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/gradio.py +39 -14
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/middleware.py +2 -2
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/wrappers.py +3 -3
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/README.md +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/asgiref/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/asgiref/typing.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/codefind/LICENSE +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/codefind/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/codefind/registry.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/codefind/version.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/LICENSE +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/codetools.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/parse.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/register.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/utils.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/jurigged/version.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/LICENSE +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/abc.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/codegen.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/core.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/dependent.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/medley.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/mro.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/py.typed +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/recode.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/signatures.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/typemap.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/types.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/utils.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/ovld/version.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sse_starlette/LICENSE +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sse_starlette/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sse_starlette/event.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sse_starlette/py.typed +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sse_starlette/sse.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sseclient/LICENSE +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/_vendor/sseclient/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/config.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/reloading/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/reloading/client.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/reloading/server.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/reloading/types.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/reloading/types.ts +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/utils.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/api.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/config.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/configs.json +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/decorator.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/elf.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/lifecycle.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/mmap.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/__init__.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/aoti.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/bitsandbytes.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/bitsandbytes_legacy.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/cudart.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/packing.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/patching.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/patching_legacy.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/static.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/types.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/torch/utils.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/tqdm.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/types.py +0 -0
- {spaces-0.52.0.dev0 → spaces-0.52.0.dev2}/spaces/zero/utils.py +0 -0
|
@@ -19,8 +19,8 @@ if (gr := sys.modules.get('gradio')) is not None: # pragma: no cover
|
|
|
19
19
|
from .zero.decorator import GPU
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def gradio_auto_wrap(
|
|
23
|
-
|
|
22
|
+
def gradio_auto_wrap(task): # pragma: no cover
|
|
23
|
+
return task
|
|
24
24
|
|
|
25
25
|
def disable_gradio_auto_wrap(*args, **kwargs): # pragma: no cover
|
|
26
26
|
warnings.warn("gradio_auto_wrap has no effect and is deprecated")
|
|
@@ -18,7 +18,7 @@ from .api import GPUSize
|
|
|
18
18
|
from .api import AuthLevel
|
|
19
19
|
from .api import QuotaInfos
|
|
20
20
|
from .api import ScheduleResponse
|
|
21
|
-
from .context import
|
|
21
|
+
from .context import get_context
|
|
22
22
|
from .context import ZeroGPUContext
|
|
23
23
|
|
|
24
24
|
|
|
@@ -104,7 +104,7 @@ def schedule(
|
|
|
104
104
|
_first_attempt: bool = True,
|
|
105
105
|
) -> ScheduleResponse:
|
|
106
106
|
|
|
107
|
-
ctx =
|
|
107
|
+
ctx = get_context()
|
|
108
108
|
token, payload = _get_token_and_payload(ctx.headers)
|
|
109
109
|
if token is not None and (token_error := payload.get('error')):
|
|
110
110
|
message = f"Falling back to IP-based quotas ({token_error})"
|
|
@@ -146,6 +146,7 @@ def schedule(
|
|
|
146
146
|
)
|
|
147
147
|
if _is_api_call(ctx):
|
|
148
148
|
if auth is None or auth == 'regular':
|
|
149
|
+
message += ". "
|
|
149
150
|
message += (
|
|
150
151
|
f"Subscribe to Hugging Face PRO to allow GPU tasks up to {PRO_QUOTA_MINUTES} min - "
|
|
151
152
|
f"{SUBSCRIBE_TO_PRO_URL}"
|
|
@@ -159,31 +160,33 @@ def schedule(
|
|
|
159
160
|
else:
|
|
160
161
|
title = "ZeroGPU quota exceeded"
|
|
161
162
|
if res.wait == timedelta(0):
|
|
162
|
-
message = "You have exceeded your ZeroGPU runs limit
|
|
163
|
+
message = "You have exceeded your ZeroGPU runs limit"
|
|
163
164
|
else:
|
|
164
165
|
gpu = "Pro ZeroGPU" if auth == 'pro' else ("free ZeroGPU" if auth == 'regular' else "ZeroGPU")
|
|
165
166
|
message = (
|
|
166
167
|
f"You have exceeded your {gpu} quota "
|
|
167
168
|
f"({requested}s requested vs. {res.left}s left). "
|
|
168
|
-
f"Try again in {res.wait}
|
|
169
|
+
f"Try again in {res.wait}"
|
|
169
170
|
)
|
|
170
171
|
if _is_api_call(ctx):
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
172
|
+
message += ". "
|
|
173
|
+
match auth:
|
|
174
|
+
case None:
|
|
175
|
+
message += (
|
|
176
|
+
f"Authenticate with a Hugging Face token for more quota - "
|
|
177
|
+
f"{TOKENS_SETTINGS_URL}"
|
|
178
|
+
)
|
|
179
|
+
case 'regular':
|
|
180
|
+
message += (
|
|
181
|
+
f"Subscribe to Hugging Face PRO to get {PRO_QUOTA_MINUTES} min of ZeroGPU quota a day - "
|
|
182
|
+
f"{SUBSCRIBE_TO_PRO_URL}"
|
|
183
|
+
)
|
|
184
|
+
case 'pro':
|
|
185
|
+
message += (
|
|
186
|
+
f"Add credits to keep using ZeroGPU. "
|
|
187
|
+
f"$1 for 10 minutes of ZeroGPU inference - "
|
|
188
|
+
f"{ADD_CREDITS_URL}"
|
|
189
|
+
)
|
|
187
190
|
raise ctx.exception(
|
|
188
191
|
title=title,
|
|
189
192
|
message=message,
|
|
@@ -284,7 +287,7 @@ def release(
|
|
|
284
287
|
allow_404: bool = False,
|
|
285
288
|
) -> None:
|
|
286
289
|
|
|
287
|
-
ctx =
|
|
290
|
+
ctx = get_context()
|
|
288
291
|
res = api_client().release(
|
|
289
292
|
allow_token=allow_token,
|
|
290
293
|
fail=fail,
|
|
@@ -324,7 +327,7 @@ def _get_token_and_payload(headers: dict[str, str]) -> tuple[str | None, dict[st
|
|
|
324
327
|
|
|
325
328
|
|
|
326
329
|
def duration_warning():
|
|
327
|
-
|
|
330
|
+
get_context().warning(
|
|
328
331
|
title="ZeroGPU duration",
|
|
329
332
|
message="GPU task is exceeding its requested duration and might be aborted",
|
|
330
333
|
)
|
|
@@ -120,3 +120,13 @@ class ZeroGPUContext:
|
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
ctx_var: ContextVar[ZeroGPUContext] = ContextVar('zerogpu_context', default=ZeroGPUContext())
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
_context_resolver: Callable[[], ZeroGPUContext | None] | None = None
|
|
126
|
+
|
|
127
|
+
def get_context() -> ZeroGPUContext:
|
|
128
|
+
if _context_resolver is not None:
|
|
129
|
+
ctx = _context_resolver()
|
|
130
|
+
if ctx is not None:
|
|
131
|
+
return ctx
|
|
132
|
+
return ctx_var.get()
|
|
@@ -5,7 +5,7 @@ import os
|
|
|
5
5
|
from functools import wraps
|
|
6
6
|
from typing import Any
|
|
7
7
|
from typing import Literal
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import cast
|
|
9
9
|
|
|
10
10
|
import gradio as gr
|
|
11
11
|
from fastapi import FastAPI
|
|
@@ -18,8 +18,14 @@ from gradio.routes import App
|
|
|
18
18
|
|
|
19
19
|
from ..utils import create_thread_daemon
|
|
20
20
|
from ..utils import SimpleQueue
|
|
21
|
+
from . import context
|
|
22
|
+
from .context import ZeroGPUContext
|
|
23
|
+
from .context import ZeroGPUErrorResponse
|
|
24
|
+
from .context import ZeroGPULog
|
|
21
25
|
from .lifecycle import zerogpu_mode_enabled
|
|
22
26
|
from .lifecycle import zerogpu_startup
|
|
27
|
+
from .middleware import ASGIScope
|
|
28
|
+
from .middleware import get_server_port
|
|
23
29
|
from .middleware import ZeroGPUMiddleware
|
|
24
30
|
|
|
25
31
|
|
|
@@ -84,24 +90,42 @@ def patch():
|
|
|
84
90
|
case 'warning':
|
|
85
91
|
return gr.Warning(message, **kwargs)
|
|
86
92
|
|
|
93
|
+
def exception_mapper(err: ZeroGPUErrorResponse, exc: Exception | None):
|
|
94
|
+
if isinstance(exc, gr.Error):
|
|
95
|
+
setattr(exc, 'print_exception', False)
|
|
96
|
+
return exc
|
|
97
|
+
detail = err['detail']
|
|
98
|
+
return error(
|
|
99
|
+
title=detail['title'],
|
|
100
|
+
message=detail['message'],
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def log_emitter(log: ZeroGPULog):
|
|
104
|
+
return info(
|
|
105
|
+
title=log['title'],
|
|
106
|
+
message=log['message'],
|
|
107
|
+
level=log['level'],
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def resolve_context():
|
|
111
|
+
if zerogpu_mode_enabled() and (request := LocalContext.request.get(None)) is not None:
|
|
112
|
+
scope = cast(ASGIScope | None, request.request.scope if request.request is not None else None)
|
|
113
|
+
return ZeroGPUContext(
|
|
114
|
+
exception_mapper=exception_mapper,
|
|
115
|
+
log_emitter=log_emitter,
|
|
116
|
+
worker_contextualizer=WorkerContextualizer,
|
|
117
|
+
disconnect_detector=disconnect_detector,
|
|
118
|
+
server_port=get_server_port(scope) if scope is not None else None,
|
|
119
|
+
headers={key.lower(): value for key, value in dict(getattr(request, 'headers', {})).items()},
|
|
120
|
+
)
|
|
121
|
+
|
|
87
122
|
def setup_middleware(app: FastAPI, *, skip_zerogpu_startup: bool = False):
|
|
88
123
|
mounted = any(middleware.cls is ZeroGPUMiddleware for middleware in app.user_middleware)
|
|
89
124
|
if not mounted:
|
|
90
125
|
app.add_middleware(
|
|
91
126
|
ZeroGPUMiddleware,
|
|
92
|
-
exception_mapper=
|
|
93
|
-
|
|
94
|
-
if isinstance(exc, gr.Error)
|
|
95
|
-
else error(
|
|
96
|
-
title=err['detail']['title'],
|
|
97
|
-
message=err['detail']['message'],
|
|
98
|
-
)
|
|
99
|
-
),
|
|
100
|
-
log_emitter=lambda log: info(
|
|
101
|
-
title=log['title'],
|
|
102
|
-
message=log['message'],
|
|
103
|
-
level=log['level'],
|
|
104
|
-
),
|
|
127
|
+
exception_mapper=exception_mapper,
|
|
128
|
+
log_emitter=log_emitter,
|
|
105
129
|
worker_contextualizer=WorkerContextualizer,
|
|
106
130
|
disconnect_detector=disconnect_detector,
|
|
107
131
|
skip_zerogpu_startup=skip_zerogpu_startup,
|
|
@@ -129,6 +153,7 @@ def patch():
|
|
|
129
153
|
gr.mount_gradio_app = mount_gradio_app
|
|
130
154
|
routes.mount_gradio_app = mount_gradio_app
|
|
131
155
|
http_server.start_server = start_server
|
|
156
|
+
context._context_resolver = resolve_context
|
|
132
157
|
_patch_queue()
|
|
133
158
|
|
|
134
159
|
|
|
@@ -87,7 +87,7 @@ class ZeroGPUMiddleware:
|
|
|
87
87
|
worker_contextualizer=self.worker_contextualizer,
|
|
88
88
|
disconnect_detector=self.disconnect_detector,
|
|
89
89
|
connection_state=connection_state,
|
|
90
|
-
server_port=
|
|
90
|
+
server_port=get_server_port(asgi_scope),
|
|
91
91
|
headers=_decode_headers(asgi_scope.get('headers', [])),
|
|
92
92
|
))
|
|
93
93
|
|
|
@@ -97,7 +97,7 @@ class ZeroGPUMiddleware:
|
|
|
97
97
|
ctx_var.reset(token)
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
def
|
|
100
|
+
def get_server_port(scope: ASGIScope):
|
|
101
101
|
match scope.get('server'):
|
|
102
102
|
case (_, int() as port):
|
|
103
103
|
return port
|
|
@@ -34,7 +34,7 @@ from .api import AllowToken
|
|
|
34
34
|
from .api import GPUSize
|
|
35
35
|
from .api import NvidiaIndex
|
|
36
36
|
from .api import NvidiaUUID
|
|
37
|
-
from .context import
|
|
37
|
+
from .context import get_context
|
|
38
38
|
from .tqdm import remove_tqdm_multiprocessing_lock
|
|
39
39
|
from .tqdm import tqdm
|
|
40
40
|
from .utils import apply_cleanups
|
|
@@ -170,7 +170,7 @@ def regular_function_wrapper(
|
|
|
170
170
|
if forked:
|
|
171
171
|
return task(*args, **kwargs)
|
|
172
172
|
|
|
173
|
-
ctx =
|
|
173
|
+
ctx = get_context()
|
|
174
174
|
duration_ = static_duration(duration, *args, **kwargs)
|
|
175
175
|
duration_ = process_duration(duration_)
|
|
176
176
|
schedule_response = client.schedule(task_id=task_id, duration=duration_, gpu_size=gpu_size)
|
|
@@ -297,7 +297,7 @@ def generator_function_wrapper(
|
|
|
297
297
|
yield from task(*args, **kwargs)
|
|
298
298
|
return
|
|
299
299
|
|
|
300
|
-
ctx =
|
|
300
|
+
ctx = get_context()
|
|
301
301
|
duration_ = static_duration(duration, *args, **kwargs)
|
|
302
302
|
duration_ = process_duration(duration_)
|
|
303
303
|
schedule_response = client.schedule(task_id=task_id, duration=duration_, gpu_size=gpu_size)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|