I have created a working localhost API with FastAPI. The POST takes a PNG, does some image processing and returns a PNG as expected when I click the 'try it out' button in the FastAPI generated docs:
The curl post command shows as follows:
curl -X 'POST' \
'http://localhost:8345/api/predict' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=@test_img.png;type=image/png'
The image File is successfully retrieved from the image picker library. (Where the image1 object has been initialized as File image1;
in the app page's class.
Future getImage() async {
var imageTmp = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
image1 = imageTmp;
print('Image Path $image1');
});
}
I tried to emulate the API call with the below function in Flutter.
doUpload() {
/*
curl -X 'POST' \
'http://192.168.178.26:8345/api/predict' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=@test_img.png;type=image/png'
*/
var request = http.MultipartRequest(
'POST',
Uri.parse("http://<my locally hosted ip>:8345/api/predict"),
);
Map<String, String> headers = {"Content-type": "multipart/form-data"};
request.files.add(
http.MultipartFile(
'image',
image1.readAsBytes().asStream(),
image1.lengthSync(),
filename: 'filename',
contentType: MediaType('image', 'png'),
),
);
request.headers.addAll(headers);
print("request: " + request.toString());
request.send().then((value) => print(value.statusCode));
}
When I run the doUpload()
function, a POST is successfully sent to the localhost API, but it returns a 422 error 'unprocessable entity'.
What I tried:
File: '/data/user/0/<my package name>/cache/image_picker3300408791299772729jpg'
looking at my local UI filepath, I see:
It shows no folder named cache, so I can't inspect it like this. However, the image picker saves it with a jpg at the end (not .jpg, is this normal?)
value
has properties like statusCode and reason, but I don't see a full json output option.To mimic that curl
command exactly, use this: (I've used the convenience constructor for simplicity)
final request = http.MultipartRequest(
'POST',
Uri.parse('http://<my locally hosted ip>:8345/api/predict'),
);
request.files.add(
await http.MultipartFile.fromPath(
'file', // NOTE - this value must match the 'file=' at the start of -F
image1.path,
contentType: MediaType('image', 'png'),
),
);
final response = await http.Response.fromStream(await request.send());
print(response.body);