Spaces:
Sleeping
Sleeping
Adjusted ping every 270 seconds for large computations up to 900 seconds
Browse files
main.py
CHANGED
|
@@ -38,7 +38,7 @@ SDK_MAX_BODY_BYTES = int(os.getenv("SDK_MAX_BODY_BYTES", "25000000")) # 25MB de
|
|
| 38 |
SDK_MAX_BODY_BYTES_extended = int(os.getenv("SDK_MAX_BODY_BYTES_extended", "125000000")) # 125MB default for prod
|
| 39 |
|
| 40 |
# How long to wait for upstream (API) response; long runs may need 30+ min (1800+)
|
| 41 |
-
UPSTREAM_TIMEOUT = float(os.getenv("UPSTREAM_TIMEOUT", "
|
| 42 |
# While waiting for a response, ping upstream every N seconds so the backend Space does not sleep
|
| 43 |
PING_UPSTREAM_INTERVAL = float(os.getenv("PING_UPSTREAM_INTERVAL", "270"))
|
| 44 |
|
|
@@ -173,22 +173,44 @@ async def _forward_stream(path: str, files=None, data=None, user_token: str | No
|
|
| 173 |
headers_holder = {}
|
| 174 |
|
| 175 |
async def body_iter():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
try:
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
# Buffer entire payload and yield once
|
| 185 |
-
chunk = await resp.aread()
|
| 186 |
-
yield chunk
|
| 187 |
-
return
|
| 188 |
-
|
| 189 |
-
async for chunk in resp.aiter_raw():
|
| 190 |
-
yield chunk
|
| 191 |
finally:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
await _cancel_ping_task(ping_task)
|
| 193 |
await client.aclose()
|
| 194 |
|
|
@@ -251,20 +273,44 @@ async def _forward_demo_stream(path: str, *, files: dict | None, data: dict | No
|
|
| 251 |
headers_holder = {}
|
| 252 |
|
| 253 |
async def body_iter():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
try:
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
yield chunk
|
| 263 |
-
return
|
| 264 |
-
|
| 265 |
-
async for chunk in resp.aiter_raw():
|
| 266 |
-
yield chunk
|
| 267 |
finally:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
await _cancel_ping_task(ping_task)
|
| 269 |
await client.aclose()
|
| 270 |
|
|
|
|
| 38 |
SDK_MAX_BODY_BYTES_extended = int(os.getenv("SDK_MAX_BODY_BYTES_extended", "125000000")) # 125MB default for prod
|
| 39 |
|
| 40 |
# How long to wait for upstream (API) response; long runs may need 30+ min (1800+)
|
| 41 |
+
UPSTREAM_TIMEOUT = float(os.getenv("UPSTREAM_TIMEOUT", "900")) # 15 minutes
|
| 42 |
# While waiting for a response, ping upstream every N seconds so the backend Space does not sleep
|
| 43 |
PING_UPSTREAM_INTERVAL = float(os.getenv("PING_UPSTREAM_INTERVAL", "270"))
|
| 44 |
|
|
|
|
| 173 |
headers_holder = {}
|
| 174 |
|
| 175 |
async def body_iter():
|
| 176 |
+
chunk_queue: asyncio.Queue = asyncio.Queue()
|
| 177 |
+
stream_done = {"done": False, "exc": None}
|
| 178 |
+
|
| 179 |
+
async def stream_reader():
|
| 180 |
+
try:
|
| 181 |
+
async with stream_ctx as resp:
|
| 182 |
+
status_holder["code"] = resp.status_code
|
| 183 |
+
media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
|
| 184 |
+
headers_holder.update(_filter_resp_headers(resp.headers))
|
| 185 |
+
if resp.status_code >= 400:
|
| 186 |
+
chunk = await resp.aread()
|
| 187 |
+
await chunk_queue.put(chunk)
|
| 188 |
+
await chunk_queue.put(None)
|
| 189 |
+
return
|
| 190 |
+
async for chunk in resp.aiter_raw():
|
| 191 |
+
await chunk_queue.put(chunk)
|
| 192 |
+
await chunk_queue.put(None)
|
| 193 |
+
except Exception as e:
|
| 194 |
+
stream_done["exc"] = e
|
| 195 |
+
await chunk_queue.put(None)
|
| 196 |
+
finally:
|
| 197 |
+
stream_done["done"] = True
|
| 198 |
+
|
| 199 |
+
reader_task = asyncio.create_task(stream_reader())
|
| 200 |
try:
|
| 201 |
+
while True:
|
| 202 |
+
chunk = await chunk_queue.get()
|
| 203 |
+
if chunk is None:
|
| 204 |
+
if stream_done["exc"]:
|
| 205 |
+
raise stream_done["exc"]
|
| 206 |
+
break
|
| 207 |
+
yield chunk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
finally:
|
| 209 |
+
reader_task.cancel()
|
| 210 |
+
try:
|
| 211 |
+
await reader_task
|
| 212 |
+
except asyncio.CancelledError:
|
| 213 |
+
pass
|
| 214 |
await _cancel_ping_task(ping_task)
|
| 215 |
await client.aclose()
|
| 216 |
|
|
|
|
| 273 |
headers_holder = {}
|
| 274 |
|
| 275 |
async def body_iter():
|
| 276 |
+
chunk_queue: asyncio.Queue = asyncio.Queue()
|
| 277 |
+
stream_done = {"done": False, "exc": None}
|
| 278 |
+
|
| 279 |
+
async def stream_reader():
|
| 280 |
+
try:
|
| 281 |
+
async with stream_ctx as resp:
|
| 282 |
+
status_holder["code"] = resp.status_code
|
| 283 |
+
media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
|
| 284 |
+
headers_holder.update(_filter_resp_headers(resp.headers))
|
| 285 |
+
if resp.status_code >= 400:
|
| 286 |
+
chunk = await resp.aread()
|
| 287 |
+
await chunk_queue.put(chunk)
|
| 288 |
+
await chunk_queue.put(None)
|
| 289 |
+
return
|
| 290 |
+
async for chunk in resp.aiter_raw():
|
| 291 |
+
await chunk_queue.put(chunk)
|
| 292 |
+
await chunk_queue.put(None)
|
| 293 |
+
except Exception as e:
|
| 294 |
+
stream_done["exc"] = e
|
| 295 |
+
await chunk_queue.put(None)
|
| 296 |
+
finally:
|
| 297 |
+
stream_done["done"] = True
|
| 298 |
+
|
| 299 |
+
reader_task = asyncio.create_task(stream_reader())
|
| 300 |
try:
|
| 301 |
+
while True:
|
| 302 |
+
chunk = await chunk_queue.get()
|
| 303 |
+
if chunk is None:
|
| 304 |
+
if stream_done["exc"]:
|
| 305 |
+
raise stream_done["exc"]
|
| 306 |
+
break
|
| 307 |
+
yield chunk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
finally:
|
| 309 |
+
reader_task.cancel()
|
| 310 |
+
try:
|
| 311 |
+
await reader_task
|
| 312 |
+
except asyncio.CancelledError:
|
| 313 |
+
pass
|
| 314 |
await _cancel_ping_task(ping_task)
|
| 315 |
await client.aclose()
|
| 316 |
|