Amit Gelber
03/11/2024, 3:07 PM@bentoml.api
async def generate(self, input_request: GenerateImageRequestBase) -> GenerateImageResponseBase:
app_logger.info(f"request type {TYPE} for {input_request.studio_name} with {input_request}")
# prepare model params
model_params = map_params_to_pipeline(input_request)
where GenerateImageRequestBase is pydantic class
swagger seems to generate the following request example:
{
"input_request": {
"modelId": "pixel-art-xl-lora",
"type": "character",
"prompt": "a 3d rendering",
"numOfImages": 4,
"samplingSteps": 120,
"width": 1024}
I expected for for the request to be
{
"modelId": "pixel-art-xl-lora",
"type": "character",
"prompt": "a 3d rendering",
"numOfImages": 4,
"samplingSteps": 120,
"width": 1024
}
not wrapped in input_request key
I understand the alternative is not to use pydantic class and add each param explicitly in generate function (I prefer pydantic class)
also, when using pil image as input, all request turns into files? it that on purpose?Jian Shen Yap
03/11/2024, 4:59 PM@bentoml.service
class MyService:
@bentoml.api(input_spec=GenerateImageRequestBase)
def generate(self, **params: t.Any) -> str:
...
This is how you would do it for your use case.
also, when using pil image as input, all request turns into files?the request will become a
multipart/form-data request. I don't think it turns everything into file? @Frost MingAmit Gelber
03/11/2024, 5:01 PMJian Shen Yap
03/11/2024, 5:03 PMformAmit Gelber
03/11/2024, 7:10 PMtry:
model_params = map_params_to_pipeline(input_request)
except KeyError as exc:
return JSONResponse(
{"detail": f"Missing required parameter: {exc}"},
status_code=400,
)Frost Ming
03/12/2024, 12:50 AMfrom bentoml.exceptions import BadInput
raise BadInput(f"Missing required parameter: {exc}")Frost Ming
03/12/2024, 12:50 AMAmit Gelber
03/12/2024, 11:54 AMAmit Gelber
03/12/2024, 7:20 PMFrost Ming
03/13/2024, 2:00 AMFrost Ming
03/13/2024, 5:22 AMService and call it like a normal object.
svc = MyService()
assert svc.predict(...) == expectedAmit Gelber
03/13/2024, 6:30 PMAmit Gelber
03/13/2024, 7:11 PMFrost Ming
03/14/2024, 7:25 AMimport httpx
app = MyService.to_asgi(init=True)
client = httpx.AsyncClient(base_url="<http://testserver>", app=app)
response = await client.post("/predict", json=[[1,2,3,4]])
assert response.json() == [1]Amit Gelber
03/14/2024, 7:40 AMAmit Gelber
03/14/2024, 6:36 PMapp = Txt2Img.to_asgi()
async with httpx.AsyncClient(base_url="<http://testserver>", app=app) as client:
response = await client.post("/generate", json=detailed_data)
media_type = request.headers.get("Content-Type", "application/json")
media_type = media_type.split(";")[0].strip()
if self.is_main and media_type == "application/vnd.bentoml+pickle":
# Disallow pickle media type for main service for security reasons
raise BentoMLException(
"Pickle media type is not allowed for main service",
error_code=HTTPStatus.UNSUPPORTED_MEDIA_TYPE,
)
method = self.service.apis[name]
> func = getattr(self._service_instance, name)
E AttributeError: 'NoneType' object has no attribute 'generate'Frost Ming
03/14/2024, 11:16 PM