laika222
10/16/2019 - 7:01 PM

API Requests Using Requests Module

###################################
### REQUESTS MODULE ###
###################################

import requests, getpass

# collect authentication values
my_username = input('Enter Authentication Username:')
my_password = getpass.getpass(prompt='Enter Authentication Password:') 

# create variables for request pieces
url = 'https://httpbin.org/post'
headers = {'user-agent': 'my-app/0.0.1'}
parameters = {'parameter_key1': 'value1', 'parameter_key2': 'value2', 'parameter_key3': 'value3'}
data = {'form_data_key1': 'value1', 'form_data_key2': 'value2'} # form data for request body

# make the request
my_response = requests.post(
                            url = url, 
                            headers = headers,
                            params = parameters,
                            data = my_data,
                            # json = my_data # you can optionally send data a json
                            timeout = 10, 
                            auth = (my_username, my_password)
                            )

# view the results as a whole, or access certain JSON elements
my_response.json()

''' Results:

{'args': {'parameter_key1': 'value1', 'parameter_key2': 'value2', 'parameter_key3': 'value3'}, 'data': '', 'files': {}, 'form': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Authorization': 'Basic enp6ejp6enp6eg==', 'Content-Length': '23', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'my-app/0.0.1'}, 'json': None, 'origin': '38.130.85.3, 38.130.85.3', 'url': 'https://httpbin.org/post?parameter_key1=value1&parameter_key2=value2&parameter_key3=value3'}
'''

my_response.json()['headers']['Host'] # result is 'httpbin.org'


###################################
### MAKING A REQUEST ###
###################################

# the standard verbs are available
import requests

# GET
my_response = requests.get('https://httpbin.org/get')

# PUT
my_response = requests.put('https://httpbin.org/put', data = {'key': 'value'})

# DELETE
my_response = requests.delete('https://httpbin.org/delete')

# HEAD
my_response = requests.head('https://httpbin.org/get')

# OPTIONS
my_response = requests.options('https://httpbin.org/get')


###################################
### ACCESSING RESPONSE CONTENT ###
###################################

import requests

my_response = requests.get('https://httpbin.org/get')

# view the headers returned in the response from the server
my_response.headers

''' Results:
{'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Wed, 16 Oct 2019 18:21:37 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '181', 'Connection': 'keep-alive'}
'''

# view the headers that you sent with the request by accessing the request
my_response.request.headers

''' Results:
{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
'''

# view the encoded result returned from the server that request that you sent to the server
my_response.text

''' Results:
'{\n  "args": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.22.0"\n  }, \n  "origin": "38.130.85.3, 38.130.85.3", \n  "url": "https://httpbin.org/get"\n}\n'
'''

# view the response as bytes, for non-text requests
my_response.content

''' Results:
b'{\n  "args": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.22.0"\n  }, \n  "origin": "38.130.85.3, 38.130.85.3", \n  "url": "https://httpbin.org/get"\n}\n'
'''

# view results as JSON
print(my_response.json())

''' Results:
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}, 'origin': '38.130.85.3, 38.130.85.3', 'url': 'https://httpbin.org/get'}
'''

# access certain key values within the JSON returned in the request
my_response.json()['headers'] # access the 'headers' key level, result is {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}
my_response.json()['headers']['Host'] # access the 'headers' > 'Host' key level, result is 'httpbin.org'
print(my_response_json.keys()) # print all of the keys contained within the JSON response

''' Results:
dict_keys(['args', 'headers', 'origin', 'url'])
'''

print(my_response_json.values()) # print all of the key values contained within the JSON response

''' Results:
dict_values([{}, {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}, '38.130.85.3, 38.130.85.3', 'https://httpbin.org/get'])
'''


# view raw socket response from the server - note that you have to set stream = True when making the request
my_response = requests.get('https://httpbin.org/get', stream = True)
my_response.raw
my_response.raw.read(10) # result is b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

''' Results:
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0'}, 'origin': '38.130.85.3, 38.130.85.3', 'url': 'https://httpbin.org/get'}
'''

# view the server's response headers as a Python dictionary
my_response.headers

''' Results:
{'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Tue, 15 Oct 2019 02:38:54 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '280', 'Connection': 'keep-alive'}
'''

# view the URL you sent in the request
my_response.url # result is 'https://httpbin.org/get'



###################################
### PARAMETERS ###
###################################

# parameters are used to pass data in the URL's query string. These are passed in a dictionary of key-value pairs, and use the params keyword as an argument.
# Any dictionary key with a value of None will not be added to the query string.
import requests

my_parameters = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

my_response = requests.get('https://httpbin.org/get', params = my_parameters)

# you can then use the url method to see that it has taken the my_paremeters dicitonary and added it to as a URL encoded query string
print(my_response.url) # result is https://httpbin.org/get?key1=value1&key2=value2&key3=value3

# you can also pass in mutliple values for a key
my_parameters = {'key1': 'value1', 'key2': ['value2A, value2B']}

my_response = requests.get('https://httpbin.org/get', params = my_parameters)

print(my_response.url) # result is https://httpbin.org/get?key1=value1&key2=value2A%2C+value2B


###################################
### HEADERS ###
###################################

# you can pass custom headers as a dictionary. Header values must be string, bytestring, or unicode.
import requests

my_headers = {'user-agent': 'my-app/0.0.1'}

my_response = requests.get('https://httpbin.org/get', headers = my_headers)


###################################
### FORM ENCODED DATA ###
###################################

# the data argument is where you can pass form-encoded data for the body of a request
import requests

my_data = {'key1': 'value1', 'key2': 'value2'}

my_response = requests.post('https://httpbin.org/post', data = my_data)

# afterwards, you can view what you sent under the "form" section
my_response.text

''' Results:

'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.22.0"\n  }, \n  "json": null, \n  "origin": "38.130.85.3, 38.130.85.3", \n  "url": "https://httpbin.org/post"\n}\n'

'''

# the data argument can have mutiple values for each key. This is done by either making data a list of tuples or a dictionary with lists as values

# multiple values tuples example - note there is a comma in-between the key-value pair and not a colon
my_data_tuples = [('key1', 'value1'), ('key2', 'value2')]
my_response = requests.post('https://httpbin.org/post', data = my_data)

my_response.text

''' Results:

'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.22.0"\n  }, \n  "json": null, \n  "origin": "38.130.85.3, 38.130.85.3", \n  "url": "https://httpbin.org/post"\n}\n'
'''

# multiple values lists example - note there is a comma in-between the key-value pair and not a colon
my_data_dictionary = {'key1': ['value1', 'value2']}
my_response = requests.post('https://httpbin.org/post', data = my_data_dictionary)

my_response.text

''' Results:

'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": [\n      "value1", \n      "value2"\n    ]\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.22.0"\n  }, \n  "json": null, \n  "origin": "38.130.85.3, 38.130.85.3", \n  "url": "https://httpbin.org/post"\n}\n'
'''

# you can also encode the data as JSON directly using the json parameter
my_data_json = my_response = requests.post('https://httpbin.org/post', json = my_data_json)


###################################
### TIMEOUTS ###
###################################

# you can have the request timeout fater a certain amount of time. This is usually needed in production code since you don't want a request to be sitting there indefinitely.
# timeout measures the time waiting for a response from the server in seconds and not the time for the entire response to download. If no timeout is specified explicitly,
# the request will never timeout.
import requests

my_data = {'key1': 'value1', 'key2': 'value2'}

my_response = requests.get('https://httpbin.org/get', data = my_data, timeout = 0.5)


###################################
### AUTHENTICATION ###
###################################

# BASIC AUTHENTICATION
from requests.auth import HTTPBasicAuth

my_response = requests.get('https://httpbin.org/get', auth = HTTPBasicAuth('myusername', 'mypassword'))

# if you don't specify HTTPBasicAuth in the auth argument, it'll default to HTTPBasicAuth, so this request is the same as the one above
my_response = requests.get('https://httpbin.org/get', auth = ('myusername', 'mypassword'))

# DIGEST AUTHENTICATION
from requests.auth import HTTPDigestAuth

my_response = requests.get('https://httpbin.org/get', auth = HTTPDigestAuth('myusername', 'mypassword'))

# OAUTH1 AUTHENTICATION
# for OAuth1 requests, you have to pass in the following arguments:
    # your app key
    # your app secret key
    # your user token
    # your user secret token
import requests
from requests_oauthlib import OAuth1

my_authentication = ('my_app_key', 'my_app_secret_key', 'my_user_OAuth_token', 'my_user_OAuth_secret_token')

my_response = requests.get('https://httpbin.org/get', auth = my_authentication)