-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Closed
Labels
Description
First Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google "How to X in FastAPI" and didn't find any information.
- I already read and followed all the tutorial in the docs and didn't find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse
import pandas as pd
from config import failure_path
app = FastAPI()
@app.post("/infer", tags=["inference"], response_class=FileResponse)
async def infer(input: UploadFile = File(...)) -> Union[FileResponse, dict]:
data = None
# Convert from CSV to pandas
if input.content_type == "text/csv":
data = await input.read()
temp_io = io.StringIO(data.decode("utf-8"))
data = pd.read_csv(temp_io)
else:
return {
"success": False,
"message": f"Content type {input.content_type} not supported (only CSV, 'text/csv' data allowed)",
}
print(f"Invoked with {data.shape[0]} records")
# Do the prediction
try:
predictions = model_server.predict(data, data_schema)
# Convert from dataframe to CSV
with NamedTemporaryFile() as temp:
predictions.to_csv(temp.name, index=False)
temp.seek(0)
return FileResponse(temp.name, media_type="text/csv")
except Exception as err:
# Write out an error file. This will be returned as the failureReason to the client.
trc = traceback.format_exc()
with open(failure_path, "w") as s:
s.write("Exception during inference: " + str(err) + "\n" + trc)
# Printing this causes the exception to be in the training job logs, as well.
print("Exception during inference: " + str(err) + "\n" + trc, file=sys.stderr)
# A non-zero exit code causes the training job to be marked as Failed.
return {
"success": False,
"message": f"Exception during inference: {str(err)} (check failure file for more details)",
}Description
- run the server (using docker)
- Open postman and make call to
/inferwith the appropriatecsvas input. - Returns output as
Internal Server Error
(PS - in order to test it, you can just use any random csv data, since the failing line should be caught by the exception anyways)
Operating System
Linux, macOS
Operating System Details
No response
FastAPI Version
0.86.0
Python Version
Python 3.10.8
Additional Context
Essentially, when I try to run this with some sample data, the line:
predictions = model_server.predict(data, data_schema)throws an Exception, which should be caught by except block and subsequently return a JSON with the error message. However, I run into an Internal Server Error, with the following traceback:
172.17.0.1 - - [12/Nov/2022:15:14:11 +0000] "POST /infer HTTP/1.1" 500 21 "-" "curl/7.84.0"
Invoked with 17 records
Exception during inference: "['nan'] not in index"
Traceback (most recent call last):
File "/opt/app/./inference_app.py", line 74, in infer
predictions = model_server.predict(data, data_schema)
File "/opt/app/./algorithm/model_server.py", line 76, in predict
preds_df["prediction"] = pd.DataFrame(preds_df[class_names], columns = class_names).idxmax(axis=1)
File "/usr/local/lib/python3.10/site-packages/pandas/core/frame.py", line 3810, in __getitem__
indexer = self.columns._get_indexer_strict(key, "columns")[1]
File "/usr/local/lib/python3.10/site-packages/pandas/core/indexes/base.py", line 6111, in _get_indexer_strict
self._raise_if_missing(keyarr, indexer, axis_name)
File "/usr/local/lib/python3.10/site-packages/pandas/core/indexes/base.py", line 6174, in _raise_if_missing
raise KeyError(f"{not_found} not in index")
KeyError: "['nan'] not in index"
INFO: - "POST /infer HTTP/1.0" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 419, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
raise exc
File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 680, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 275, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 264, in app
response = actual_response_class(content, **response_args)
File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 299, in __init__
media_type = guess_type(filename or path)[0] or "text/plain"
File "/usr/local/lib/python3.10/site-packages/starlette/responses.py", line 35, in guess_type
return mimetypes_guess_type(url, strict)
File "/usr/local/lib/python3.10/mimetypes.py", line 307, in guess_type
return _db.guess_type(url, strict)
File "/usr/local/lib/python3.10/mimetypes.py", line 122, in guess_type
url = os.fspath(url)
TypeError: expected str, bytes or os.PathLike object, not dictNow, I can/will fix the issue with the predict function, but even then, this error shows up (ie, circumventing the function for the time being). I don't understand where exactly the "type" of the response is being used, and what "url" is in this context.
Reactions are currently unavailable