Skip to content

Create G-Code

This example demonstrates how to upload a G-code file and create a G-Code entry in the Helio Additive platform. This is a prerequisite for running simulations and optimizations.

Create the following GraphQL files, then run your language’s codegen tool to generate the types.

queries/GetPresignedUrl.graphql
query GetPresignedUrl($fileName: String!) {
getPresignedUrl(fileName: $fileName) {
mimeType
url
key
}
}

API Reference:

  1. Setup the client and configuration

    index.ts
    import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";
    import * as fs from "fs";
    import * as path from "path";
    import { GetPresignedUrlDocument } from "./queries/__generated/GetPresignedUrl.generated";
    import { CreateGcodeV2Document } from "./mutations/__generated/CreateGcodeV2.generated";
    import { GcodeV2Document } from "./queries/__generated/GcodeV2.generated";
    // Load PAT from environment
    const PAT = process.env.PAT;
    if (!PAT) {
    throw new Error("PAT environment variable is required");
    }
    // Create Apollo Client
    const client = new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
    uri: "https://api.helioadditive.com/graphql",
    headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${PAT}`,
    },
    }),
    });
    // Replace these with actual IDs from your materials and printers queries
    const PRINTER_ID = process.env.PRINTER_ID ?? "your-printer-id";
    const MATERIAL_ID = process.env.MATERIAL_ID ?? "your-material-id";
  2. Upload G-code file to presigned URL

    First, request a presigned URL from the API, then upload your G-code file directly to S3.

    async function uploadToS3(filePath: string) {
    const fileName = path.basename(filePath);
    // Get presigned URL
    const { data } = await client.query({
    query: GetPresignedUrlDocument,
    variables: { fileName },
    fetchPolicy: "no-cache",
    });
    const presigned = data?.getPresignedUrl;
    if (!presigned) {
    throw new Error("Failed to get presigned URL");
    }
    const { key, url, mimeType } = presigned;
    // Upload file to S3
    const fileBuffer = fs.readFileSync(filePath);
    const uploadResponse = await fetch(url, {
    method: "PUT",
    body: fileBuffer,
    headers: { "Content-Type": mimeType },
    });
    if (!uploadResponse.ok) {
    throw new Error("Failed to upload file to S3");
    }
    return { key, url, mimeType };
    }
  3. Create the G-Code entry

    Once the file is uploaded, create a G-Code entry in the system using the returned key.

    async function createGcodeEntry(key: string, name: string) {
    const { data } = await client.mutate({
    mutation: CreateGcodeV2Document,
    variables: {
    input: {
    gcodeKey: key,
    printerId: PRINTER_ID,
    materialId: MATERIAL_ID,
    isSingleShell: true,
    name: name,
    },
    },
    });
    const gcodeId = data?.createGcodeV2?.id;
    if (!gcodeId) {
    throw new Error("Failed to create G-Code");
    }
    return gcodeId;
    }
  4. Poll and wait for G-Code to be ready

    After creation, the G-Code needs to be processed. Poll the status until it’s ready.

    async function waitForGcodeReady(gcodeId: string): Promise<void> {
    return new Promise((resolve, reject) => {
    const checkStatus = async () => {
    const { data } = await client.query({
    query: GcodeV2Document,
    variables: { id: gcodeId },
    fetchPolicy: "no-cache",
    });
    const status = data?.gcodeV2?.status;
    const progress = data?.gcodeV2?.progress;
    console.log(`G-Code status: ${status}, progress: ${progress}%`);
    if (status === "READY") {
    resolve();
    } else if (status === "ERROR") {
    reject(new Error("G-Code processing failed"));
    } else {
    // Poll every 2 seconds
    setTimeout(checkStatus, 2000);
    }
    };
    checkStatus();
    });
    }
  5. Put it all together

    Combine all the steps into a single function and run it.

    async function createGcode(filePath: string, name: string) {
    console.log(`Uploading G-code file: ${filePath}`);
    // Upload to S3
    const { key } = await uploadToS3(filePath);
    console.log("File uploaded successfully");
    // Create G-Code entry
    const gcodeId = await createGcodeEntry(key, name);
    console.log(`G-Code created with ID: ${gcodeId}`);
    // Wait for G-Code to be ready
    console.log("Waiting for G-Code processing to complete...");
    await waitForGcodeReady(gcodeId);
    console.log("G-Code is ready!");
    return gcodeId;
    }
    // Example usage
    const gcodeFilePath = "./my-print.gcode";
    const gcodeName = `my-gcode-${Date.now()}`;
    createGcode(gcodeFilePath, gcodeName)
    .then((id) => console.log(`Successfully created G-Code: ${id}`))
    .catch(console.error);
  1. Create a .env.local file with your PAT and IDs:

    Terminal window
    PAT="your-personal-access-token"
    PRINTER_ID="your-printer-id"
    MATERIAL_ID="your-material-id"
  2. Update the PRINTER_ID and MATERIAL_ID with valid IDs from your account. You can get these by running the Listing Printers and Listing Materials examples.

  3. Place your G-code file in the project directory.

  4. Run the example:

    Terminal window
    bun run index.ts ./my-print.gcode