How to send a progress of operation in a FastAPI app?

前端 未结 2 883
盖世英雄少女心
盖世英雄少女心 2021-02-05 19:56

I have deployed a fastapi endpoint,

from fastapi import FastAPI, UploadFile
from typing import List

app = FastAPI()

@app.post(\'/work/test\')
async def testing(         


        
2条回答
  •  野性不改
    2021-02-05 20:34

    Below is solution which uses uniq identifiers and globally available dictionary which holds information about the jobs:

    NOTE: Code below is safe to use until you use dynamic keys values ( In sample uuid in use) and keep application within single process.

    1. To start the app create a file main.py
    2. Run uvicorn main:app --reload
    3. Create job entry by accessing http://127.0.0.1:8000/
    4. Repeat step 3 to create multiple jobs
    5. Go to http://127.0.0.1/status page to see page statuses.
    6. Go to http://127.0.0.1/status/{identifier} to see progression of the job by the job id.

    Code of app:

    from fastapi import FastAPI, UploadFile
    import uuid
    from typing import List
    
    
    import asyncio
    
    
    context = {'jobs': {}}
    
    app = FastAPI()
    
    
    
    async def do_work(job_key, files=None):
        iter_over = files if files else range(100)
        for file, file_number in enumerate(iter_over):
            jobs = context['jobs']
            job_info = jobs[job_key]
            job_info['iteration'] = file_number
            job_info['status'] = 'inprogress'
            await asyncio.sleep(1)
        pending_jobs[job_key]['status'] = 'done'
    
    
    @app.post('/work/test')
    async def testing(files: List[UploadFile]):
        identifier = str(uuid.uuid4())
        context[jobs][identifier] = {}
        asyncio.run_coroutine_threadsafe(do_work(identifier, files), loop=asyncio.get_running_loop())
    
        return {"identifier": identifier}
    
    
    @app.get('/')
    async def get_testing():
        identifier = str(uuid.uuid4())
        context['jobs'][identifier] = {}
        asyncio.run_coroutine_threadsafe(do_work(identifier), loop=asyncio.get_running_loop())
    
        return {"identifier": identifier}
    
    @app.get('/status')
    def status():
        return {
            'all': list(context['jobs'].values()),
        }
    
    @app.get('/status/{identifier}')
    async def status(identifier):
        return {
            "status": context['jobs'].get(identifier, 'job with that identifier is undefined'),
        }
    
    

提交回复
热议问题