En utilisant le module python fastAPI , je ne peux pas comprendre comment renvoyer une image. Dans le flacon, je ferais quelque chose comme ceci:
@app.route("/vector_image", methods=["POST"]) def image_endpoint(): # img = ... # Create the image here return Response(img, mimetype="image/png")
quel est l'appel correspondant dans ce module?
6 Réponses :
Ce n'est pas encore correctement documenté, mais vous pouvez utiliser n'importe quoi de Starlette.
Ainsi, vous pouvez utiliser un FileResponse
s'il s'agit d'un fichier sur disque avec un chemin: https://www.starlette.io/responses/#fileresponse
S'il s'agit d'un objet de type fichier créé dans votre opération de chemin , dans la prochaine version stable de Starlette (utilisée en interne par FastAPI), vous pourrez également le renvoyer dans un StreamingResponse
.
Merci pour la réponse! Je l'ai fait fonctionner avec votre suggestion mais ce n'était pas facile (et probablement exagéré!). Voir ma solution ci-dessous. En dehors de ce problème, fastAPI a été un plaisir de travailler avec un très bien documenté, merci de l'avoir fourni!
J'ai également créé une balise pour votre bibliothèque dans la question. N'hésitez pas à le modifier et à le «regarder» pour voir les questions des autres utilisateurs.
La réponse de @ SebastiánRamírez m'a orienté dans la bonne direction, mais pour ceux qui cherchent à résoudre le problème, j'avais besoin de quelques lignes de code pour le faire fonctionner. J'avais besoin d'importer FileResponse
de starlette (pas de fastAPI?), D'ajouter le support CORS et de revenir à partir d'un fichier temporaire. Il existe peut-être un meilleur moyen, mais je n'ai pas pu faire fonctionner le streaming:
from starlette.responses import FileResponse from starlette.middleware.cors import CORSMiddleware import tempfile app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"] ) @app.post("/vector_image") def image_endpoint(*, vector): # Returns a raw PNG from the document vector (define here) img = my_function(vector) with tempfile.NamedTemporaryFile(mode="w+b", suffix=".png", delete=False) as FOUT: FOUT.write(img) return FileResponse(FOUT.name, media_type="image/png")
pourriez-vous être plus précis s'il vous plaît? comme où est le nom du fichier? quel est l'article, où est l'itinéraire?
@PekoChan Vous avez raison, il me manquait certaines parties. J'essayais d'adapter le code que j'utilisais réellement à un exemple minimal. Je l'ai fait un peu trop minimal, j'espère que je l'ai corrigé.
J'ai eu un problème similaire mais avec une image cv2. Cela peut être utile pour d'autres. Utilise StreamingResponse
.
import io from starlette.responses import StreamingResponse app = FastAPI() @app.post("/vector_image") def image_endpoint(*, vector): # Returns a cv2 image array from the document vector cv2img = my_function(vector) res, im_png = cv2.imencode(".png", cv2img) return StreamingResponse(io.BytesIO(im_png.tobytes()), media_type="image/png")
Merci! Je pense que c'est une bien meilleure réponse que mon hack qui nécessitait un fichier temporaire.
Si vous utilisez BytesIO
particulier avec PIL / skimage, assurez-vous de faire également img.seek(0)
avant de retourner!
Merci à la réponse de @ biophetik, avec un rappel important qui m'a semé la confusion: si vous utilisez BytesIO
particulier avec PIL / skimage, assurez-vous de faire également img.seek(0)
avant de revenir!
@app.get("/generate") def generate(data: str): img = generate_image(data) print('img=%s' % (img.shape,)) buf = BytesIO() imsave(buf, img, format='JPEG', quality=100) buf.seek(0) # important here! return StreamingResponse(buf, media_type="image/jpeg", headers={'Content-Disposition': 'inline; filename="%s.jpg"' %(data,)})
Toutes les autres réponses sont sur le point, mais maintenant il est si facile de renvoyer une image
from fastapi.responses import FileResponse @app.get("/") async def main(): return FileResponse("your_image.jpeg")
Vous pouvez faire quelque chose de très similaire dans FastAPI
from fastapi import FastAPI, Response app = FastAPI() @app.post("/vector_image/") async def image_endpoint(): # img = ... # Create the image here return Response(content=img, media_type="image/png")