Skip to content

Instantly share code, notes, and snippets.

@andreif
Created April 4, 2017 11:26
Show Gist options
  • Select an option

  • Save andreif/073a59818421f0678a7e5a5d657ef005 to your computer and use it in GitHub Desktop.

Select an option

Save andreif/073a59818421f0678a7e5a5d657ef005 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import mimetypes
import uuid
import io
import os
class FormData(object):
def __init__(self, data=None, files=None):
self.boundary = uuid.uuid4().hex
self._content = io.BytesIO()
for name, value in (data or {}).items():
self.write_part(value=value, name=name)
for name, path in (files or {}).items():
with open(path, 'rb') as fd:
ct = mimetypes.guess_type(path)[0] or 'application/octet-stream'
self.write_part(value=fd.read(), name=name,
filename=os.path.basename(path),
content_type=ct)
def write_part(self, value, content_type=None, **kwargs):
params = ''.join([f'; {k}="{v}"' for k, v in kwargs.items()])
ct = f'\r\nContent-Type: {content_type}' if content_type else ''
self._content.write(
f'--{self.boundary}\r\n'
f'Content-Disposition: form-data{params}{ct}\r\n\r\n'.encode())
if isinstance(value, str):
value = value.encode()
self._content.write(value + b'\r\n')
@property
def content_type(self):
return f'multipart/form-data; boundary={self.boundary}'
@property
def body(self):
return self._content.getvalue() + \
f'--{self.boundary}--\r\n'.encode()
data = FormData(data={'name': 'value'},
files={'file': __file__})
from urllib.request import Request, urlopen
with urlopen(Request(url='https://httpbin.org/post',
data=data.body,
headers={'Content-Type': data.content_type})) as response:
print(response.status)
print(response.headers)
print(response.read().decode())
import http.client
conn = http.client.HTTPSConnection(host='httpbin.org')
conn.request(method='POST', url='/post', body=data.body,
headers={'Content-Type': data.content_type})
response = conn.getresponse()
print(response.status)
print(response.headers)
print(response.read().decode())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment