-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Describe the bug
The predict() function in vetiver/server.py sends DataFrame data using requests.post(endpoint, data=...), which transmits the JSON as a raw byte string without setting Content-Type: application/json.
On the server side, the /predict endpoint declares its input as List[Model], relying on FastAPI + Pydantic to parse the body. Pydantic v1 was lenient enough to coerce the raw bytes into the expected type, but pydantic v2 strictly rejects it with a 422:
"Input should be a valid list".
data= sends the body as raw bytes. It should use json= (or set the content type to application/json) so that FastAPI correctly parses the body before handing it to pydantic for validation.
pydantic: 2.12.5
vetiver: 0.2.6
To Reproduce
import vetiver
from fastapi.testclient import TestClient
X, y = vetiver.mock.get_mock_data()
model = vetiver.mock.get_mock_model().fit(X, y)
v = vetiver.VetiverModel(model=model, model_name="model", prototype_data=X)
app = vetiver.VetiverAPI(v).app
client = TestClient(app)
response = vetiver.predict(
"http://testserver/predict", X, test_client=client
)Traceback (most recent call last):
File "vetiver/server.py", line 379, in predict
response.raise_for_status()
File "httpx/_models.py", line 829, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'http://testserver/predict'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "demo.py", line 11, in <module>
response = vetiver.predict(
"http://testserver/predict", X, test_client=client
)
File "vetiver/server.py", line 382, in predict
raise TypeError(re.sub(r"\n", ": ", response.text))
TypeError: 1 validation error:: {'type': 'list_type', 'loc': ('body',), 'msg': 'Input should be a valid list', 'input':
b'[{"B":54,"C":48,"D":68},...]'}: : File "vetiver/server.py", line 238, in custom_endpoint: POST /predict
Expected behavior
vetiver.predict() should return a DataFrame of predictions. With pydantic<2 installed, it does
Additional context
Add any other context about the problem here.