将cURL POST转换为urllib2而不要求

将cURL POST转换为urllib2而不要求

问题描述:

我目前有一个cURL命令可以在我的环境中使用。我需要将其转换成一个Python 2.7的urllib等同,需要一些帮助将cURL POST转换为urllib2而不要求

cURL命令中的问题:

curl -k -v -XPOST -H "Authorization: Bearer $Token" -F [email protected]${local_filename} https://interesting_url.com/ 

我需要同时支持一个头(H)的能力和形式/文件( -F)并且还没有成功。

This post includes a discussion on headers,但我一直没能得到“-F”等价工作

+3

如果您可以使用请求,则可以使用https://curl.trillworks.com/翻译cURL命令 –

+0

如果我们停留在Python 2.7并且无法使用pip,该怎么办? – Numpty

+0

请求在2.7下正常工作,您应该可以通过[下载repo](https://github.com/requests/requests/releases)并运行'python setup.py install'来安装它。 –

随着python3你可以用requests做到这一点:

import requests 

headers = {'Authorization': 'Bearer $Token'} 

files = [('file', open('${local_filename}', 'rb'))] 

requests.post('https://interesting_url.com/', headers=headers, files=files, verify=False) 

与urllib2的文件上载是一个相当复杂的任务(example)。 所以我建议你requests

龙答案,而无需使用PIP和第三方软件包

您可以实现自定义类MultiPartForm,然后用它来编码文件:

import itertools 
import mimetools 
import mimetypes 
from cStringIO import StringIO 
import urllib 
import urllib2 

class MultiPartForm(object): 
    """Accumulate the data to be used when posting a form.""" 

    def __init__(self): 
     self.form_fields = [] 
     self.files = [] 
     self.boundary = mimetools.choose_boundary() 
     return 

    def get_content_type(self): 
     return 'multipart/form-data; boundary=%s' % self.boundary 

    def add_field(self, name, value): 
     """Add a simple field to the form data.""" 
     self.form_fields.append((name, value)) 
     return 

    def add_file(self, fieldname, filename, fileHandle, mimetype=None): 
     """Add a file to be uploaded.""" 
     body = fileHandle.read() 
     if mimetype is None: 
      mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' 
     self.files.append((fieldname, filename, mimetype, body)) 
     return 

    def __str__(self): 
     """Return a string representing the form data, including attached files.""" 
     # Build a list of lists, each containing "lines" of the 
     # request. Each part is separated by a boundary string. 
     # Once the list is built, return a string where each 
     # line is separated by '\r\n'. 
     parts = [] 
     part_boundary = '--' + self.boundary 

     # Add the form fields 
     parts.extend(
      [ part_boundary, 
       'Content-Disposition: form-data; name="%s"' % name, 
       '', 
       value, 
      ] 
      for name, value in self.form_fields 
      ) 

     # Add the files to upload 
     parts.extend(
      [ part_boundary, 
       'Content-Disposition: file; name="%s"; filename="%s"' % \ 
       (field_name, filename), 
       'Content-Type: %s' % content_type, 
       '', 
       body, 
      ] 
      for field_name, filename, content_type, body in self.files 
      ) 

     # Flatten the list and add closing boundary marker, 
     # then return CR+LF separated data 
     flattened = list(itertools.chain(*parts)) 
     flattened.append('--' + self.boundary + '--') 
     flattened.append('') 
     return '\r\n'.join(flattened) 

with open(`local_file.txt`) as f: 
    form = MultiPartForm() 
    form.add_file('file', `local_file`, 
        fileHandle=f) 

    # Build the request 
    request = urllib2.Request('https://interesting_url.com/') 
    request.add_header('Authorization', 'Bearer $Token') 
    body = str(form) 
    request.add_header('Content-type', form.get_content_type()) 
    request.add_header('Content-length', len(body)) 
    request.add_data(body) 

    print 
    print 'OUTGOING DATA:' 
    print request.get_data() 

    print 
    print 'SERVER RESPONSE:' 
    print urllib2.urlopen(request).read() 

The source

+0

如果我们停留在Python 2.7并且不能使用pip,该怎么办? – Numpty

+1

@Numpty,请参阅复杂版本的请求的更新答案,而无需安装额外的软件包 –

+0

谢谢 - 可能需要我花一天时间来适应此问题并进行测试。你没有在讨论复杂性:| – Numpty

尝试寻找到请求库。之后,您可以使用pip install requests进行安装,只需在线搜索一些示例代码即可。根据您的应用程序,它会有所不同。请求库允许你做很多事情。有很多文档。我强烈建议你检查一下。