Skip to content
Peter Holloway edited this page Apr 25, 2025 · 2 revisions

Numtracker from Python

Using the service from Python code is similar to making requests with curl. The basic underlying request is a 'normal' http request and can be made via any http library, for instance httpx. The handling of the deserialization of responses can be made easier using a library such as pydantic. While graphql specific libraries are available for forming queries, for a limited API surface such as numtracker it is possible to build them manually.

Making queries

It is possible to wrap the queries in application specific types if it makes code clearer but the underlying requests are possible using the http library directly.

import httpx

SERVER = "https://numtracker.example.com/graphql"

def run_query(query: str, server=SERVER) -> dict[str, Any]:
    # error handling left as an exercise. Errors will be returned under the
    # `errors` key in the returned json data - the HTTP status code will not
    # reflect whether the query was successful or not.
    return httpx.post(server, json={"query": query}).json()['data']

# Query for visit directory
visit_directory = run_query("""
    {
        paths(instrument: "i22", instrumentSession: "cm12345-6") {
            path
        }
    }
""")

directory = Path(visit_directory['paths']['path'])

# Query for scan information
scan_info = run_query("""
    mutation {
        scan(instrument: "i22", instrumentSession: "cm12345-6") {
            scanNumber
            scanFile
            directory {
                path
            }
            detectors(names: ["one", "two"]) {
                name
                path
            }
        }
    }
""")

scan_number = scan_info['scan']['scanNumber']
scan_file = scan_info['scan']['scanFile']
# ...etc

Authentication

The method for acquiring an access token is beyond the scope of this page (see docs here) but once the token is available it can be added to requests as an 'Authorization' header. For instance the above run_query method could be amended to include a token as follows

def run_query(server: str, query: str, token: str|None):
    headers = {"Authorization": f"Bearer {token}"} if token else {}
    httpx.post(server, json={"query": query}, headers=headers)

Clone this wiki locally