I have to send the image through the REST API service from my test C QT client to get some information about it. I've been trying to figure out for very long time, what's wrong with my POST request according follow documentation...
link: https://docs.facecloud.tevian.ru/
So i do it next way using QHttpMultiPart and QNetworkReply
QUrl testUrl("https://backend.facecloud.tevian.ru/api/v1/photos");
QNetworkRequest request(testUrl);
//auth token i've got before
request.setRawHeader(QByteArray("Authorization"), token.toUtf8());
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart firstPart;
const QString header = "application/json";
firstPart.setHeader(QNetworkRequest::ContentTypeHeader, header);
QJsonObject req;
QJsonDocument doc;
QByteArray data;
req.insert("fd_min_size",0);
req.insert("fd_max_size",0);
req.insert("fd_threshold",0.8);
req.insert("rotate_until_faces_found",true);
req.insert("orientation_classifier",true);
QJsonArray array;
array.push_back("0");
array.push_back("0");
array.push_back("1000");
array.push_back("1000");
req.insert("face", array);
req.insert("person_id",1);
doc = QJsonDocument(req);
data = doc.toJson();
firstPart.setBody(data);
QString img_path = "C:/Users/brode/Downloads/hi.jpg";
QString img_name = "hi.jpg";
QHttpPart secondPart;
secondPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
secondPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\"" img_name "\""));
QFile *file = new QFile(img_path);
if (!file->exists()) {
return;
}
file->open(QIODevice::ReadOnly);
secondPart.setBodyDevice(file);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(firstPart);
multiPart->append(secondPart);
QNetworkReply* reply = manager.post(request, multiPart);
multiPart->setParent(reply); // delete the multiPart with the reply
connect(reply, &QNetworkReply::readyRead,this, &rest_handler::readyRead);
First time i faced REST API...What i've done wrong?
CodePudding user response:
After playing around with the api
you are using, You are using wrong request format, the endpoint expects request with Content-Type: image/jpeg
not using multipart
. Also values like fd_min_size, face...
should be sent as query parameters
not in request body. The following piece of code works fine:
double fd_min_size = 0;
double fd_max_size = 0;
double fd_threshold=0.8;
bool rotate_until_faces_found = false;
bool orientation_classifier = false;
QVector <int>face = {0, 0, 1000, 1000};
int person_id = 1;
QString path = "https://backend.facecloud.tevian.ru/api/v1/photos";
// You don't have to add them all.
path = "?fd_min_size=" QString::number(fd_min_size);
path = "&fd_max_size=" QString::number(fd_max_size);
path = "&fd_threshold=" QString::number(fd_threshold);
path = "&rotate_until_faces_found=" (rotate_until_faces_found ? QString("true") : QString("false"));
path = "&orientation_classifier=" (orientation_classifier ? QString("true") : QString("false"));
path = "&face=";
for(int i = 0;i < static_cast<int>(face.size());i ) {
path = QString::number(face[i]);
if(i 1 != static_cast<int>(face.size())) {
path = ",";
}
}
path = "&person_id=" QString::number(person_id); // The only one required
QUrl testUrl(path);
QNetworkRequest request(testUrl);
//auth token i've got before
request.setRawHeader(QByteArray("Authorization"), "Bearer " token.toUtf8());
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
QString img_path = "C:/Users/xxx/Pictures/face.jpg";
QFile *file = new QFile(img_path);
if (!file->exists() || !file->open(QIODevice::ReadOnly)) {
return;
}
auto manager = new QNetworkAccessManager();
QNetworkReply *reply = manager->post(request, file);