'How do I implement this Python post request in Rust?
I have the following python script that uploads a image to imgurl:
headers = {"Authorization": "Client-ID "+client_id}
data = {
"key": client_secret,
"image": base64.b64encode(file),
"type": "base64",
}
r = requests.post("https://api.imgur.com/3/upload.json",headers=headers,data=data)
if json.loads(r.content)["status"] == 200:
link = json.loads(r.content)["data"]["link"]
print(link)
I am trying to remake that on rust, this is how far i came:
use curl::easy::{Easy,List};
fn main() {
let mut list = List::new();
list.append("Authorization Client-ID MYCLIENTID").unwrap();
let mut easy = Easy::new();
easy.url("https://api.imgur.com/3/upload.json").unwrap();
easy.http_headers(list).unwrap();
easy.post(true).unwrap();
easy.write_function(|data| {
stdout().write_all(data).unwrap();
Ok(data.len())
}).unwrap();
easy.perform().unwrap();
}
I have no idea how to make the data part of the python script on rust.
I tried using reqwest but i found no working examples on post requests with multipart/form-data.
Solution 1:[1]
Easy Curl
You can use read_function
use data_encoding::BASE64;
use std::collections::HashMap;
fn main() {
let mut data = HashMap::new();
data.insert("key", client_secret);
data.insert("image", BASE64.encode(file));
data.insert("type", "base64");
let post_data = format!("{:?}", data);
let mut list = List::new();
list.append("Authorization Client-ID MYCLIENTID").unwrap();
let mut easy = Easy::new();
easy.url("https://api.imgur.com/3/upload.json").unwrap();
easy.http_headers(list).unwrap();
easy.post(true).unwrap();
easy.read_function(|into| {
Ok(post_data.as_bytes().read(into).unwrap())
});
easy.write_function(|data| {
stdout().write_all(data).unwrap();
Ok(data.len())
}).unwrap();
easy.perform().unwrap();
}
use data_encoding::BASE64;
use std::collections::HashMap;
fn main() {
let mut data = HashMap::new();
data.insert("key", client_secret);
data.insert("image", BASE64.encode(file));
data.insert("type", "base64");
let post_data = format!("{:?}", data);
let mut list = List::new();
list.append("Authorization Client-ID MYCLIENTID").unwrap();
let mut easy = Easy::new();
easy.url("https://api.imgur.com/3/upload.json").unwrap();
easy.http_headers(list).unwrap();
easy.post(true).unwrap();
easy.post_fields_copy(post_data.as_bytes());
easy.write_function(|data| {
stdout().write_all(data).unwrap();
Ok(data.len())
}).unwrap();
easy.perform().unwrap();
}
Reqwest
use reqwest::header::HeaderName;
fn main() {
let mut data = HashMap::new();
data.insert("key", client_secret);
data.insert("image", BASE64.encode(file));
data.insert("type", "base64");
let mut headers = reqwest::header::HeaderMap::new();
let name: HeaderName = "Authorization".parse().unwrap();
headers.insert(name, "Client-ID MYCLIENTID".parse().unwrap());
let client = reqwest::blocking::Client::new();
let res = client.post("https://api.imgur.com/3/upload.json")
.headers(headers)
.json(&data)
.send();
}
Solution 2:[2]
I try to use curl and reqwest to complete, you can refer to curl's test case
use std::io::{stdout, Write};
use curl::easy::{Easy, Form, List};
fn main() {
let mut list = List::new();
list.append("Authorization: Client-ID MYCLIENTID").unwrap();
let mut easy = Easy::new();
easy.url("http://127.0.0.1:8000/").unwrap();
easy.http_headers(list).unwrap();
let mut form = Form::new();
form.part("key").contents("key".as_bytes()).add();
form.part("image").contents("image".as_bytes()).add();
form.part("type").contents("type".as_bytes()).add();
easy.write_function(|data| {
stdout().write_all(data).unwrap();
Ok(data.len())
}).unwrap();
easy.httppost(form);
easy.perform().unwrap();
}
Path: /
Headers:
Host: 127.0.0.1:8000
Accept: */*
Authorization: Client-ID MYCLIENTID
Content-Length: 337
Content-Type: multipart/form-data; boundary=------------------------7f3cd45715114afd
Body:
--------------------------7f3cd45715114afd
Content-Disposition: form-data; name="key"
key
--------------------------7f3cd45715114afd
Content-Disposition: form-data; name="image"
image
--------------------------7f3cd45715114afd
Content-Disposition: form-data; name="type"
type
--------------------------7f3cd45715114afd--
127.0.0.1 - - [19/Mar/2022 01:48:29] "POST / HTTP/1.1" 200 -
add reqewst implementation
reqwest = { version = "0.11.10", features = ['multipart', "blocking"] }
use reqwest::blocking::multipart;
use reqwest::header::HeaderName;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let form = multipart::Form::new()
.text("key", "key")
.text("type", "type");
let mut headers = reqwest::header::HeaderMap::new();
let name: HeaderName = "Authorization".parse().unwrap();
headers.insert(name, "Client-ID MYCLIENTID".parse().unwrap());
let client = reqwest::blocking::Client::new();
let res = client.post("http://127.0.0.1:8000/")
.headers(headers)
.multipart(form)
.send()?;
Ok(())
}
Path: /
Headers:
authorization: Client-ID MYCLIENTID
content-type: multipart/form-data; boundary=333d5f9f981ff8c4-52968a2548643dba-06b19c9eb1896219-083c4cc6b1618966
content-length: 319
accept: */*
host: 127.0.0.1:8000
Body:
--333d5f9f981ff8c4-52968a2548643dba-06b19c9eb1896219-083c4cc6b1618966
Content-Disposition: form-data; name="key"
key
--333d5f9f981ff8c4-52968a2548643dba-06b19c9eb1896219-083c4cc6b1618966
Content-Disposition: form-data; name="type"
type
--333d5f9f981ff8c4-52968a2548643dba-06b19c9eb1896219-083c4cc6b1618966--
127.0.0.1 - - [19/Mar/2022 02:27:40] "POST / HTTP/1.1" 200 -
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Chandan |
| Solution 2 |
