Skip to main content

Examples

Python Example

This example shows the basic idea of how the API could be used via python and the flow to create an instance with a startup script (e.g. GPU driver), snapshot, and delete it. The full script can be found here.

Before you start you need to have a Genesis Cloud account with a valid payment method, enabled the Compute Service, created an API TOKEN, and uploaded your public SSH Key.

import requests
import json
import time

# Go to https://console.genesiscloud.com/dashboard/security
# and create and paste your secret API token here
API_TOKEN = "<ADD TOKEN HERE>"
# as well as the name of the SSH key you want to use to access your instance
ssh_key_name = "<ADD SSH KEY NAME>"

For this example, we will set a startup script to install anything you like on the new instance right after it booted.

startup_script = """#!/bin/sh

# Define your installation script here.

"""

Here is the main function of the our script. First it walks us through the flow of getting the needed IDs of our image, SSH key, and optionally security group. Then we create the instance and wait for it to be ready. Afterwards, we will take a snapshot, wait for the snapshot to finish, and then delete the instance.

def main():
# Instance Configuration
# Modify the following values to configure the instance that you want to create.
# Please Note: As of the time of writing only a single SSH key is supported.
instance = {
"name": "my-new-instance",
"type": "vcpu-4_memory-18g_disk-80g_nvidia3090-1",
# Ubuntu 18.04
"image_id": "45d06539-f8f5-48d9-816e-d4b1a8e5163e",
"ssh_key_names": [ssh_key_name],
"security_group_names": ["standard"],
"startup_script": startup_script,
}

# Get the IDs for the SSH keys we want for our instance.
# Please Note: As the the time of writing this ONLY ONE KEY is supported.
instance["ssh_key_ids"] = get_ssh_key_ids(instance["ssh_key_names"])

# OPTIONAL: Get the IDs of the security groups we want for our instance.
instance["security_group_ids"] = get_security_group_ids(
instance["security_group_names"]
)

# Create the instance
instance["id"] = create_instance(instance)

# The created instance will first be in the status 'enqueued' and then 'creating'
# before changing to the status 'active' when it has booted and was assigned a public IP address.
# This typically takes 30 seconds to 2 Minutes.
while get_instance_status(instance["id"]) != "active":
time.sleep(1.0)

# Now you can use your instance: connect via SSH, start a machine learning training, render a movie or find a cure agains Covid-19... ;)
# For demo purpose we will just wait 10 minutes here.
# Please Note: if you passed a startup script, i.e. installing the NVIDIA GPU driver, the script is likely still executing by the time the
# instance changes to acctive.
print(
"Instance is ready to be used...Public IP address: "
+ get_instance_public_ip(instance["id"])
)
time.sleep(600.0)

# If you want to save the state of your instance's disk you can take a snapshot before you delete it.
# Next time you create an instance you can use this snapshot as the instance image.
# This way all you installed software and stored data are ready to be used.
# Note: In order to store larger datasets that you want to use with multiple instances it is preferred to use volumes for data storage.
snapshot_name = "my-snapshot-2020-04-12"
snapshot_id = create_instance_snapshot(instance["id"], snapshot_name)

# Before we can delete our instance we need to wait for the snapshot to finish.
# The instance state will change from "copying" during the snapshot back to 'active'.
# This typically takes 1 to 5 minutes
while get_instance_status(instance["id"]) != "active":
time.sleep(1.0)
print("Finished taking snapshot " + snapshot_id)

# Now that we saved our instance data as snapshot we are ready to delete it again.
delete_instance(instance["id"])

print("Done.")

Let's take a look at the API calls. We authenticate by passing the API Token in the header. After the API request, we always check for the HTTP status code to see if the call was successful. Optionally, for listing APIs we can set query parameters for example per_page to define the number of elements returned by the API call. For the create API calls we also have to provide a JSON with the needed information to create the resource, such as the name.

def get_ssh_key_ids(ssh_key_names):
# getting a list of available SSH Keys and looking up the ID

# Setting the secret auth token and content type in the headers of all API calls
headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
params = {"per_page": 50, "page": 1}
response = requests.get(
"https://api.genesiscloud.com/compute/v1/ssh-keys",
headers=headers,
params=params,
)

if response.status_code != 200:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()

available_ssh_keys = {}
for ssh_key in response.json()["ssh_keys"]:
available_ssh_keys[ssh_key["name"]] = ssh_key["id"]

ssh_key_ids = []
for ssh_key_name in ssh_key_names:
ssh_key_ids.append(available_ssh_keys[ssh_key_name])

return ssh_key_ids


def get_security_group_ids(security_group_names):
# getting a list of security groups and the id of a specifc security group

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
params = {"per_page": 50, "page": 1}
response = requests.get(
"https://api.genesiscloud.com/compute/v1/security-groups",
headers=headers,
params=params,
)

if response.status_code != 200:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()

available_security_groups = {}
for security_group in response.json()["security_groups"]:
available_security_groups[security_group["name"]] = security_group["id"]

security_group_ids = []
for security_group_name in security_group_names:
security_group_ids.append(available_security_groups[security_group_name])

return security_group_ids


def create_instance(instance):
# Creating an instance

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
jsonbody = {
"name": instance["name"],
"hostname": instance["name"],
"type": instance["type"],
"image": instance["image_id"],
"ssh_keys": instance["ssh_key_ids"],
"security_groups": instance["security_group_ids"],
"metadata": {"startup_script": instance["startup_script"]},
}
response = requests.post(
"https://api.genesiscloud.com/compute/v1/instances",
headers=headers,
json=jsonbody,
)

if response.status_code != 201:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()

instance_id = response.json()["instance"]["id"]
print("Creating instance " + instance_id)
return instance_id


def get_instance_status(instance_id):

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
response = requests.get(
"https://api.genesiscloud.com/compute/v1/instances/" + instance_id,
headers=headers,
)
if response.status_code == 200:
return response.json()["instance"]["status"]
else:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()


def get_instance_public_ip(instance_id):

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
response = requests.get(
"https://api.genesiscloud.com/compute/v1/instances/" + instance_id,
headers=headers,
)
if response.status_code == 200:
return response.json()["instance"]["public_ip"]
else:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()


def create_instance_snapshot(instance_id, snapshot_name):

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
jsonbody = {
"name": snapshot_name,
}
response = requests.post(
"https://api.genesiscloud.com/compute/v1/instances/"
+ instance_id
+ "/snapshots",
headers=headers,
json=jsonbody,
)

if response.status_code != 201:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()

snapshot_id = response.json()["snapshot"]["id"]
print("Creating snapshot " + snapshot_id + " of instance " + instance_id)
return snapshot_id


def delete_instance(instance_id):

headers = {"Content-Type": "application/json", "Authorization": "Bearer " + API_TOKEN}
response = requests.delete(
"https://api.genesiscloud.com/compute/v1/instances/" + instance_id,
headers=headers,
)

if response.status_code != 204:
print(response.status_code)
print(json.dumps(response.json(), indent=4, sort_keys=True))
exit()
print("Deleting instance " + instance_id)

In order to execute the main function when the script is started we add at the end of script

if __name__ == "__main__":
main()

And here is a sample output from the script which you should see if everything goes well.

Creating instance 306b6845-b199-4d68-8d92-834a0b40f4cf
Instance is ready to be used...Public IP address: 194.61.20.115
Creating snapshot 4292d74e-b9d3-4c92-82a4-b5e14222f72d of instance 306b6845-b199-4d68-8d92-834a0b40f4cf
Finished taking snapshot 4292d74e-b9d3-4c92-82a4-b5e14222f72d
Deleting instance 306b6845-b199-4d68-8d92-834a0b40f4cf
Done.