Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

641
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda