GitHubContribute in GitHub: Open doc issue|Edit online

Querying the CAT GraphQL API with Python

You can find sample code that helps you to interact with the CAT GraphQL API from a Jupyter Notebook. You can find the code here.

Step 1: Install Required Packages:

Install the following packages with the command:

!pip install requests pandas matplotlib seaborn

1. pandas

A powerful data manipulation and analysis library that provides the DataFrame object for working with structured data.

2. matplotlib

A plotting library for creating static, animated, and interactive visualizations. It is often used to make line plots, bar charts, scatter plots, and more.

3. seaborn

A statistical data visualization library that is built on top of Matplotlib. It makes it easier to create visually appealing charts with better defaults and additional plot types.

Step 2: Configure the GraphQL Client

Set up a Python script to interact with a GraphQL server. Depending on whether you enforce client certificates, you need to present your client certificate in the request.

import requests
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Set up endpoint
HOST = 'hostname' 
# The ${HTTPS_PORT} parameter from the server setup
PORT = 59000
PATH = 'graphql'
GRAPHQL_ENDPOINT = f"https://{HOST}:{PORT}/{PATH}"

# Paths to mTLS certificate files
CLIENT_CERT_PATH = "mtls-client.crt"
CLIENT_KEY_PATH = "mtls-client.key"

# Optional: path to a CA bundle (self-signed or internal cert)
CA_CERT_PATH = "serverCA.crt"

# Modified query function
def run_query(query: str):
    headers = {"Content-Type": "application/json"}

    try:
        response = requests.post(
            GRAPHQL_ENDPOINT,
            json={"query": query},
            headers=headers,
            cert=(CLIENT_CERT_PATH, CLIENT_KEY_PATH),
            verify=CA_CERT_PATH
        )
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Query failed to run with status code: {response.status_code}. {response.text}")

Step 3: Define and Execute a query for data visualization

Define a GraphQL query to request specific data from the server, then executes it using the secure mTLS connection that is established earlier. The response is parsed to extract raw data, ready for visualization with libraries like pandas, matplotlib, and seaborn.

query = """
query MyQuery {
  getCryptoUsageCount(fieldName: "crypto_usage_id") {
    counts {
      name
      count
    }
    fieldName
  }
}
"""

response = run_query(query)
raw_data = response["data"]["getCryptoUsageCount"]["counts"]

Step 4: Normalize and Transform the Data

Make sure that the data is in a clean, organized format that is suitable for visualization, addressing missing values, and arranging the data in a meaningful order.

df = pd.DataFrame(raw_data)

# Rename null 'name' values to "Unknown"
df["name"] = df["name"].fillna("Unknown")

# Sort the data by 'count' in descending order
df = df.sort_values(by="count", ascending=False)
df

Output example:

|   | name | count |
| - | ---- | ----- | 
| 6 | AES256 | 8137|
| 2 | 93AADZCB | 7706|
| 0 | 93AADY4J | 7686|
| 185 | PRNG | 5641|
| 117 | CSFPKB | 5364|
| ... | ... | ...|
| 194 | SHA3-256 | 1|
| 195 | SHA3-384 | 1|
| 196 | SHA3-512 | 1|
| 149 | CSFSTCS | 1|
| 191 | SHA224 | 1|

Step 5: Visualize the Data

Create a bar chart to visualize the frequency of different cryptographic algorithms used.

plt.figure(figsize=(18, 10))
sns.barplot(data=df.head(50), x="name", y="count")
plt.xticks(rotation=45, ha="right")
plt.title("Top 50 Crypto Usages by Frequency")
plt.xlabel("Crypto Usage")
plt.ylabel("Count")
plt.tight_layout()
plt.show()

Bar chart example:

bar chart

Alternative query with paginated data

The following is an example of a GraphQL query that is designed to retrieve paginated data from the server.

query = """
query MyQuery {
  getKeyUsageEvents(limit: 10, offset: 10) {
    keyUsageEvents {
      algorithmId
      category
      jobId
      jobName
      keyFingerprint
      keyFingerprintType
      keySecurity
      keyType
      keyUsages
      keyUsedByJobId
      userId
      plex
      service
      startTime
      endTime
      systemId
      systemName
      tokenFormat
      usageCount
    }
  }
}
"""
response = run_query(query)
raw_data = response["data"]["getKeyUsageEvents"]["keyUsageEvents"]
df_raw = pd.DataFrame(raw_data)
df_raw

Output example:

algorithmId category jobId jobName keyFingerprint keyFingerprintType keySecurity keyType keyUsages keyUsedByJobId userId plex service startTime endTime systemId systemName tokenFormat usageCount
0 AES:256 SYMMETRIC STC48231 UKO0DA 2EFA3A SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::2EFA3A UKO0DAU MV3N CSFSAE 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 2
1 AES:256 SYMMETRIC STC48231 UKO0DA F77656 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY IMPORTER UDX_CCA,IMPORT,TRANSLAT,GEN_OPIM,GEN_IMEX,GEN_... MV3N:MV3N:CKDS::F77656 UKO0DAU MV3N CSFSYI2 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 1
2 AES:256 SYMMETRIC STC48231 UKO0DA 372998 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY IMPORTER UDX_CCA,IMPORT,TRANSLAT,GEN_OPIM,GEN_IMEX,GEN_... MV3N:MV3N:CKDS::372998 UKO0DAU MV3N CSFSYI2 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 1
3 AES:256 SYMMETRIC STC49383 UKO0D B70AFF SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::B70AFF UKO0DSU MV3N CSFSAD 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 4
4 AES:256 SYMMETRIC STC49383 UKO0D 1FB4D7 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::1FB4D7 UKO0DSU MV3N CSFSAD 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 3
5 AES:256 SYMMETRIC STC49383 UKO0D B70AFF SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::B70AFF UKO0DSU MV3N CSFSAE 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 3
6 AES:256 SYMMETRIC STC49383 UKO0D 1FB4D7 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::1FB4D7 UKO0DSU MV3N CSFSAE 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 2
7 AES:256 SYMMETRIC STC49383 UKO0D F8D6D1 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC,EC... MV3N:MV3N:CKDS::F8D6D1 UKO0DSU MV3N CSFSAD 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 3
8 AES:256 SYMMETRIC STC49383 UKO0D 2EFA3A SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC MV3N:MV3N:CKDS::2EFA3A UKO0DSU MV3N CSFSAD 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 2
9 AES:256 SYMMETRIC STC49383 UKO0D F8D6D1 SHAVP1 ENCRYPTED_UNDER_MASTER_KEY CIPHER UDX_CCA,DATA_ENCRYPTION,DATA_DECRYPTION,CBC,EC... MV3N:MV3N:CKDS::F8D6D1 UKO0DSU MV3N CSFKRR2 2025-03-31T00:30:41.627559 2025-03-31T01:30:41.647569 MV3N:MV3N MV3N VARIABLE_LENGTH_CCA 3

Disable SSL verification (verify=False) only for internal or testing purposes, as it bypasses certificate validation.

For schema types, see CC CAT GraphQL reference.