56

What is the cleanest way to do HTTP POST with Basic Auth in Python?

Using only the Python core libs.

esamatti
  • 18,293
  • 11
  • 75
  • 82

3 Answers3

145

Seriously, just use requests:

import requests
resp = requests.post(url, data={}, auth=('user', 'pass'))

It's a pure python library, installing is as easy as easy_install requests or pip install requests. It has an extremely simple and easy to use API, and it fixes bugs in urllib2 so you don't have to. Don't make your life harder because of silly self-imposed requirements.

Zach Kelling
  • 52,505
  • 13
  • 109
  • 108
  • 5
    +1 for requests, but doesn't satisfy the OP's requirements (in stdlib) – Corey Goldberg Jun 06 '11 at 18:26
  • 1
    @Corey Indeed, and my purpose was to get him to change his requirements. Requests fixes several issues with the standard library, not to mention that it has a much simpler API. Using it will undoubtedly make his life easier, and save him trouble. – Zach Kelling Jun 06 '11 at 18:30
  • agreed. if the requirements are flexible, I'd also use requests – Corey Goldberg Jun 06 '11 at 18:31
  • 7
    Yeah, I aware of requests. It is cool, but I would not have asked here if could have used it easily enough. – esamatti Jun 07 '11 at 17:22
  • What prevents you from using requests? – Zach Kelling Jun 07 '11 at 17:31
  • 2
    @zeekay - IT security imposed software vetting requirements (yes, this is literally almost a decade later, but still applicable). Sometimes it's easier to roll your own than it is to convince 30 people to sign off on something, as horrible as that sounds. – iAdjunct Jun 17 '19 at 15:54
10

Hackish workaround works:

urllib.urlopen("https://username:password@hostname/path", data) 

A lot of people don't realize that the old syntax for specifying username and password in the URL works in urllib.urlopen. It doesn't appear the username or password require any encoding, except perhaps if the password includes an "@" symbol.

The Matt
  • 1,423
  • 1
  • 12
  • 22
user1740078
  • 476
  • 5
  • 3
6

if you define a url, username, password, and some post-data, this should work in Python2...

import urllib2

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, username, password)
auth_handler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
content = urllib2.urlopen(url, post_data)

example from official Python docs showing Basic Auth in urllib2: * http://docs.python.org/release/2.6/howto/urllib2.html

full tutorial on Basic Authentication using urllib2: * http://www.voidspace.org.uk/python/articles/authentication.shtml

Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143
  • 3
    Not a great article — it spends a lot of time explaining how to do it *wrong* before saying "but ignore that, here's how to do it right". :-/ – Ben Blank Jun 06 '11 at 18:26