Appearance
Generate HMAC headers - Python
The document API uses HMAC for authentication. You must use your private key and public key to create an HMAC digest for a request and pass that as part of the Authorization header.
The python code below shows the function that can be used to generate the headers for such a request:
py
def generate_headers(method, path):
"""Generates authentication headers for the request."""
private_key = os.environ.get('UNOPDF_PRIVATE_KEY')
public_key = os.environ.get('UNOPDF_PUBLIC_KEY')
timestamp = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
payload = method.upper() +"\n" + timestamp + "\n" + path.lower()
digest = hmac.new(private_key.encode('utf-8'), msg=payload.encode('utf-8'), digestmod=hashlib.sha256).digest()
base64_encoded = base64.b64encode(digest)
url_safe = base64_encoded.rstrip(b'=').replace(b'+', b'-').replace(b'/', b'_').decode('utf-8')
auth_header = "SharedKey: " + public_key + ":" + url_safe
return {'Authorization': auth_header, 'Timestamp': timestamp, 'Accept': 'application/json'}
See the Authentication guide for more information.
The example below shows a fully working example that calls the /v1/files
endpoint using HMAC signing.
Code
py
import base64
import datetime
import hashlib
import hmac
import os
import requests
from dotenv import load_dotenv
load_dotenv()
def get_error(response):
"""Extracts error message from a response object."""
try:
response_body = response.json()
except ValueError:
response_body = response.text.strip()
if isinstance(response_body, dict) and 'errors' in response_body:
errors = response_body['errors']
if isinstance(errors, dict):
return ','.join(str(v) for v in errors.values())
return str(errors)
return str(response_body) or response.reason
#region generate_headers
def generate_headers(method, path):
"""Generates authentication headers for the request."""
private_key = os.environ.get('UNOPDF_PRIVATE_KEY')
public_key = os.environ.get('UNOPDF_PUBLIC_KEY')
timestamp = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
payload = method.upper() +"\n" + timestamp + "\n" + path.lower()
digest = hmac.new(private_key.encode('utf-8'), msg=payload.encode('utf-8'), digestmod=hashlib.sha256).digest()
base64_encoded = base64.b64encode(digest)
url_safe = base64_encoded.rstrip(b'=').replace(b'+', b'-').replace(b'/', b'_').decode('utf-8')
auth_header = "SharedKey: " + public_key + ":" + url_safe
return {'Authorization': auth_header, 'Timestamp': timestamp, 'Accept': 'application/json'}
#endregion generate_headers
def main():
"""Main function to execute the script."""
path = "/v1/files"
url = os.environ.get('UNOPDF_API_URL') + path
method = 'GET'
headers = generate_headers(method, path)
response = requests.request(method, url, headers=headers, timeout=30)
if response.status_code != 200:
message = get_error(response)
raise Exception("Error \"" + message + "\" calling UnoPdf API \"GET " + url + "\".")
print("ok")
if __name__ == "__main__":
main()
txt
requests
python-dotenv