Skip to content

Instantly share code, notes, and snippets.

@alanbchristie
Last active July 26, 2023 14:14
Show Gist options
  • Save alanbchristie/ce49248560060c9562d7f7e34f8172af to your computer and use it in GitHub Desktop.
Save alanbchristie/ce49248560060c9562d7f7e34f8172af to your computer and use it in GitHub Desktop.
API access to a Token-based REST service (Python/requests)
#! /usr/bin/env python
import os
import base64
# Use the Python requests module
# (you'll need to have PIP-installed this - it's not part of core Python)
import requests
# The keycloak credentials (sensitive).
# Required!
KEYCLOAK_USERNAME: str = os.environ['KEYCLOAK_USERNAME']
KEYCLOAK_PASSWORD: str = os.environ['KEYCLOAK_PASSWORD']
KEYCLOAK_CLIENT_SECRET: str = os.environ['KEYCLOAK_CLIENT_SECRET']
def get_csrf(REQ_URL):
client = requests.session()
# Retrieve the CSRF token first
client.get(REQ_URL) # sets cookie
if 'csrftoken' in client.cookies:
# Django 1.6 and up
csrftoken = client.cookies['csrftoken']
else:
# older versions
csrftoken = client.cookies['csrf']
return csrftoken
def get_keycloak_access_token(*,
keycloak_url: str,
keycloak_realm: str,
keycloak_client_id: str) -> str:
"""Gets an 'access token' from Keycloak.
If successful we'll get the token (a big long string)
"""
realm_url: str = f"{keycloak_url}/realms/{keycloak_realm}"
url = f"{realm_url}/protocol/openid-connect/token"
data = (
f"client_id={keycloak_client_id}"
f"&grant_type=password"
f"&username={KEYCLOAK_USERNAME}"
f"&password={KEYCLOAK_PASSWORD}"
f"&client_secret={KEYCLOAK_CLIENT_SECRET}"
)
headers = {"Content-Type": "application/x-www-form-urlencoded"}
resp = requests.post(url, headers=headers, data=data, timeout=4.0)
assert resp.status_code == 200
assert "access_token" in resp.json()
return resp.json()["access_token"]
# Get a Keycloak/OIDC access token
# ----------------------------
access_token = get_keycloak_access_token(
keycloak_url = "https://????/auth",
keycloak_realm = "xchem",
keycloak_client_id = "????")
print(f"access_token='{access_token}'")
# Call a Fragalysis API Method (using OIDC authentication)
# ----------------------------
# Now, using the token, we can call the Fragalysis REST API.
# Here we're just using a GET that needs no extra parameters.
# What _you_ need to provide in terms of URL and associated DATA is up to you.
fragalysis_hostname = "????"
method = "viewer/upload_cset"
url = f"https://{fragalysis_hostname}/{method}/"
csrf_token = get_csrf(url)
headers = {"X-CSRFToken": csrf_token,
"Cookie": f"csrftoken={csrf_token}",
"Authorization": f"Bearer {access_token}"}
resp = requests.get(url, headers=headers)
print(resp)
assert resp is not None
print(resp.text)
# Call a Fragalysis API Method (using Basic authentication)
# ----------------------------
basic = str(base64.b64encode(f"{KEYCLOAK_USERNAME}:{KEYCLOAK_PASSWORD}".encode("utf-8")), "utf-8")
csrf_token = get_csrf(url)
headers = {"X-CSRFToken": csrf_token,
"Cookie": f"csrftoken={csrf_token}",
"Authorization": f"Basic {basic}"}
resp = requests.get(url, headers=headers)
assert resp is not None
print(resp)
print(resp.text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment