Slide 1

Slide 1 text

Simplicity Is A Feature

Slide 2

Slide 2 text

Hi!

Slide 3

Slide 3 text

Me @lukasaoz @lukasa

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Warning Opinions!

Slide 6

Slide 6 text

What Is Simplicity?

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

import requests r = requests.get( ‘https://api.github.com', auth=('user', ‘pass') )

Slide 12

Slide 12 text

import urllib2 gh_url = 'https://api.github.com' req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, 'user', 'pass') auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) urllib2.install_opener(opener) handler = urllib2.urlopen(req)

Slide 13

Slide 13 text

– Justice Potter Stewart “I know it when I see it.”

Slide 14

Slide 14 text

Simplicity ⫫ Features

Slide 15

Slide 15 text

Simplicity is about defaults

Slide 16

Slide 16 text

Why Be Simple?

Slide 17

Slide 17 text

– Edsger Dijkstra “Simplicity is a prerequisite for reliability.”

Slide 18

Slide 18 text

– Robert Browning “Less is more.”

Slide 19

Slide 19 text

– Henry David Thoreau “Our life is frittered away by detail. Simplify.”

Slide 20

Slide 20 text

How To Be Simple

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

How To Onion

Slide 23

Slide 23 text

Build In Layers

Slide 24

Slide 24 text

Layer 1: Low-level

Slide 25

Slide 25 text

import email.generator import http.client import io import os import shutil def _encode_multipart_formdata(fields, files): boundary = email.generator._make_boundary() buf = io.BytesIO() textwriter = io.TextIOWrapper( buf, 'utf8', newline='', write_through=True) for (key, value) in fields.items(): textwriter.write( '--{boundary}\r\n' 'Content-Disposition: form-data; name="{key}"\r\n\r\n' '{value}\r\n'.format( boundary=boundary, key=key, value=value)) for (key, filepath, filename) in files: if os.path.isfile(filepath): textwriter.write( '--{boundary}\r\n' 'Content-Disposition: form-data; name="{key}"; ' 'filename="{filename}"\r\n' 'Content-Type: {content_type}\r\n\r\n'.format( boundary=boundary, key=key, filename=filename, content_type='application/octet-stream')) with open(filepath, "rb") as f: shutil.copyfileobj(f, buf) textwriter.write('\r\n') textwriter.write('--{}--\r\n\r\n'.format(boundary)) content_type = 'multipart/form-data; boundary={}'.format(boundary) return content_type, buf.getvalue() content_type, data = _encode_multipart_formdata( fields={'key': 'value'}, files=[('filekey', 'test.py', 'test.py')] ) headers = { 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'User-Agent': 'python-requests/2.7.0 CPython/2.7.10 Darwin 14.5.0', 'Content-Type': content_type, 'Content-Length': '{}'.format(len(data)), } c = http.client.HTTPSConnection('http2bin.org', 443) c.request('POST', '/post', body=data, headers=headers) resp = c.getresponse() print(resp.read())

Slide 26

Slide 26 text

Layer 1: Low-level Layer 2: Features

Slide 27

Slide 27 text

import urllib3 from urllib3.filepost import RequestField fields = [ RequestField( 'key', 'value', ), RequestField( 'filekey', open('test.py').read(), filename='test.py', ), ] fields[0].make_multipart() fields[1].make_multipart(content_type='application/octet-stream') headers = {'User-Agent': 'python-requests/2.7.0 CPython 2.7.10 Darwin/14.5.0'} http = urllib3.PoolManager() r = http.request('POST', 'http://http2bin.org/post', fields=fields) print(r.data)

Slide 28

Slide 28 text

Layer 1: Low-level Layer 2: Features Layer 3: Simplicity

Slide 29

Slide 29 text

import requests r = requests.post( 'https://http2bin.org/post', files={ 'key': 'value', 'filekey': ( 'test.py', open('test.py'), 'application/octet-stream' ) } ) print(r.text)

Slide 30

Slide 30 text

While We’re Here…

Slide 31

Slide 31 text

80%

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

Thanks! ✨✨