Examples
Some examples illustrating the basics of the API.
You can find the source code and data files for these examples in
the examples
directory of the squonk2-python-client repository.
get_token
An example that illustrates how to use the client get a token that can be used in other examples.
#!/usr/bin/env python
"""Get and print a Squonk2 access token.
"""
import argparse
import os
from squonk2.auth import Auth
# Username and password are taken from environment variables...
keycloak_user: str = os.environ["SQUONK2_KEYCLOAK_USER"]
keycloak_user_password: str = os.environ["SQUONK2_KEYCLOAK_USER_PASSWORD"]
# Less sensitive information is extracted from the command-line...
parser = argparse.ArgumentParser(
description="Get a user token. SQUONK2_KEYCLOAK_USER and"
" SQUONK2_KEYCLOAK_USER_PASSWORD must be set."
)
parser.add_argument(
"--keycloak-hostname", "-k", help='The API URL, i.e. "example.com"', required=True
)
parser.add_argument(
"--keycloak-realm", "-r", help='The Keycloak realm, i.e. "blob"', required=True
)
parser.add_argument(
"--keycloak-client-id",
"-i",
help='The Keycloak client ID, i.e. "data-manager-api-dev"'
' or "account-server-api-dev"',
required=True,
)
args = parser.parse_args()
# Now get an API token.
# It should be valid for the remainder of the utility...
token: str = Auth.get_access_token(
keycloak_url="https://" + args.keycloak_hostname + "/auth",
keycloak_realm=args.keycloak_realm,
keycloak_client_id=args.keycloak_client_id,
username=keycloak_user,
password=keycloak_user_password,
)
assert token
print(token)
Note
Tokens typically have a limited lifespan and you may need to regenerate it at intervals.
To run this example set these environment variables (your parameters may differ): -
export SQUONK2_KEYCLOAK_USER=<keycloak username>
export SQUONK2_KEYCLOAK_USER_PASSWORD=<keycloak password>
Then run it like this, storing the token in the KEYCLOAK_TOKEN
environment variable: -
export KEYCLOAK_TOKEN=$(./examples/get_token.py \
--keycloak-hostname keycloak.xchem-dev.diamond.ac.uk \
--keycloak-realm xchem \
--keycloak-client-id data-manager-api-dev)
calc_rdkit_props
An example that illustrates how to use the client to run a job that Illustrates how to: -
Upload a file
Run a simple job (with options) using that file
Wait for the job to complete
Download the results and, finally…
Cleanup (delete) the job instance
It uploads a .smi
file, a text file containing lines of tab-separated
SMILES and a Compound ID strings. The one used here can be found
in the examples directory of this repository.
This example calculates molecular properties using RDKit and uses the rdkit-molprops Job, which is typically available on a DM server.
Read the rdkit-molprops documentation in our Virtual Screening collection for further details.
#!/usr/bin/env python
"""An example that illustrates how to use the client to run a job that
calculates molecular properties using RDKit.
Remember that you need to have the SQUONK2_DMAPI_URL environment variable set to
the Squonk2 Data Manager API URL, e.g.
'https://data-manager.xchem-dev.diamond.ac.uk/data-manager-api' or set the
API URL programmatically with a call to DmApi.set_api_url().
"""
import os
import sys
import time
from squonk2.dm_api import DmApi, DmApiRv
# Squonk2 authentication token, project id and the job's input file
# are taken from environment variables...
token: str = os.environ.get("KEYCLOAK_TOKEN")
project_id: str = os.environ.get("PROJECT_ID")
job_input: str = os.environ.get("JOB_INPUT")
if token:
print("TOKEN present")
else:
print("No token provided")
sys.exit(1)
if project_id:
print("PROJECT_ID present")
else:
print("No project_id provided")
sys.exit(1)
if job_input:
print("JOB_INPUT present")
else:
print("No job_input provided")
sys.exit(1)
# The 'ping()' is a handy, simple, API method
# to check the Data Manager is responding.
rv: DmApiRv = DmApi.ping(token)
if rv.success:
print("API OK")
else:
print("API not responding")
sys.exit(1)
# Put some files in a pre-existing DM Project.
# The project is identified by the project_id.
# We simply name the file (or files) and the project-relative
# destination path.
rv = DmApi.put_unmanaged_project_files(
token, project_id=project_id, project_files=job_input, project_path="/work"
)
if rv.success:
print("FILE UPLOAD OK")
else:
print("FILE UPLOAD FAILED")
sys.exit(1)
# Now, run a Job.
# We identify jobs by using a 'collection', 'job' and 'version'
# and then pass variables expected by the Job in a 'variables' block...
spec = {
"collection": "rdkit",
"job": "rdkit-molprops",
"version": "1.0.0",
"variables": {
"separator": "tab",
"outputFile": "work/foo.smi",
"inputFile": "work/100.smi",
},
}
rv = DmApi.start_job_instance(
token, project_id=project_id, name="My Job", specification=spec
)
# If successful the DM returns an instance ID
# (the instance identity of our specific Job)
# and a Task ID, which is responsible for running the Job.
if rv.success:
instance_id = rv.msg["instance_id"]
task_id = rv.msg["task_id"]
print(f"JOB STARTED (instance_id={instance_id})")
else:
print("JOB FAILED")
sys.exit(1)
# We can now use the 'task_id' to query the state of the running Job
# (an instance). When we receive 'done' the Job's finished.
ITERATIONS = 0
while True:
if ITERATIONS > 10:
print("TIMEOUT")
sys.exit(1)
rv = DmApi.get_task(token, task_id=task_id)
if rv.msg["done"]:
break
print("waiting ...")
ITERATIONS += 1
time.sleep(5)
print("DONE")
# Here we get Files from the project.
# These might be files the Job's created.
rv = DmApi.get_unmanaged_project_file(
token,
project_id=project_id,
project_file="foo.smi",
project_path="/work",
local_file="examples/foo.smi",
)
if rv.success:
print("DOWNLOAD OK")
else:
print("DOWNLOAD FAILED")
print(rv)
# Now, as the Job remains in the DM until deleted
# we tidy up by removing the Job using the instance ID we were given.
rv = DmApi.delete_instance(token, instance_id=instance_id)
if rv.success:
print("CLEANUP OK")
else:
print("CLEANUP FAILED")
print(rv)
sys.exit(1)
Assuming you’ve set a token in the environment variable KEYCLOAK_TOKEN
set these additional environment variables.
You will need access to pre-existing Squonk2 Project, we’ve used
project-6c54641f-00b3-4cfa-97f7-363a7b76230a
but you will need
to provide ione that’s valid with your environment: -
export SQUONK2_DMAPI_URL=https://data-manager.xchem-dev.diamond.ac.uk/data-manager-api
export PROJECT_ID=project-6c54641f-00b3-4cfa-97f7-363a7b76230a
export JOB_INPUT=examples/100.smi
Then run the example like this :
./examples/calc_rdkit_props.py