python - 创建包含多个 HTTP 请求的 mime/multipart 请求

标签 python asp.net asp.net-web-api python-requests

我正在关注 this使用 ASP.NET 4.5 批处理 http 请求的教程。我有 sample工作,现在我需要用 Python 编写客户端应用程序。

此代码创建批处理请求并将其发送到 Web API:

JsonMediaTypeFormatter formatter = new JsonMediaTypeFormatter();
//Create a request to query for customers
HttpRequestMessage queryCustomersRequest = new HttpRequestMessage(HttpMethod.Get, serviceUrl + "/Customers");
//Create a message to add a customer
HttpRequestMessage addCustomerRequest = new HttpRequestMessage(HttpMethod.Post, serviceUrl + "/Customers");
addCustomerRequest.Content = new ObjectContent<Customer>(addedCustomer, formatter);
//Create a message to update a customer
HttpRequestMessage updateCustomerRequest = new HttpRequestMessage(HttpMethod.Put, string.Format(serviceUrl + "/Customers/{0}", updatedCustomer.Id));
updateCustomerRequest.Content = new ObjectContent<Customer>(updatedCustomer, formatter);
//Create a message to remove a customer.
HttpRequestMessage removeCustomerRequest = new HttpRequestMessage(HttpMethod.Delete, string.Format(serviceUrl + "/Customers/{0}", removedCustomer.Id));

//Create the different parts of the multipart content
HttpMessageContent queryContent = new HttpMessageContent(queryCustomersRequest);
HttpMessageContent addCustomerContent = new HttpMessageContent(addCustomerRequest);
HttpMessageContent updateCustomerContent = new HttpMessageContent(updateCustomerRequest);
HttpMessageContent removeCustomerContent = new HttpMessageContent(removeCustomerRequest);

//Create the multipart/mixed message content
MultipartContent content = new MultipartContent("mixed", "batch_" + Guid.NewGuid().ToString());
content.Add(queryContent);
content.Add(addCustomerContent);
content.Add(updateCustomerContent);
content.Add(removeCustomerContent);

//Create the request to the batch service
HttpRequestMessage batchRequest = new HttpRequestMessage(HttpMethod.Post, serviceUrl + "/batch");
//Associate the content with the message
batchRequest.Content = content;

//Send the message
HttpResponseMessage batchResponse = await client.SendAsync(batchRequest);

这是我在 Python 中的尝试,但它不起作用:

def build_request( url, type, headers, data = {}):

    #Build appropriate request
    if type == "get":
        request = Request('GET', url, headers=headers)

    elif type == "post":
        request = Request('POST', url, data = json.dumps(data), headers = {'Content-Type':'application/json'})

    elif type == "delete":
        request = Request('DELETE', url, headers = {'Content-Type':'application/json'})

    elif type == "put":
        request = Request('PUT', url, data = json.dumps(data), headers = {'Content-Type':'application/json'})

    elif type == "patch":
        request = Request('PATCH', url, data = json.dumps(data), headers = {'Content-Type':'application/json'})

    prepared_request = request.prepare()
    return prepared_request



#Get customers
get_customers = build_request( url + "/Customers", "get", headers)

#Add a customer
add_customer = build_request( url + "/Customers", "post", data=added_customer, headers=headers)

#update a customer
update_customer = build_request( url + "/Customers/{0}".format(updated_customer["Id"]), "put", data=updated_customer, headers=headers)

#Remove a customer
remove_customer = build_request( url + "/Customers/{0}".format(removed_customer["Id"]), "delete", headers=headers)

request_list = [get_customers,add_customer,update_customer, remove_customer]

batch_request = requests.Request('POST',url + "/batch", data=request_list)

s = Session()

batch_request.prepare()

resp = s.send(batch_request)

请求应该是这样的:

POST http://localhost:12345/api/batch HTTP/1.1
Content-Type: multipart/mixed; boundary="batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e"
Host: localhost:12345
Content-Length: 857
Expect: 100-continue

--batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e
Content-Type: application/http; msgtype=request

GET /api/WebCustomers HTTP/1.1
Host: localhost:13245


--batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e
Content-Type: application/http; msgtype=request

POST /api/WebCustomers HTTP/1.1
Host: localhost:13245
Content-Type: application/json; charset=utf-8

{"Id":129,"Name":"Name4752cbf0-e365-43c3-aa8d-1bbc8429dbf8"}
--batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e
Content-Type: application/http; msgtype=request

PUT /api/WebCustomers/1 HTTP/1.1
Host: localhost:13245
Content-Type: application/json; charset=utf-8

{"Id":1,"Name":"Peter"}
--batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e
Content-Type: application/http; msgtype=request

DELETE /api/WebCustomers/2 HTTP/1.1
Host: localhost:13245


--batch_357647d1-a6b5-4e6a-aa73-edfc88d8866e--

最佳答案

我已经设法使用以下代码将 C# 示例的第一部分翻译成 Python:

class BatchRequest:
    'Class for sending several HTTP requests in a single request'

    def __init__(self, url, uuid):
        self.batch_url = batch_url
        self.uuid = uuid
        self.data = ""
        self.headers = {"Content-Type" : "multipart/mixed; boundary=\"batch_{0}\"".format(uuid)}

    #Build sub-request depending on Method and Data supplied 
    def add_request(self, method, url, data={}):

        if method == "GET":
            self.data += "--batch_{0}\r\nContent-Type: application/http; msgtype=request\r\n\r\n{1} {2} HTTP/1.1\r\nHost: localhost:65200\r\n\r\n\r\n".format(uuid, method, url)

        #If no data, have alternative option
        elif method == "POST" or method == "PUT":
            self.data += "--batch_{0}\r\nContent-Type: application/http; msgtype=request\r\n\r\n{1} {2} HTTP/1.1\r\nHost: localhost:65200\r\nContent-Type: application/json; charset=utf-8\r\n\r\n{3}\r\n".format(uuid, method, url, json.dumps(data))

        elif method == "DELETE":
            self.data += "--batch_{0}\r\nContent-Type: application/http; msgtype=request\r\n\r\n{1} {2} HTTP/1.1\r\nHost: localhost:65200\r\n\r\n\r\n".format(uuid, method, url)

    def execute_request(self):
        #Add the "closing" boundary  
        self.data += "--batch_{0}--\r\n".format(uuid)

        result = requests.post(self.batch_url, data=self.data, headers=self.headers)
        return result

if __name__ == '__main__':

    url = "http://localhost:65200/api"

    batch_url = "{0}/batch".format(url)

    uuid = uuid.uuid4()

    br = BatchRequest("http://localhost:65200/api", uuid)

    #Get customers
    br.add_request("GET", "/api/Customers")

    #Create a new customer
    new_customer = {"Id" : 10, "Name" : "Name 10"};
    br.add_request("POST", "/api/Customers", new_customer)

    #Update the name of the first customer in the list 
    update_customer = customer_list[0]
    update_customer["Name"] = "Peter"
    br.add_request("PUT", "/api/Customers/{0}".format(update_customer["Id"]), update_customer)

    #Remove the second customer in the list
    br.add_request("DELETE", "/api/Customers/{0}".format(customer_list[1]["Id"]))

    result = br.execute_request()

剩下的就是弄清楚如何解析来自服务器的响应。

关于python - 创建包含多个 HTTP 请求的 mime/multipart 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23289602/

相关文章:

javascript - 原子编辑器 : node-gyp rebuild crashes

python - 如何在python中配置gRPC HTTP/2流量控制

c# - 无法加载文件或程序集 'Microsoft.Web.Iis.Rewrite.Providers, Version=7.1.761.0, Culture=neutral, PublicKeyToken=0545b0627da60a5f'

c# - 调试异步等待 Controller 操作

c# - 生成具有角色的身份用户(从 Web API 到 MVC 应用程序)

python - 解包一个类

python - 如何使用youtube-dl以相反的顺序获取播放列表索引?

c# - 如何将包含不同数据类型列表的列表作为子列表?

c# - 返回一个用ajax写入的HtmlTable

javascript - 如何从AJAX上传文件到asp.net core Controller