2.6 Header and Body Data
While a querystring key is a good starting point for authentication, there are more secure and efficient methods available. An open standard for delegation access to internet users. is one such method. Oauth is an open standard for delegating access to internet users, first introduced in 2006. It currently exists in two distinct versions: 1.0 and 2.0. It is important to note that Oauth 2.0 is not backward compatible with 1.0, as they are entirely separate technical specifications.
Both versions of Oauth rely on an alternative method for passing data to web services, besides using querystring parameters. This method uses An HTTP header used to provide information about the context of the request.. Request headers are not visible in the URL querystring but are transmitted along with the URL when the web service is called, providing additional context and security.
Oauth 1.0 authentication requires four parameters: Consumer Key, Consumer Secret, Access Token, and Token Secret. These are essentially four keys that function similarly to the querystring keys used in earlier examples, such as the data.gov API. However, due to technical challenges, particularly around URL redirects, Oauth 2.0 was developed as an improved alternative. Oauth 2.0 uses a A large token or key that is sent along with URL requests as a header., which is a single, sizable token (approximately three times larger than a querystring key) sent as a header. This approach enhances security and simplifies the authentication process.
Oauth 2.0 is widely adopted and powers numerous modern web services, including those from cloud-based machine learning platforms like Azure ML Studio and AWS Machine Learning. For example, a demo web service you may have created in a previous class, based on the BikeBuyers.csv dataset, could illustrate how this works. This dataset contains information about consumers visiting a bicycle store, and the web service performs more than just returning data—it accepts data inputs and provides a prediction on whether a new customer will purchase a bike.
To make such a web service functional, additional values must be sent alongside the bearer token as inputs to the model, which are then used to generate a prediction. When working with large datasets or data structures more complex than a simple key/value dictionary, these inputs are typically sent in the Data sent to a web service in addition to the URL and any parameters or headers.. In the following example, you will see how all three inputs—parameters, headers, and body—are combined to interact with the web service.
import requests
import json
# Define the input data structure
data = {
"Inputs": {
"input1": [ # This is a list of feature sets; you can send multiple customers at a time
{ # Example of a customer's data
"age": 19, # Age of the customer
"sex": "female", # Gender of the customer
"bmi": 27.9, # BMI (Body Mass Index) of the customer
"children": 0, # Number of children the customer has
"smoker": "yes", # Smoking status: "yes" or "no"
"region": "southwest" # Geographic region: northeast, northwest, southeast, southwest
},
{ # Collect user inputs for another customer
"age": int(input("What is your age? (enter a valid integer): ")),
"sex": input("What is your gender? (female/male): "),
"bmi": float(input("What is your BMI? (e.g., 21.3): ")),
"children": int(input("How many children do you have? (enter an integer): ")),
"smoker": input("Do you smoke? (enter yes or no): "),
"region": input("Where do you live? (options: northeast, northwest, southeast, southwest): ")
} # You could potentially add as many customers as you want to with additional dictionaries here
]
}
}
# Encode the data as a JSON string
body = str.encode(json.dumps(data))
# Define the web service endpoint and API key
url = 'http://772ac08d-cced-464d-b0e9-03f59d2f1fef.westcentralus.azurecontainer.io/score'
api_key = 'qmvgoa0Yw2paT2ACX2n1D306aoEs1c8S' # Replace with your actual API key
# Set the headers for the HTTP request
headers = {
'Content-Type': 'application/json', # Specify the format of the request body
'Authorization': 'Bearer ' + api_key # Include the API key for authorization
}
# Send the POST request to the endpoint; the result is immediately parsed as JSON for further use
req = requests.post(url=url, data=body, headers=headers).json()
# Print the raw response for debugging purposes
print('\nRaw response from the API:', req, '\n')
# Iterate through the response results to extract and display projected costs
print("Customer projected costs:")
for result in req['Results']['WebServiceOutput0']:
# Format and right-align the printed cost value
print(f" Customer projected cost: ${result['Scored Labels']:>10.2f}")
# Output:
# What is your age? (enter a valid integer): 45
# What is your gender? (female/male): male
# What is your BMI? (e.g., 21.3): 24.3
# How many children do you have? (enter an integer): 3
# Do you smoke? (enter yes or no): no
# Where do you live? (options: northeast, northwest, southeast, southwest): southeast
#
# Raw response from the API: {'Results': {'WebServiceOutput0': [{'Scored Labels': 25180.178081707592}, {'Scored Labels': 7992.073217857426}]}}
#
# Customer projected costs:
# Customer projected cost: $ 25180.18
# Customer projected cost: $ 7992.07
Before we end, notice a couple of things. First, the request was a POST rather than a GET. Although parameters, body, and headers can be used with both GET and POST requests, the web service handles them a bit differently. However, we do not need to know how the web service processes this data in order to use it. We only need to know to format the request. Second, notice that the body needed to be JSON encoded before sending it. Each web service can require whatever format it wants for the body. The web service documentation will let you know how it wants the body encoded.