Skip to content

Instantly share code, notes, and snippets.

@alanbchristie
Created June 6, 2024 13:49
Show Gist options
  • Save alanbchristie/cd7e07928b9bbab7c924f3ff4107f314 to your computer and use it in GitHub Desktop.
Save alanbchristie/cd7e07928b9bbab7c924f3ff4107f314 to your computer and use it in GitHub Desktop.
Simplified API token-demo (Fragalysis)
#! /usr/bin/env python
#
# A simplified 'token-demo'.
# Driven by a number of envieonment variables,
# this code example illustrates the extraction of a token from the Stack keycloak server
# and then the invokation of a (non-CSRF) API endpoint using that toekn.
#
# Tested with Python 3.12.3 and requires 'requests' (and tested with 2.32.2).
# Last tested 6th June 2024 against the legacy Fragalysis Stack.
import os
# Use the Python requests module
# (you'll need to have PIP-installed this - it's not part of core Python)
import requests
# Various 'sensitive' values...
# Required!
# Hostname is without the https, i.e. 'example./com'
KEYCLOAK_HOSTNAME: str = os.environ['KEYCLOAK_HOSTNAME']
KEYCLOAK_USERNAME: str = os.environ['KEYCLOAK_USERNAME']
KEYCLOAK_PASSWORD: str = os.environ['KEYCLOAK_PASSWORD']
KEYCLOAK_CLIENT_SECRET: str = os.environ['KEYCLOAK_CLIENT_SECRET']
# Other values, with defaults
KEYCLOAK_CLIENT_ID: str = os.environ.get('KEYCLOAK_CLIENT_ID', 'fragalysis')
KEYCLOAK_REALM: str = os.environ.get('KEYCLOAK_REALM', 'xchem')
FRAGALYSIS_HOSTNAME: str = os.environ.get('FRAGALYSIS_HOSTNAME', 'fragalysis-legacy.xchem.diamond.ac.uk')
def get_keycloak_access_token() -> str:
"""Gets an 'access token' from Keycloak.
If successful we'll get the token (a big long string)
"""
keycloak_url: str = f"https://{KEYCLOAK_HOSTNAME}/auth"
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()
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.
method = "api/download_structures"
url = f"https://{FRAGALYSIS_HOSTNAME}/{method}/"
headers = {"Authorization": f"Bearer {access_token}"}
data = {"target_name": "Mpro", "file_url": "", "proteins": ""}
resp = requests.post(url, headers=headers, data=data)
print(resp)
assert resp is not None
print(resp.text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment