Streamlining Workspace Operations and More With Python and SingleStore’s Management API

Streamlining Workspace Operations and More With Python and SingleStore’s Management API

In this blog post, we'll explore a suite of Python functions designed to simplify various tasks like creating, resuming, terminating and resizing workspaces, as well as uploading files to staging areas from S3.

Efficiently managing a database requires powerful tools. When coupled with Python, the SingleStore Management API provides an incredible level of control and automation. In this blog post, we'll explore a suite of Python functions designed to simplify various tasks like creating, resuming, terminating and resizing workspaces, as well as uploading files to staging areas from S3. Before we dive into the functions, ensure you have the following Python libraries imported:

1import requests2import json3import re4import boto35from datetime import datetime

For detailed API documentation, visit the SingleStore Management API Reference

Python-powered workspace management

Create workspaces with a simple function

Kickstart your database operations by setting up a new workspace effortlessly using Python.

1def create_workspace(name, size, workspaceGroupID, token):2    url = "<https://api.singlestore.com/v1/workspaces>"3    payload = {4        "enableKai": True,5        "name": name,6        "size": size,7        "workspaceGroupID": workspaceGroupID,8    }9    payload_json = json.dumps(payload)10    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}11    response = requests.post(url, headers=headers, data=payload_json)12    return response.text

Tip: to get your workspace group ID, navigate to your workspace group and copy the last part of the URL.

Resuming a workspace

Need to get your suspended workspace back online? Do it in a snap with this function.

1def resume_workspace(workspaceID, token):2    url = f"<https://api.singlestore.com/v1/workspaces/{workspaceID}/resume>"3    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}4    response = requests.post(url, headers=headers)5    return response.text

Tip: to get your workspaceID, click into the ellipsis (Actions) next to your workspace, click on “Edit Workspace Settings” and copy the workspace ID.

Terminating a workspace

Save resources by temporarily terminating inactive workspaces using this straightforward function.

1def terminate_workspace(workspaceID, token):2    url = f"<https://api.singlestore.com/v1/workspaces/{workspaceID}>"3    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}4    response = requests.requests("DELETE", url, headers=headers)5    return response.text

Resizing a workspace

Adjust the size of your workspace easily to match your current needs, ensuring efficient resource utilization and performance optimization.

1def resize_workspace(workspaceID, size, token):2    url = f"<https://api.singlestore.com/v1/workspaces/{workspaceID}>"3    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}4    payload = {5      "size": size6    }7
8    response = requests.patch(url, headers=headers, data=json.dumps(payload))9
10    return response.text

Tip: visit our sizing page for a list of supported sizes (i.e., S-00, S-1, S4, etc.)

Streamline file uploads to Stage

SingleStore Stage allows you to load files in a staging area attached to your workspace group, helping you quickly get your data into SingleStore (read more about it here).. You can either upload a local file, or upload a file in a S3 bucket.

Local file upload:

1def upload_to_staging(workspaceGroupID, stagePath, fileName, filePath, token):2    url = f"<https://api.singlestore.com/v1/stages/{workspaceGroupID}/fs/{stagePath}>"3
4    headers = {"Authorization": f"Bearer {token}"}5
6    # if do not want to specify fileName, only filePath7    # fileName = os.path.basename(filePath)8
9    files = [("file", (fileName, open(filePath, "rb")))]10
11    response = requests.request("PUT", url, headers=headers, files=files)12
13    return response.text

S3 file upload:

1def upload_to_staging(workspaceGroupID, bucketName, filepath, stagePath, awsKeyID, awsSecret, awsToken, token):2    url = f"<https://api.singlestore.com/v1/stages/{workspaceGroupID}/fs/{stagePath}>"3
4    headers = {"Authorization": f"Bearer {token}"}5
6    # accessing the S3 buckets using boto3 client7    s3 = boto3.client('s3',8        aws_access_key_id=awsKeyID,9        aws_secret_access_key=awsSecret,10        aws_session_token=awsToken11    )12
13    # download file from S314    s3.download_file(bucketName, filepath, 'localfile')15
16    # open the file in binary mode17    with open('localfile', 'rb') as f:18        files = {'file': f}19        response = requests.put(url, headers=headers, files=files)20
21    return response.text

Easy access to billing information

Staying on top of your billing information is crucial. With our Python function, accessing your billing details is just a function call away.

1def get_billing(startTime=None, endTime=None, aggregateBy="day"):2    # can change aggregateBy to "hour" or "month"3
4    # format time in ISO 8601 format5    def format_time(time):6        iso8601_pattern = re.compile(r"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$")7        if iso8601_pattern.match(time):8            formatted_time = format_time9        else:10            try:11                parsed_time = datetime.strptime(time, "%Y-%m-%dT%H:%M:%SZ")12                formatted_time = parsed_time.strftime("%Y-%m-%dT%H:%M:%SZ")13            except ValueError:14                try:15                    # if no time provided, add 'T00:00:00Z'16                    parsed_date = datetime.strptime(time, "%Y-%m-%d")17                    formatted_time = parsed_date.strftime("%Y-%m-%dT00:00:00Z")18                except Exception as e:19                    raise ValueError(20                        "Invalid date time format. Please provide a valid ISO 8601 formatted time."21                    )22
23        return formatted_time24
25    formatted_startTime = format_time(startTime)26    formatted_endTime = format_time(endTime)27
28    url = f"<https://api.singlestore.com/v1/billing/usage?startTime={formatted_startTime}&endTime={formatted_endTime}&aggregateBy={aggregateBy}>"29    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}30
31    response = requests.get(url, headers=headers)32    return response.text

This function will return a JSON object detailing the compute credits and storage usage for each workspace in the specified workspace group. You can then plot graphs to visualize — for instance, the compute credits consumed over time by each workspace. The following code snippet will aggregate this consumption by day:

1# plotting the compute credits consumed per day for each workspace2import matplotlib.pyplot as plt3import pandas as pd4from datetime import datetime5
6json_data = get_billing(startTime="2023-10-25", endTime="2023-10-28")7data = json.loads(json_data)8
9# function to parse the date-time format in the data10def parse_datetime(dt_str):11    return datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S %z UTC')12
13# complete data extraction14all_usage = []15for billing in data['billingUsage']:16    all_usage.extend(billing['Usage'])17
18# convert to dataframe19df_all = pd.DataFrame(all_usage)20
21# convert endTime, startTime, and value to appropriate types22df_all['endTime'] = df_all['endTime'].apply(parse_datetime)23df_all['value'] = pd.to_numeric(df_all['value'])24
25# extracting all distinct workspace names26all_resource_names = df_all['resourceName'].unique()27
28# creating a bar plot for each distinct workspace name29plt.figure(figsize=(15, 10))30
31# offset to position bars next to each other32bar_width = 0.04 # adjusting bar width for potentially large number of33resources34
35# plotting individual bars for each workspace36for idx, resource_name in enumerate(all_resource_names):37    # filter data for each workspace38    filtered_data = df_all[df_all['resourceName'] == resource_name]39
40    # group by date and sum the values41    grouped_data = filtered_data.groupby('endTime').agg({'value': 'sum'}).reset_index()42
43    # plotting44    plt.bar(45        grouped_data['endTime'] + pd.to_timedelta(idx * bar_width, unit='D'),46        grouped_data['value'],47        width=bar_width,48        label=resource_name49    )50
51# adjust x-axis to accommodate the bar width52plt.xticks(rotation=45)53plt.title('Compute Credits Consumed Per Day for Each Workspace')54plt.xlabel('Date')55plt.ylabel('Compute Credits')56plt.legend(title='Resource Name', bbox_to_anchor=(1.05, 1), loc='upper left')57plt.tight_layout()58plt.show()

You will get a plot that looks something like this:

Why use these Python functions?

These Python functions serve as practical examples of how to interact with the SingleStore Management API. They are designed to be:

  • User friendly. Even if you're not familiar with the API, you can start using these functions right away.
  • Timesaving. Automate repetitive tasks and focus on more important aspects of your work.
  • Customizable. Feel free to modify these functions to better fit your specific requirements.

How to build an app with Python and SingleStore

Step-by-step guides for setting up your free SingleStore Helios® account, connecting to your database, and running your first queries.
Start building

Learn more

For a comprehensive understanding of what the SingleStore Management API offers, including detailed endpoint descriptions, check out the API Overview. You can put this all to the test by activating your SingleStore trial — including with our newly released Free Shared Tier.

The SingleStore Management API offers robust capabilities for managing your database environment. By leveraging these Python functions, you can automate and streamline your workspace operations and file management tasks. Whether you're adjusting workspace sizes, managing workspaces or handling file uploads, these tools are designed to enhance your productivity and simplify your database management journey.


Share

Start building with SingleStore