Last active
July 26, 2023 14:14
-
-
Save alanbchristie/ce49248560060c9562d7f7e34f8172af to your computer and use it in GitHub Desktop.
API access to a Token-based REST service (Python/requests)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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