
Python for Humans - ColinWright
https://speakerdeck.com/kennethreitz/python-for-humans
======
ak217
Wow, this is cool. Kenneth has started to identify and call out other
libraries that are "barriers to entry" in Python. If this is a call to arms to
scale the Requests experience, it could grow into something really powerful -
a movement to systematically reinvent and rejuvenate the Python standard
library.

~~~
andybak
Yep. I was looking for exactly this list.

Incidentally Python could use an more equivalent to djangopackages.com to help
in identifying popular alternatives to standard lib packages.

~~~
pyre
While not a table of "stdlib package => 3rd party package", there is this:
<http://docs.python-guide.org/en/latest>

[ Also by Kenneth Reitz ]

~~~
wylie
That link doesn't appear to work for me, so I think the same content is
available at <http://docs.python-guide.org/>

~~~
pyre
Sorry. Looks like the trailing slash was omitted when I copy-pasted that from
the location bar. ^^;;

~~~
pbreit
That does seem to be the problem. But that seems wrong?

------
peter_l_downs
Slightly off topic: in an effort to become a better programmer, and to improve
the Python ecosystem, I've tried to write a "for Humans" style logging
library. Would anyone mind giving me feedback?

<http://peterdowns.com/lggr/>

~~~
jwpeddle
Some feedback from reading this page:

    
    
      - Why is your example logger named d? It might seem nitpicky but it's hard
        to read an example with a meaningless single character variable.
      - "d.close() # stop logging" - what is this? What does it mean to "stop
        logging" and why do I want to?
      - "Add a coroutine" - I would wager the lay Python developer doesn't even
        know what this word means.
      - lggr.Lggr() - Why not just name the class Logger?
      - The default format variables are inconsistent about when words are
        separated with an underscore.
      - I can't make sense of the example logging calls. In one you pass a 
        dictionary as the second argument, in another you pass three strings as
        separate arguments. Why would anyone pass a message like this instead of
        just using standard string formatting? Especially when there's other
        legit arguments like extra. It's not even really clear why you'd want to
        pass something in extra instead of in the message.
    

I fully support your goal, but at a glance this seems like a confusing
alternative to logging.

EDIT: hot dang it's hard to format a bulleted list on HN

~~~
peter_l_downs
Hi jwpeddle, thanks for all of the feedback! All of the changes I've made are
on a branch called 'hn-fix' (<https://github.com/peterldowns/lggr/tree/hn-
fix>) if you'd like to take a look.

    
    
        > Why is your example logger named d? It might seem nitpicky but
        > it's hard to read an example with a meaningless single character variable.
    

No particular reason -- you're right, I will change this now.

    
    
        > "d.close() # stop logging" - what is this? What does it mean to "stop logging"
        > and why do I want to?
    

This is a way to "close" the logger and clean up all of its associated
coroutines. An example of when you might want to is upon catching a fatal
error to your program, you might want to log the error and then safely clean
up all open files or network sockets to which the logger is writing.

The method name is clearly confusing -- what do you think of using "shutdown"
instead?

    
    
        > "Add a coroutine" - I would wager the lay Python developer doesn't
        > even know what this word means.
    

Maybe not, but they should! The readme now includes a link to dabeaz's
coroutines page, and I'll add a quick overview in a couple of minutes.

    
    
        > lggr.Lggr() - Why not just name the class Logger?
    

For consistency's sake. Maybe if I had to start again I would call the project
`logger`, but I decided to be "hip" and use a vowel-less name instead :)

    
    
        > The default format variables are inconsistent about when words are separated
        > with an underscore.
    

The initial idea was to mimic the variable names from the default logging
module ([http://docs.python.org/2/library/logging.html#logrecord-
attr...](http://docs.python.org/2/library/logging.html#logrecord-attributes)).
You're right that it is confusing though! I think I will rename everything to
be lower case, one word, instead of the default module's mix of camelCase and
underscore_separated names. Thoughts?

    
    
        > I can't make sense of the example logging calls. In one you pass a
        > dictionary as the second argument, in another you pass three strings
        > as separate arguments. Why would anyone pass a message like this
        > instead of just using standard string formatting? Especially when
        > there's other legit arguments like extra. It's not even really clear
        > why you'd want to pass something in extra instead of in the message.
    

I should definitely clarify what formats are allowed and aren't. The log
message format _is_ using standard string formatting -- string.format(), to be
exact. The 'extra' argument is a result of trying to imitate the default
library (see
[http://docs.python.org/2/library/logging.html#logging.Logger...](http://docs.python.org/2/library/logging.html#logging.Logger.debug)
for a description of the 'extra' kwarg), and can be useful when you'd like to
pass information to every single log message.

~~~
aiiane
Why not just add an atexit trap that automatically cleans up open logs?

<http://docs.python.org/2/library/atexit.html>

~~~
LeafStorm
I am fairly sure that most of the streams and sockets would get closed when
the interpreter exited regardless.

Also, in accordance to the principle of "explicit is better than implicit,"
it's generally better to avoid messing with global state (such as atexit)
behind the scenes, and to provide a way to shut down the logs manually.

------
slurgfest
This keeps getting reposted, <http://news.ycombinator.com/item?id=3419671>
<http://news.ycombinator.com/item?id=4117035>
<http://news.ycombinator.com/item?id=4651882>

~~~
jwpeddle
It was reposted today because he gave the talk again this morning at Pycon
Canada, I suspect.

------
dagw
Reminds me of a chat session I had with a dev at another office a few days
ago:

    
    
      him: "have you ever used urllib2"
      me: "not if I can avoid it"
      him: "I've just spent 3 days trying to do X"
      me: "have you heard of Requests"
      him: "nope"
      ...send URL...
      him: "god damn it!  Why didn't I talk to you three days ago"

20 minutes later he's replaced three days work with a dozen lines of easy to
read Requests code.

------
3pt14159
Was there today at PyCon Canada and not only was the presentation Kenneth gave
very good, but he was very awesome to talk to afterwards. I randomly came
across his 500px account, so we sent him a shirt, and he wore it on Friday
just to say thanks :3 (I actually didn't get to see him on the Friday night
party, probably because I know him best by his pixelated twitter pic, but it
is super cool that he take the time to think of stuff like that).

------
falcolas
While I appreciate the effort to make some more simplistic APIs available
alongside their more complex counterparts - libraries like urllib2 are _not_
expendable in the process.

In the act of making an API simpler and abstracting the details - you loose a
lot of the detailed control provided by these lower level libraries. Perhaps
you won't miss the 10% as outlined in the slides, but someone out there will.

Do we really need both? I think no, but then again for most of what I do,
urllib2 just works; I'm not really the target for requests. Just don't expect
that requests will ever replace urllib2.

~~~
scottbruin
If requests hits the 90% and urllib2 the 10%, then requests should be the
standard library and urllib2 a module. I think his point is more to point out
good modules that most people should use, and should become common knowledge
of what people should turn to when trying to do something. Java, for example,
has several date and time options but Jodatime actually does what most people
want to do with dates and times.

------
revolutions
A bit off-topic, but I couldn't find this and was very curious: What font are
the slides using in the code snippets? It looks very clean--I didn't realize
it was monospace at first.

~~~
porker
And also, what's the main font used for all the text? It's a lovely serif

~~~
revolutions
Looks like this one: <http://www.azfonts.net/load_font/high_tower_text.html>

~~~
porker
Spot on. Thanks!
<http://www.myfonts.com/fonts/fontbureau/hightower/textroman/>

------
wrath
I was at his talk this morning at pycon canada. It was a very good talk, the
highlight of the conference. I like his approach, although I think it'll be a
challenge to get there since not everyone has his "visionary" and api building
skills, but someone has to start somewhere. Well done.

~~~
jwpeddle
Also there- loved it. I think the key is what he said about writing the readme
first. Write the docs on how you'd want to use the software, then hold
yourself to that API when you actually write it.

------
rmccue
As much as I know everyone dislikes PHP, there's lots of people still working
with it. I love Requests in Python, so I built Requests for PHP:
<http://requests.ryanmccue.info/>

I have to agree with Kenneth's points, in that pragmatism should outweigh the
theoretical points. For example, in PHP, using a class as a grouping for
static methods is a bad idea. I agree to a point, but there's something to be
said for the ability to do `Requests::get('<http://google.com/)`> versus all
the crap you have to do with cURL. (Plus, it's always >90% test coverage,
which I stick to religiously.)

~~~
dave1010uk
If autoloading namespaces or namespaced functions was possible then static
classes wouldn't be needed and things like this would be commonplace:

    
    
        \Requests\get('http://google.com');

~~~
antihero
Another reminder of why in the fuck did they use the backslash character.

------
inovica
Here's a video:

<http://www.youtube.com/watch?v=Y97D8j6CAog>

------
codexon
His requests module is an improvement, but he says being able to specify the
outbound IP of an HTTP request is out of the scope of his module???

<https://github.com/kennethreitz/requests/issues/394>

That's why I am still using urllib2.

~~~
jwpeddle
I'm not sure why you feel this niche requirement requires three question
marks. The point of modules like this is to make it easier to do the tasks
that 95% of developers are likely to need to do regularly, at the cost of not
covering all rare use cases.

~~~
akkartik
It's a reasonable tradeoff for a specific library. But if he's trying to claim
that the entire eco-system should put the API above all, then it's worth
asking how the 5% use case integrates with this worldview. If I suddenly find
I need multiple IPs, do I now need to switch my http client library?

~~~
Nagyman
The slides don't mention this, but he did touch on having layered designs so
the 5% remains possible. However, the primarily exposed api shouldn't get
sacrificed for said features. By conceding on a feature that makes the API
less usable, you sacrifice more than not having it in the first place
(confusion, complexity). Even the GH Issue linked shows a possible solution to
the issue using urllib2, which is just a layer down.

~~~
codexon
I don't understand, what is not usable about being about do to this:

requests.get('news.ycombinator.com', sourceip='1.2.3.4')

------
js2
urllib2 is so bad (and I know how to use it) that I have at times used
subprocess + curl, which says a lot, because subprocess ain't exactly pretty
either. But the thing is, urllib2 is included and is the devil I know.

~~~
batgaijin
I remember writing raw socket stuff and I actually thought that was better
than urllib2.

------
andybak
I was googling to see the status of the 'requests should be in stdlib' debate
and discovered PEP411: <http://www.python.org/dev/peps/pep-0411/>

Basically this helps mitigate the downside of a module getting included in
stdlib.

------
jaimebuelta
There is a video of him giving this presentation on the PyCon Ireland, in case
someone want to hear it.

[http://www.youtube.com/watch?v=IN5AlsEHdIM&feature=plcp](http://www.youtube.com/watch?v=IN5AlsEHdIM&feature=plcp)

------
pav3l
>lxml is awesome, but difficult to install

So true... I often need to write something that will run on a Windows machine
and I just end up having to use the old version of Beautiful Soup (before it
became dependent on lxml). Pretty frustrating.

~~~
tnuc
lxml is great. The docs and the installation aren't the best.

For a windows install. <http://www.lfd.uci.edu/~gohlke/pythonlibs/>

~~~
pav3l
Thanks so much! Just tried it and the setup binaries worked like a charm! 20
seconds for the whole experience including downloading and testing. Very
different from how I remember my experience with lxml on Windows when I tried
it before! They should definitely have a link to this website from
<http://lxml.de/installation.html#ms-windows>

------
maaku
Absolutely love `requests`. First I've heard of `envoy`; will certainly be
using that in the future. Thank you.

------
waterside81
requests & envoy have saved me a huge amount of hours. I wish I met Kenneth
when he was in Toronto this weekend, I would have bought him anything he
wanted.

~~~
kenneth_reitz
I'm still in Toronto :)

~~~
ersii
Going straight to the Python Stockholm Meetup after yer flight? :-O Mmmmh,
jetlag

------
jklio
I can't express how depressing dealing with text encoding issues in any
language is.

------
dmritard96
spot on - if only I knew many others felt this way when building projects. lol

Maybe libraries should have a rating or something just for fun. Might help
direct attention at problems like this.

