问题
I am following this tutorial for batching http requests with ASP.NET 4.5. I have the sample working, and now I need to write a client application in Python.
This code creates, and sends a batch request to the 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);
This is my attempt in Python but it doesn't work:
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)
The request should look like this:
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--
回答1:
I've managed to translate the first part of the C# sample into Python using the following code:
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()
All that remains is to figure out how to parse the response(s) from the server.
来源:https://stackoverflow.com/questions/23289602/create-mime-multipart-request-containing-multiple-http-requests