Skip to content

Commit

Permalink
Added client disconnect, but task continues to execute asynchronously
Browse files Browse the repository at this point in the history
  • Loading branch information
NastyBoget committed Dec 10, 2024
1 parent d5c321f commit 5ffdb35
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
3 changes: 2 additions & 1 deletion dedoc/api/cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from dedoc.config import get_config

logger = get_config().get("logger", logging.getLogger())


@asynccontextmanager
async def cancel_on_disconnect(request: Request) -> None:
Expand All @@ -16,7 +18,6 @@ async def cancel_on_disconnect(request: Request) -> None:
Source: https://github.com/dorinclisu/runner-with-api
See discussion: https://github.com/fastapi/fastapi/discussions/8805
"""
logger = get_config().get("logger", logging.getLogger())
async with create_task_group() as task_group:
async def watch_disconnect() -> None:
while True:
Expand Down
31 changes: 23 additions & 8 deletions dedoc/api/dedoc_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import base64
import dataclasses
import importlib
Expand All @@ -7,6 +8,7 @@
import traceback
from typing import Optional

from anyio import get_cancelled_exc_class
from fastapi import Depends, FastAPI, File, Request, Response, UploadFile
from fastapi.responses import ORJSONResponse, UJSONResponse
from fastapi.staticfiles import StaticFiles
Expand Down Expand Up @@ -75,16 +77,18 @@ async def upload(request: Request, file: UploadFile = File(...), query_params: Q
if not file or file.filename == "":
raise MissingFileError("Error: Missing content in request_post file parameter", version=dedoc.version.__version__)

return_format = str(parameters.get("return_format", "json")).lower()

loop = asyncio.get_running_loop()
async with cancel_on_disconnect(request):
with tempfile.TemporaryDirectory() as tmpdir:
file_path = save_upload_file(file, tmpdir)
document_tree = manager.parse(file_path, parameters={**dict(parameters), "attachments_dir": tmpdir})

if return_format == "html":
__add_base64_info_to_attachments(document_tree, tmpdir)
try:
future = loop.run_in_executor(None, __parse_file, parameters, file)
document_tree = await future
except get_cancelled_exc_class():
future.cancel(DedocError)
loop.stop()
loop.close()
return JSONResponse(status_code=499, content={})

return_format = str(parameters.get("return_format", "json")).lower()
if return_format == "html":
html_content = json2html(
text="",
Expand Down Expand Up @@ -117,6 +121,17 @@ async def upload(request: Request, file: UploadFile = File(...), query_params: Q
return ORJSONResponse(content=document_tree.to_api_schema().model_dump())


def __parse_file(parameters: dict, file: UploadFile) -> ParsedDocument:
return_format = str(parameters.get("return_format", "json")).lower()
with tempfile.TemporaryDirectory() as tmpdir:
file_path = save_upload_file(file, tmpdir)
document_tree = manager.parse(file_path, parameters={**dict(parameters), "attachments_dir": tmpdir})

if return_format == "html":
__add_base64_info_to_attachments(document_tree, tmpdir)
return document_tree


@app.get("/upload_example")
async def upload_example(file_name: str, return_format: Optional[str] = None) -> Response:
file_path = os.path.join(static_path, "examples", file_name)
Expand Down

0 comments on commit 5ffdb35

Please sign in to comment.