├── Gemfile
├── Gemfile.lock
├── Makefile
├── README.md
├── config.ru
├── custom.css
├── python-for-humans
├── 0_intro.md
├── 1_content.md
├── 2_outro.md
└── ext
│ ├── dont-panic.jpeg
│ ├── heroku.png
│ └── moo.png
└── showoff.json
/Gemfile:
--------------------------------------------------------------------------------
1 | source :rubygems
2 | gem 'bluecloth'
3 | gem 'nokogiri'
4 | gem 'showoff'
5 | gem 'gli'
6 | gem 'heroku'
7 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | addressable (2.2.6)
5 | blankslate (2.1.2.4)
6 | bluecloth (2.1.0)
7 | gli (1.3.3)
8 | heroku (2.8.5)
9 | launchy (>= 0.3.2)
10 | rest-client (~> 1.6.1)
11 | rubyzip
12 | term-ansicolor (~> 1.0.5)
13 | json (1.6.1)
14 | launchy (2.0.5)
15 | addressable (~> 2.2.6)
16 | mime-types (1.16)
17 | nokogiri (1.5.0)
18 | parslet (1.2.3)
19 | blankslate (~> 2.0)
20 | rack (1.3.4)
21 | rack-protection (1.1.4)
22 | rack
23 | rest-client (1.6.7)
24 | mime-types (>= 1.16)
25 | rubyzip (0.9.4)
26 | showoff (0.7.0)
27 | bluecloth
28 | gli (>= 1.3.2)
29 | json
30 | nokogiri
31 | parslet
32 | sinatra
33 | sinatra (1.3.1)
34 | rack (~> 1.3, >= 1.3.4)
35 | rack-protection (~> 1.1, >= 1.1.2)
36 | tilt (~> 1.3, >= 1.3.3)
37 | term-ansicolor (1.0.6)
38 | tilt (1.3.3)
39 |
40 | PLATFORMS
41 | ruby
42 |
43 | DEPENDENCIES
44 | bluecloth
45 | gli
46 | heroku
47 | nokogiri
48 | showoff
49 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | run:
2 | showoff serve
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python for Humans
2 |
3 | ## tl;dr
4 |
5 | - Publish Modules for Humans
6 | - Help with Python-Guide
7 |
8 | ## Slides
9 |
10 | [Available Online](http://python-for-humans.heroku.com)
11 |
12 | ## Audio
13 |
14 | - [MP3](http://cl.ly/1h0y0k2F0D2K3F3V3J16/PyCodeConf2011_-_Kenneth_Reitz_01.mp3)
15 | - [OGG](http://codeconf.s3.amazonaws.com/2011/pycodeconf/talks/PyCodeConf2011%20-%20Kenneth%20Reitz.ogg)
16 | - [M4A](http://codeconf.s3.amazonaws.com/2011/pycodeconf/talks/PyCodeConf2011%20-%20Kenneth%20Reitz.m4a)
17 |
18 |
19 | ## Powered By
20 |
21 | - [schacon/showoff](https://github.com/schacon/showoff)
22 | - [Heroku](https://heroku.com)
23 | - [Octocats](http://octodex.github.com/)
24 | - [Redbull](http://www.redbull.com/)
25 |
26 | ## Special Thanks
27 |
28 | - GitHub
29 | - The dozens of developers that helped form the list of woes.
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | require "showoff"
2 | run ShowOff.new
3 |
--------------------------------------------------------------------------------
/custom.css:
--------------------------------------------------------------------------------
1 | .github {
2 | font-family: 'Collegiate', helvetica, sans-serif;
3 | }
4 |
5 | .bigger {
6 | font-size: 2.3em;
7 | }
8 |
9 | .red {
10 | color: red;
11 | }
12 |
13 | .top {
14 | margin-top: 50px !important;
15 | }
16 |
--------------------------------------------------------------------------------
/python-for-humans/0_intro.md:
--------------------------------------------------------------------------------
1 | !SLIDE bullets
2 |
3 | * API Design and Pragmatic Python
4 | * Python is a Ghetto
5 | * Python is a Cancer
6 | * Python Has Jumped the Shark
7 |
8 | !SLIDE
9 | # Hi.
10 |
11 |
12 | !SLIDE github bigger
13 | github.com/kennethreitz
14 |
15 | !SLIDE
16 |
17 | ## I ♥ PYTHON!
18 |
19 | !SLIDE
20 |
21 | 
22 |
23 | !SLIDE github
24 |
25 | ## The GitHub Reflog.
26 |
27 | !SLIDE
28 |
29 | ## I ♥ OPEN SOURCE!
30 |
31 | !SLIDE incremental bullets small
32 |
33 | * Requests: HTTP for Humans
34 | * Tablib: Pythonic Tabular Datasets
35 | * Legit: Awesome Git Interface
36 | * OSX-GCC-Installer: Angers Lawyers
37 | * Clint: Command-line Interface Tools
38 | * Envoy: Subprocess for Humans
39 | * Httpbin.org: Requests & Response Service
40 | * ~197 Others
41 |
--------------------------------------------------------------------------------
/python-for-humans/1_content.md:
--------------------------------------------------------------------------------
1 | !SLIDE
2 | # Python for Humans
3 | (or something to that effect)
4 |
5 |
6 | !SLIDE
7 | # Philosophy.
8 |
9 |
10 | !SLIDE
11 | # We share a dark past:
12 |
13 | Perl, Java, PHP, ColdFusion, Classic ASP, *&c*.
14 |
15 |
16 | !SLIDE code
17 | # The Zen of Python.
18 | >>> import this
19 |
20 |
21 | !SLIDE
22 | ## Beautiful is better than ugly.
23 |
24 |
25 | !SLIDE
26 | ## Explicit is better than implicit.
27 |
28 |
29 | !SLIDE
30 | ## Simple is better than complex.
31 |
32 |
33 | !SLIDE
34 | ## Complex is better than complicated.
35 |
36 |
37 | !SLIDE incremental bullets
38 | ### If the implementation is hard to explain, it's a bad idea.
39 |
40 | - (except pypy)
41 |
42 |
43 | !SLIDE
44 | ### There should be one—and preferably only one—obvious way to do it.
45 |
46 |
47 |
48 | !SLIDE
49 | # Welcome to paradise.
50 |
51 | !SLIDE
52 | # Welcome to paradise.
53 |
54 | !SLIDE red bigger
55 | # LIES!
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | !SLIDE
69 | # Let's mess around.
70 |
71 | ### Maybe play with the GitHub API?
72 |
73 |
74 | !SLIDE small code
75 |
76 | ## We know Ruby.
77 |
78 | @@@ ruby
79 | require 'net/http'
80 | require 'uri'
81 |
82 | uri = URI.parse('https://api.github.com/user')
83 |
84 | http = Net::HTTP.new(uri.host, uri.port)
85 | http.use_ssl = true
86 |
87 | req = Net::HTTP::Get.new(uri.request_uri)
88 | req.basic_auth('username', 'password')
89 |
90 | r = http.request(req)
91 |
92 | puts r
93 |
94 | !SLIDE
95 | # Python's net/http?
96 |
97 | ## http/url/lib/2
98 |
99 | (better in py3)
100 |
101 | !SLIDE
102 |
103 | # Several hours later...
104 |
105 | !SLIDE smaller code execute
106 |
107 | @@@ python
108 | import urllib2
109 |
110 | gh_url = 'https://api.github.com/user'
111 |
112 | req = urllib2.Request(gh_url)
113 |
114 | password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
115 | password_manager.add_password(None, gh_url, 'user', 'pass')
116 |
117 | auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
118 | opener = urllib2.build_opener(auth_manager)
119 |
120 | urllib2.install_opener(opener)
121 |
122 | handler = urllib2.urlopen(req)
123 |
124 | print handler.read()
125 |
126 | !SLIDE smaller code execute
127 | #I lied — there's more!
128 |
129 | @@@ python
130 |
131 | import re
132 |
133 | class HTTPForcedBasicAuthHandler(HTTPBasicAuthHandler):
134 |
135 | auth_header = 'Authorization'
136 | rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
137 | 'realm=(["\'])(.*?)\\2', re.I)
138 |
139 | def __init__(self, *args, **kwargs):
140 | HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
141 |
142 | def http_error_401(self, req, fp, code, msg, headers):
143 | url = req.get_full_url()
144 | response = self._http_error_auth_reqed(
145 | 'www-authenticate', url, req, headers)
146 | self.reset_retry_count()
147 | return response
148 |
149 | http_error_404 = http_error_401
150 |
151 | !SLIDE
152 | # Admit it.
153 |
154 | If this was you, you'd leave Python and never come back.
155 |
156 |
157 |
158 | !SLIDE bullets incremental
159 | # The Problem.
160 |
161 | - Unclear which module to use in the first place.
162 | - Prognosis seems to be urllib2, but the docs are terrible.
163 | - Worst API ever.
164 |
165 |
166 | !SLIDE bullets incremental smaller
167 | # This is a serious problem.
168 |
169 | - HTTP should be as simple as the print statement.
170 |
171 |
172 | !SLIDE bullets incremental
173 | # The Solution is Simple.
174 |
175 | - Build elegant tools to perform these tasks.
176 |
177 |
178 | !SLIDE
179 | ## Python needs more Pragmatic Packages.
180 |
181 | !SLIDE dark
182 |
183 | ## pra•gmat•ic |pragˈmatik|, *adj*:
184 | Dealing with things sensibly and realistically in a way that is
185 | based on practical rather than theoretical considerations.
186 |
187 | !SLIDE
188 | # Python for Humans
189 |
190 |
191 | !SLIDE incremental
192 | # Let's Break it down.
193 |
194 | What *is* HTTP at its core?
195 |
196 | - A small set of methods with consistent parameters.
197 | - HEAD, GET, PUSH, POST, PUT, PATCH, DELETE
198 | - They all accept headers, url parameters, and form data.
199 |
200 |
201 | !SLIDE incremental
202 | # Urllib2 is Toxic.
203 |
204 | - Heavily over-engineered.
205 | - Abolishes most of PEP20.
206 | - Docs are impossible to read.
207 | - HTTP is simple. Urllib2 is absolute garbage.
208 | - Scares people away.
209 |
210 |
211 | !SLIDE
212 | # Enter Requests.
213 |
214 |
215 | !SLIDE
216 | # HTTP for Humans.
217 |
218 |
219 | !SLIDE
220 |
221 | @@@ python
222 | import requests
223 |
224 | url = 'https://api.github.com/user'
225 | auth = ('username', 'password')
226 |
227 | r = requests.get(url, auth=auth)
228 | print r.content
229 |
230 |
231 | !SLIDE incremental
232 | # Achievement Unlocked!
233 |
234 | - A small set of methods with consistent parameters.
235 | - HEAD, GET, PUSH, POST, PUT, PATCH, DELETE
236 | - They all accept headers, url parameters, and form data.
237 |
238 | !SLIDE incremental
239 | # Do this.
240 |
241 |
242 | !SLIDE
243 | # The Litmus Test
244 | If you have to refer to the documentation every time you use a module,
245 | find (or build) a new module.
246 |
247 | !SLIDE
248 | # Fit the 90% Use Case.
249 |
250 | !SLIDE
251 | # The API is all that matters.
252 |
253 |
254 | ## Everything else is secondary.
255 |
256 |
257 | !SLIDE incremental bullets
258 | # I Mean ***Everything***.
259 |
260 | - Features.
261 | - Efficiency.
262 | - Performance.
263 | - Corner-cases.
264 |
265 |
266 | !SLIDE incremental bullets
267 | # Pivot.
268 |
269 | - At first, Requests was far from powerful.
270 | - Deeply resonated with people.
271 | - Features grew over time, API never compromised.
272 |
273 | !SLIDE incremental bullets
274 | # Today
275 | - Cookies, sessions, content-iteration, decompression, file uploads, async i/o, keep-alive, callback hooks, proxies, *&c*.
276 | - 7th most–watched Python GitHub project.
277 | - 65,000+ downloads from PyPi.
278 | - Twitter, Library of Congress, Readability, etc.
279 |
280 |
281 | !SLIDE incremental bullets
282 | # Cool Story, Bro.
283 |
284 | - We need this.
285 | - We want this.
286 | - It's worth your time.
287 | - It's worth everyone's time.
288 |
289 |
290 | !SLIDE bullets incremental
291 | # Subprocess
292 |
293 | - Powerful
294 | - Effective
295 | - (Second) Worst API ever.
296 | - Documentation is severely lacking.
297 |
298 |
299 | !SLIDE bullets
300 | # (Proposed) Solution.
301 |
302 | 
303 |
304 |
305 |
306 | !SLIDE
307 | # File and System Operations
308 | - sys | shutils | os | os.path | io
309 | - Really difficult to run external commands.
310 | - This blocks dev+ops folks from adopting Python.
311 |
312 |
313 |
314 |
315 | !SLIDE
316 | # Barriers to Entry
317 |
318 |
319 | !SLIDE incremental
320 | # Installing Python.
321 |
322 | Decisions, decisions.
323 |
324 | * Download installer from python.org?
325 | * 32bit or 64bit?
326 | * Build from source?
327 | * If so, Unix or framework build?
328 |
329 | !SLIDE
330 | ### There should be one—and preferably only one—obvious way to do it.
331 |
332 |
333 | !SLIDE
334 | # XML
335 |
336 | - `etree` is terrible.
337 | - `lxml` is awesome, but difficult to install.
338 |
339 |
340 | !SLIDE incremental
341 | # Packaging and Dependencies
342 | - Pip or easy_install?
343 | - Setuptools isn't included with python?
344 | - Distribute? Why?
345 | - No easy_uninstall?
346 | - Broken `setup.py`s
347 | - "Released" packages not in the Cheeseshop
348 |
349 | !SLIDE incremental
350 | # Date[time]s.
351 | - Which module to use?
352 | - Timezones
353 | - The stdlib can generate but not parse ISO8601 dates
354 |
355 | !SLIDE
356 | # Unicode.
357 |
358 | !SLIDE
359 | # Testing.
360 |
361 | !SLIDE incremental
362 | # Installing Dependencies
363 |
364 | * python-mysql
365 | * PIL
366 | * mod_wsgi
367 |
368 |
369 |
370 | !SLIDE
371 | ## Unless there's an explicit requirement,
372 | ## a student should never be exposed to urllib2.
373 |
374 | # No excuses.
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 | !SLIDE
385 | ## The Hitchhiker's Guide to Python
386 |
387 | http://python-guide.org
388 |
389 | !SLIDE code top
390 | 
391 |
392 |
393 | !SLIDE bullets incremental
394 | - A guidebook for newcomers.
395 | - A reference for seasoned veterans.
396 |
397 | !SLIDE small bullets incremental
398 | # Best Practices
399 |
400 | - Will recommend **distribute**, **pip**, and **virtualenv** out of the box.
401 | Explicit directions for setup on every major OS.
402 | - Instill a resistance to `doctest`
403 | - Teach `datetime.utcnow()`
404 |
405 |
406 | !SLIDE
407 | # There's only one rule.
408 |
409 | !SLIDE
410 | > There should be one—and preferably only one—obvious way to do it.
411 |
412 |
413 | !SLIDE
414 | # This Solves
415 |
416 | - Makes Python more accessible, lowering the barrier to entry.
417 | - Great reference guide for seasoned veterans.
418 | - Practice what we preach.
419 |
420 |
421 | !SLIDE red
422 | # THE MANIFESTO
423 |
424 |
425 | !SLIDE
426 | # Simplify terrible APIs.
427 |
428 | !SLIDE
429 | # Document our best-practices.
430 |
431 |
--------------------------------------------------------------------------------
/python-for-humans/2_outro.md:
--------------------------------------------------------------------------------
1 | !SLIDE
2 | ## Questions?
3 |
4 |
5 | !SLIDE github bigger
6 | [github.com/kennethreitz](http://github.com/kennethreitz)
7 |
--------------------------------------------------------------------------------
/python-for-humans/ext/dont-panic.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/not-kennethreitz/python-for-humans/a9dd19fa85396ebdb86aab3a553df8030270ec71/python-for-humans/ext/dont-panic.jpeg
--------------------------------------------------------------------------------
/python-for-humans/ext/heroku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/not-kennethreitz/python-for-humans/a9dd19fa85396ebdb86aab3a553df8030270ec71/python-for-humans/ext/heroku.png
--------------------------------------------------------------------------------
/python-for-humans/ext/moo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/not-kennethreitz/python-for-humans/a9dd19fa85396ebdb86aab3a553df8030270ec71/python-for-humans/ext/moo.png
--------------------------------------------------------------------------------
/showoff.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Python for Humans",
3 | "sections":
4 | [
5 | {"section": "python-for-humans"}
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------