Running Repository Tasks
You can connect and run git repositories on the Signaloid Cloud Compute Engine.
The Signaloid Cloud Compute Engine API currently only supports repositories hosted on GitHub.
When you submit a repository task to the API, the Signaloid Cloud Compute Engine clones your repository (with --recurse-submodules
), builds your code, and runs the application.
To connect private repositories you need to authorise the Signaloid Cloud Compute Engine to access your GitHub account. You have to do this via the Signaloid Cloud Developer Platform. Refer to documentation on connecting repositories for more details.
This guide uses the Brown-Ham model GitHub repository from the Signaloid public demo repositories as an example. The following code examples show to connect and run the repository on the Signaloid Cloud Compute Engine API.
The Task request communication and schema are different when running repository tasks compared to source code tasks.
For repository applications you need to connect the repository first and then provide the repository identifier (RepositoryID
) to the Signaloid Cloud Compute Engine, instead of sending the entire application source with an API request. The repository is connected to your Signaloid Cloud account and any changes you make to the repository object are pulled each time you launch a repository task for this repository.
Prerequisites
To run a repository task, you will need to have the following:
- An API key to access the Signaloid Cloud API. Please refer to the Authentication guide for more details.
- A GitHub repository containing the application source.
- If the repository is private, authorization of the Signaloid Cloud Compute Enging to access your repositories.
Connecting a repository to your account
To run a repository task you must first connect the repository to your Signaloid Cloud account. You can connect a repository using the /repositories
endpoint of the API. Through this endpoint, you can also programmatically list your connected repositories and amend their configurations if needed.
To connect a repository to your account you need to send an HTTP POST
request to the /repositories
endpoint with a repository configuration object.
The TypeScript type definition below shows the structure of the repository configuration object:
- TypeScript
type DataSource = {
Location: string;
Object: "DataSource";
ResourceID: string;
ResourceType: "Gateway" | "Bucket" | "Drive" | "SignaloidCloudStorage";
}
type TraceVariable = {
File: string;
LineNumber: number;
Expression: string;
}
type RepositoryConfig = {
RemoteURL: string;
Commit: string;
Branch: string;
BuildDirectory: string;
Arguments: string;
Core?: string;
DataSources?: DataSource[];
TraceVariables?: TraceVariable[];
};
You can also use the Repositories page on the Signaloid Cloud Developer Platform to connect repositories to your account. Please refer to documentation on connecting repositories for more details.
The code below shows how to connect a repository to your account using the axios
library. The code shows how to use the BuildDirectory
key. We set the BuildDirectory
to src/v3
to instruct the Signaloid Cloud Compute Engine to use the code src/v3
as the application source code and ignore the rest of the directories. The README in the GitHub repository explains the different versions of the Brown-Ham example.
- TypeScript
- cURL
// API token generated from signaloid.io/settings/api
const apiToken = "scce_yourSignaloidCloudApiKey";
// Setup HTTP client
const axios = require("axios");
const signaloidClient = axios.create({
baseURL: "https://api.signaloid.io",
});
// Setup request headers
signaloidClient.defaults.headers["Authorization"] = `${apiToken}`;
signaloidClient.defaults.headers["Content-Type"] = "application/json";
const repositoryURL = "https://github.com/signaloid/Signaloid-Demo-Metallurgy-BrownHamModel";
const repositoryConfig = {
RemoteURL: repositoryURL,
Commit: "42e4b5a6f5bc8641317f17d0662b54ae9fc587f9",
Branch: "main",
BuildDirectory: "src/v3",
Arguments: "",
};
console.log(`Connecting ${repositoryURL} to your account via the API...`);
let repositoryID;
let connectRepositoryResponse;
try {
connectRepositoryResponse = await signaloidClient.post("/repositories", repositoryConfig);
console.log("connectRepositoryResponse.status :>> ", connectRepositoryResponse.status);
if (connectRepositoryResponse.status === 201) {
repositoryID = connectRepositoryResponse.data.RepositoryID;
console.log(`...repository successfully connected. Repository ID: ${repositoryID}`);
}
} catch (error) {
console.log("Error :>> ", error); // [TODO]: handle errors
}
# Branch is empty to get the default branch
connectRepositoryRequestBody='{
"RemoteURL": "https://github.com/signaloid/Signaloid-Demo-Metallurgy-BrownHamModel",
"Commit": "HEAD",
"Branch": "",
"BuildDirectory": "src/v3",
"Arguments": "",
"Overrides": {
"Core": "cor_b21e4de9927158c1a5b603c2affb8a09"
}
}'
# The following API connects a Github repository with details specified by githubRepositoryObject.
connectCurlReturn=$(curl -s --request POST --location 'https://api.signaloid.io/repositories' \
--header "Content-Type: application/json" \
--header "Authorization: "$signaloidAPIKey \
--data "$connectRepositoryRequestBody")
# Unique identifier of the connected repository
connectedRepositoryID=$(echo $connectCurlReturn | jq -r '.RepositoryID')
if [ ! "$connectedRepositoryID" == "null" ]
then
echo "GitHub repository connected with ID: "$connectedRepositoryID
else
message=$(echo $connectCurlReturn | jq -r '.Message')
echo "Exiting because GitHub repository connrection failed with message: \""$message"\""
exit
fi
The Signaloid Cloud Compute Engine API allows you to connect the same repository multiple times to your account. This allows you to keep different configurations of the same GitHub repository. Each connected repository will have a different repository IDs even though they use the same GitHub repository as the base.
Setting up the task request
The repository task request object has the following structure:
- TypeScript
type RepositoryTaskRequest = {
Type: "Repository";
Repository: string;
Overrides?: {
Arguments?: string;
BuildDirectory?: string;
Core?: string;
DataSources?: DataSource[];
TraceVariables?: TraceVariable[];
};
};
Task request object for an uncertaintry-tracking (UT) C0 or C0 Pro core
The snippet below shows how to initialise a task request object for a connected GitHub repository.
- TypeScript
- cURL
// Core ID of the C0-S+ core
const coreID = "cor_b21e4de9927158c1a5b603c2affb8a09";
const taskRequest = {
Type: "Repository",
Repository: repositoryID, // your repository ID
Overrides: {
Core: coreID,
},
};
# Core ID of the C0-S+ core
signaloidCoreId="cor_b21e4de9927158c1a5b603c2affb8a09"
taskObject='{
"Type": "Repository",
"Repository": "'$connectedRepositoryID'",
"Overrides": {
"Core": "'$signaloidCoreId'"
}
}'
Task request object for a C0 or C0 Pro Reference core
You need to use the TraceVariables
element in Overrides
of the Task object to instruct the Signaloid Cloud Compute Engine about which variables it should trace. Your source code may contain multiple variables with the same name, defined in different scopes of your source code. Because of this, the Signaloid Cloud Compute Engine needs to know the file and line number of the declaration of the variable that you want to trace to be able to uniquely identify it.
The following code snippets show how to use the Signaloid API calls to instruct the Signaloid Cloud Compute Engine to run on C0-Reference core the source code shown at the top of the page. The TraceVariables
element of the Task object, instructs the Signaloid Cloud Compute Engine to trace variable sigmaCMpa
, in line 95 of file Brown-and-Ham-with-all-parameters-as-distributions.c
as you can see in src/v3/src
of the connected GitHub repository.
- TypeScript
- cURL
// Core ID of the C0-Reference core
const coreID = "cor_9a3efb0094405df5aeb61cf1f29606a0";
const taskRequest = {
Type: "Repository",
Repository: repositoryID, // your repository ID
Overrides: {
Core: coreID,
TraceVariables: [{ Expression: "sigmaCMpa", File: "src/v3/src/Brown-and-Ham-with-all-parameters-as-distributions.c", LineNumber: 95 }]
},
};
# Core ID of the C0-Reference core
signaloidCoreId="cor_9a3efb0094405df5aeb61cf1f29606a0"
taskObject='{
"Type": "Repository",
"Repository": "'$connectedRepositoryID'",
"Overrides": {
"Core": "'$signaloidCoreId'",
"TraceVariables": [{"Expression":"sigmaCMpa","File":"Brown-and-Ham-with-all-parameters-as-distributions.c","LineNumber":95}]
}
}'
Submitting the task to the API
- TypeScript
- cURL
As with the single-source application, once you have constructed the task request object, you can submit it to the Signaloid Cloud Compute Engine via a POST
request to the /tasks
endpoint.
console.log("Submitting the task to the API...");
let taskPostResponse;
try {
taskPostResponse = await signaloidClient.post("/tasks", taskRequest);
if (taskPostResponse.data.TaskID) {
console.log(`...task successfully created with ID: ${taskPostResponse.data.TaskID}`);
}
} catch (error) {
console.log("Error :>> ", error); // [TODO]: handle errors
}
The response from the API follows the following structure. You can find the full structure here by choosing the RepositoryTaskPost
.
{
"data": {
"Object": "Task",
"TaskID": "tsk_6dcae4d1c4f585901efa12a89a063996",
"Owner": "usr_yourSignaloidCloudUserID",
"Application": {...}, // The application that was submitted to the API
"Status": "Accepted",
[...other response keys omitted]
},
"status": 202,
"statusText": "Accepted",
[...other response keys omitted]
}
You can now use the TaskID
to retrieve the status and outputs of the task from the API.
Once you have created the task request object, you can submit it to the API via a POST
request to /tasks
. The code snippet below shows how to submit the task request to the API using curl
.
# API token generated from signaloid.io/settings/api
signaloidAPIKey="scce_yourSignaloidCloudApiKey"
taskEndpointResponse=$(curl -s --request POST --location 'https://api.signaloid.io/tasks' \
--header "Content-Type: application/json" \
--header "Authorization: $signaloidAPIKey" \
--data "$taskObject")
If the task is valid, and the API has accepted the request, the response
variable will contain information about the task. The code snippet below shows the contents of the response
variable after the task has been successfully created.
{
"Application": {
"Type":"SourceCode",
"SourceCode": {
"Object": "SourceCode",
"Code": "...Task source code...",
"Arguments": "",
"Language": "C"
},
"Overrides": {
"Core": {
"UpdatedAt": 1683643245,
"Class": "C0",
"Microarchitecture": "Athens",
"CorrelationTracking": "Autocorrelation",
"Precision": 64,
"Object": "Core",
"MemorySize": 64000000,
"CoreID": "cor_b21e4de9927158c1a5b603c2affb8a09",
"Owner": "*",
"CreatedAt": 1683643245,
"Name": "C0-S+"
}
}
},
"Object": "Task",
"TaskID": "tsk_66a6c55239ae406caf9fa439a61115db",
"Owner": "usr_87ee9c03da2d4ddab7fdbf4788cb483a",
"CreatedAt": 1713997688,
"UpdatedAt": 1713997688,
"FinishedAt": 0,
"StartedAt": 0,
"Status": "Accepted",
"StatusTransitions": [{"Status":"Accepted","Timestamp":1713997688,"Message":"POST /tasks"}]
}
You can now use a utility like jq
to get the TaskID
:
# Retrieve TaskID
TaskID=$(echo $taskEndpointResponse | jq -r '.TaskID')
if [ ! "$TaskID" == "null" ]
then
echo "Task started with Task ID: "$TaskID
else
error=$(echo $taskEndpointResponse | jq -r '.error')
message=$(echo $taskEndpointResponse | jq -r '.Message')
echo "Starting repository task FAILED: error: \""$error"\" message: \""$message"\""
exit
fi
The TaskID
will allow you to retrieve the status and outputs of the task from the API.