Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

634
Views
FastAPI: ¿Cómo registrar el valor de retorno de un método POST después de devolver la respuesta?

Así que estoy trabajando en mi primera API REST, así que pido disculpas de antemano si me perdí algo básico. De todos modos, tengo una función que toma una solicitud json de otro servidor, la procesa (hace una predicción basada en los datos) y devuelve otro json con los resultados. Me gustaría mantener un registro en el disco local del servidor de todas las solicitudes a este punto final junto con sus resultados, con fines de evaluación y para volver a entrenar el modelo. Sin embargo, con el fin de minimizar la latencia de devolver el resultado al usuario, me gustaría devolver primero los datos de respuesta y luego escribirlos en el disco local. No es obvio para mí cómo hacer esto correctamente, ya que el paradigma FastAPI requiere que el resultado de un método POST sea el valor de retorno de la función decorada, por lo que cualquier cosa que quiera hacer con los datos debe hacerse antes de que se devuelva.

A continuación se muestra un ejemplo funcional mínimo de lo que creo que es mi intento más cercano de hacerlo bien hasta el momento, usando un objeto personalizado con un decorador de log : mi idea era solo asignar el resultado al objeto de registro como un atributo de clase, luego usar otro método para escribirlo en el disco, pero no puedo averiguar cómo asegurarme de que esa función se llame después de get_data cada vez.

 import json import uvicorn from fastapi import FastAPI, Request from functools import wraps from pydantic import BaseModel class Blob(BaseModel): id: int x: float def crunch_numbers(data: Blob) -> dict: # does some stuff return {'foo': 'bar'} class PostResponseLogger: def __init__(self) -> None: self.post_result = None def log(self, func, *args, **kwargs): @wraps(func) def func_to_log(*args, **kwargs): post_result = func(*args, **kwargs) self.post_result = post_result # how can this be done outside of this function ??? self.write_data() return post_result return func_to_log def write_data(self): if self.post_result: with open('output.json', 'w') as f: json.dump(self.post_result, f) def main(): app = FastAPI() logger = PostResponseLogger() @app.post('/get_data/') @logger.log def get_data(input_json: dict, request: Request): result = crunch_numbers(input_json) return result uvicorn.run(app=app) if __name__ == '__main__': main()

Básicamente, mi pregunta se reduce a: "¿hay alguna manera, en la clase PostResponseLogger , de llamar automáticamente a self.write_data después de cada llamada a self.log ?", pero si estoy usando el enfoque equivocado, cualquier otra sugerencia es tambien bienvenido :)

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Podría tener una background task para ese propósito. Una tarea en segundo plano "se ejecutará solo una vez que se haya enviado la respuesta" (según la documentación de Starlette ). Puede definir una función de tarea para que se ejecute en segundo plano para escribir los datos de registro, como se muestra a continuación:

 def write_log_data(): logger.write_data()

Defina un parámetro con una declaración de tipo de BackgroundTasks a su route , y dentro de la route , pase la función de tarea (arriba) al objeto background_tasks con el método add_task() :

 from fastapi import BackgroundTasks @app.post('/get_data/') @logger.log def get_data(input_json: dict, request: Request, background_tasks: BackgroundTasks): result = crunch_numbers(input_json) background_tasks.add_task(write_log_data) return result

Se podría aplicar el mismo principio si se usara un middleware para capturar y registrar los datos de respuesta, como se describe aquí . Como referencia futura, si usted (o cualquier otra persona) alguna vez necesita usar la sintaxis async/await y se encuentra con problemas de concurrencia (mientras realiza algunos cálculos pesados en segundo plano), consulte la documentación aquí , así como esta y esta respuesta .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!