81

I can't seem to Google it, but I want a function that does this:

Accept 3 arguments (or more, whatever):

  • URL
  • a dictionary of params
  • POST or GET

Return me the results, and the response code.

Is there a snippet that does this?

Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

5 Answers5

111

requests

https://github.com/kennethreitz/requests/

Here's a few common ways to use it:

import requests
url = 'https://...'
payload = {'key1': 'value1', 'key2': 'value2'}

# GET
r = requests.get(url)

# GET with params in URL
r = requests.get(url, params=payload)

# POST with form-encoded data
r = requests.post(url, data=payload)

# POST with JSON 
import json
r = requests.post(url, data=json.dumps(payload))

# Response, status etc
r.text
r.status_code

httplib2

https://github.com/jcgregorio/httplib2

>>> from httplib2 import Http
>>> from urllib import urlencode
>>> h = Http()
>>> data = dict(name="Joe", comment="A test comment")
>>> resp, content = h.request("http://bitworking.org/news/223/Meet-Ares", "POST", urlencode(data))
>>> resp
{'status': '200', 'transfer-encoding': 'chunked', 'vary': 'Accept-Encoding,User-Agent',
 'server': 'Apache', 'connection': 'close', 'date': 'Tue, 31 Jul 2007 15:29:52 GMT', 
 'content-type': 'text/html'}
bakkal
  • 54,350
  • 12
  • 131
  • 107
53

Even easier: via the requests module.

import requests
get_response = requests.get(url='http://google.com')
post_data = {'username':'joeb', 'password':'foobar'}
# POST some form-encoded data:
post_response = requests.post(url='http://httpbin.org/post', data=post_data)

To send data that is not form-encoded, send it serialised as a string (example taken from the documentation):

import json
post_response = requests.post(url='http://httpbin.org/post', data=json.dumps(post_data))
# If using requests v2.4.2 or later, pass the dict via the json parameter and it will be encoded directly:
post_response = requests.post(url='http://httpbin.org/post', json=post_data)
ropable
  • 1,547
  • 1
  • 19
  • 31
  • 3
    I had to wrap the post_data in json.dumps() before it worked for me: `data=json.dumps(post_data)` – Matt Mar 12 '14 at 18:36
  • 1
    @Matt, I think that this depends on whether you want to submit form-encoded data (just pass in a dict) or data that is not form-encoded (pass in a string of JSON data). I refer to the docs here: http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests – ropable Mar 19 '14 at 01:21
  • is there any version of this module for windows? – TheGoodUser Oct 09 '14 at 18:53
  • @TheGoodUser This library (and many more) are compiled for Windows and available here: http://www.lfd.uci.edu/~gohlke/pythonlibs/#requests – ropable Oct 09 '14 at 23:11
33

You could use this to wrap urllib2:

def URLRequest(url, params, method="GET"):
    if method == "POST":
        return urllib2.Request(url, data=urllib.urlencode(params))
    else:
        return urllib2.Request(url + "?" + urllib.urlencode(params))

That will return a Request object that has result data and response codes.

Ian Wetherbee
  • 6,009
  • 1
  • 29
  • 30
  • 11
    I prefer this one for sticking to the standard library. – Charles Duffy Dec 18 '10 at 03:11
  • should it be url + "?" instead of url + '&'? – Paulo Scardine Dec 18 '10 at 03:20
  • 1
    This is nice, but to be precise, the `Request` object itself has no result data or response codes - it needs to be "requested" via a method like [`urlopen`](https://docs.python.org/2/library/urllib2.html#urllib2.urlopen). – Bach Jul 18 '14 at 08:02
  • @Bach Do you have an example of the code that fulfills the "requested" piece like urlopen with the URLRequest method here? I can't find one anywhere. – theJerm Dec 21 '15 at 20:55
  • @theJerm, I've referenced it. Try `r = urllib2.urlopen(url)` and then `r.readlines()` and/or `r.getcode()`. You may also wish to consider using [Requests](http://requests.readthedocs.org) instead. – Bach Dec 22 '15 at 07:40
  • @Bach - Thanks, I downloaded the requests module and it was so much easier. Thanks. – theJerm Dec 23 '15 at 20:52
10
import urllib

def fetch_thing(url, params, method):
    params = urllib.urlencode(params)
    if method=='POST':
        f = urllib.urlopen(url, params)
    else:
        f = urllib.urlopen(url+'?'+params)
    return (f.read(), f.code)


content, response_code = fetch_thing(
                              'http://google.com/', 
                              {'spam': 1, 'eggs': 2, 'bacon': 0}, 
                              'GET'
                         )

[Update]

Some of these answers are old. Today I would use the requests module like the answer by robaple.

Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
9

I know you asked for GET and POST but I will provide CRUD since others may need this just in case: (this was tested in Python 3.7)

#!/usr/bin/env python3
import http.client
import json

print("\n GET example")
conn = http.client.HTTPSConnection("httpbin.org")
conn.request("GET", "/get")
response = conn.getresponse()
data = response.read().decode('utf-8')
print(response.status, response.reason)
print(data)


print("\n POST example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body = {'text': 'testing post'}
json_data = json.dumps(post_body)
conn.request('POST', '/post', json_data, headers)
response = conn.getresponse()
print(response.read().decode())
print(response.status, response.reason)


print("\n PUT example ")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing put'}
json_data = json.dumps(post_body)
conn.request('PUT', '/put', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)


print("\n delete example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing delete'}
json_data = json.dumps(post_body)
conn.request('DELETE', '/delete', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)
grepit
  • 21,260
  • 6
  • 105
  • 81