Я пишу сервис FastAPI. Я получил архив .zstd от S3. Мне нужно вернуть распакованные данные json из архива. Я прочитал о fastapi.StreamingResponse
Мой код
import os
import cramjam
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile, File, Body, Path
from fastapi.responses import JSONResponse, StreamingResponse
def iter_decompressed_from_s3(s3_response: Dict, chunk_size: int = 1024 * 1024):
body = s3_response["Body"]
decompressor = cramjam.zstd.Decompressor()
try:
while True:
chunk = body.read(chunk_size)
if not chunk:
break
out = decompressor.decompress(chunk)
if out:
yield bytes(out)
tail = decompressor.flush()
if tail:
yield bytes(tail)
finally:
body.close()
@app.get("/{s3_path:path}")
async def get_file_content(s3_path: str, request: Request):
return StreamingResponse(
iter_decompressed_from_s3(s3_response=response), # ← вот твой "pip"!
media_type="application/octet-stream",
headers={
"Content-Disposition": f'attachment; filename="{s3_path}"',
"Cache-Control": "no-cache",
}
)
У меня ошибка
Traceback (most recent call last):
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 259, in __call__
| await wrap(partial(self.listen_for_disconnect, receive))
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 255, in wrap
| await func()
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 232, in listen_for_disconnect
| message = await receive()
| File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 531, in receive
| await self.message_event.wait()
| File "/usr/local/lib/python3.10/asyncio/locks.py", line 214, in wait
| await fut
| asyncio.exceptions.CancelledError: Cancelled by cancel scope 7efc4ae2dc90
+ Exception Group Traceback (most recent call last):
| | File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
| | result = await app( # type: ignore[func-returns-value]
| | File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
| | return await self.app(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
| | await super().__call__(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 113, in __call__
| | await self.middleware_stack(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 187, in __call__
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 165, in __call__
| | await self.app(scope, receive, _send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
| | await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
| | await app(scope, receive, sender)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 715, in __call__
| | await self.middleware_stack(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 735, in app
| | await route.handle(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 288, in handle
| | await self.app(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 76, in app
| | await wrap_app_handling_exceptions(app, request)(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
| | await app(scope, receive, sender)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 74, in app
| | await response(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 252, in __call__
| | async with anyio.create_task_group() as task_group:
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 767, in __aexit__
| | raise BaseExceptionGroup(
| | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
| +-+---------------- 1 ----------------
| | Traceback (most recent call last):
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 255, in wrap
| | await func()
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 244, in stream_response
| | async for chunk in self.body_iterator:
| | File "/usr/local/lib/python3.10/site-packages/starlette/concurrency.py", line 62, in iterate_in_threadpool
| | yield await anyio.to_thread.run_sync(_next, as_iterator)
| | File "/usr/local/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
| | return await get_async_backend().run_sync_in_worker_thread(
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2461, in run_sync_in_worker_thread
| | return await future
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 962, in run
| | result = context.run(func, *args)
| | File "/usr/local/lib/python3.10/site-packages/starlette/concurrency.py", line 51, in _next
| | return next(iterator)
| | File "/app/app/api/v1/geodata.py", line 34, in iter_decompressed_from_s3
| | out = decompressor.decompress(chunk)
| | OSError: incomplete frame
Подробнее здесь: https://stackoverflow.com/questions/798 ... lete-frame
Fastapi.StreamingResponse: OSError: неполный кадр ⇐ Python
Программы на Python
-
Anonymous
1768918605
Anonymous
Я пишу сервис FastAPI. Я получил архив .zstd от S3. Мне нужно вернуть распакованные данные json из архива. Я прочитал о fastapi.StreamingResponse
Мой код
import os
import cramjam
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile, File, Body, Path
from fastapi.responses import JSONResponse, StreamingResponse
def iter_decompressed_from_s3(s3_response: Dict, chunk_size: int = 1024 * 1024):
body = s3_response["Body"]
decompressor = cramjam.zstd.Decompressor()
try:
while True:
chunk = body.read(chunk_size)
if not chunk:
break
out = decompressor.decompress(chunk)
if out:
yield bytes(out)
tail = decompressor.flush()
if tail:
yield bytes(tail)
finally:
body.close()
@app.get("/{s3_path:path}")
async def get_file_content(s3_path: str, request: Request):
return StreamingResponse(
iter_decompressed_from_s3(s3_response=response), # ← вот твой "pip"!
media_type="application/octet-stream",
headers={
"Content-Disposition": f'attachment; filename="{s3_path}"',
"Cache-Control": "no-cache",
}
)
У меня ошибка
Traceback (most recent call last):
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 259, in __call__
| await wrap(partial(self.listen_for_disconnect, receive))
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 255, in wrap
| await func()
| File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 232, in listen_for_disconnect
| message = await receive()
| File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 531, in receive
| await self.message_event.wait()
| File "/usr/local/lib/python3.10/asyncio/locks.py", line 214, in wait
| await fut
| asyncio.exceptions.CancelledError: Cancelled by cancel scope 7efc4ae2dc90
+ Exception Group Traceback (most recent call last):
| | File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
| | result = await app( # type: ignore[func-returns-value]
| | File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
| | return await self.app(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
| | await super().__call__(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 113, in __call__
| | await self.middleware_stack(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 187, in __call__
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 165, in __call__
| | await self.app(scope, receive, _send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
| | await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
| | await app(scope, receive, sender)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 715, in __call__
| | await self.middleware_stack(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 735, in app
| | await route.handle(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 288, in handle
| | await self.app(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 76, in app
| | await wrap_app_handling_exceptions(app, request)(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
| | raise exc
| | File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
| | await app(scope, receive, sender)
| | File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 74, in app
| | await response(scope, receive, send)
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 252, in __call__
| | async with anyio.create_task_group() as task_group:
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 767, in __aexit__
| | raise BaseExceptionGroup(
| | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
| +-+---------------- 1 ----------------
| | Traceback (most recent call last):
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 255, in wrap
| | await func()
| | File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 244, in stream_response
| | async for chunk in self.body_iterator:
| | File "/usr/local/lib/python3.10/site-packages/starlette/concurrency.py", line 62, in iterate_in_threadpool
| | yield await anyio.to_thread.run_sync(_next, as_iterator)
| | File "/usr/local/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
| | return await get_async_backend().run_sync_in_worker_thread(
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2461, in run_sync_in_worker_thread
| | return await future
| | File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 962, in run
| | result = context.run(func, *args)
| | File "/usr/local/lib/python3.10/site-packages/starlette/concurrency.py", line 51, in _next
| | return next(iterator)
| | File "/app/app/api/v1/geodata.py", line 34, in iter_decompressed_from_s3
| | out = decompressor.decompress(chunk)
| | OSError: incomplete frame
Подробнее здесь: [url]https://stackoverflow.com/questions/79872050/fastapi-streamingresponse-oserror-incomplete-frame[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия