Listing Printers
This example demonstrates how to query and paginate through available printers in the Helio Additive platform.
GraphQL Operations
Section titled “GraphQL Operations”Create the following GraphQL query file, then run your language’s codegen tool to generate the types.
query Printers($page: Int, $pageSize: Int) { printers(page: $page, pageSize: $pageSize) { pages pageInfo { hasPreviousPage hasNextPage } objects { ... on Printer { id name heatedBed heatedChamber nozzleDiameter maxExtruderFlowRate minExtruderFlowRate maxHardwarePrintSpeed minHardwarePrintSpeed brand { id name } } } }}API Reference:
- Printer type - Full printer object structure
- PrinterFilter input - Available filter options
Code Example
Section titled “Code Example”-
Setup the client and configuration
index.ts import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";import { PrintersDocument } from "./queries/__generated/Printers.generated";// Load PAT from environmentconst PAT = process.env.PAT;if (!PAT) {throw new Error("PAT environment variable is required");}// Create Apollo Clientconst client = new ApolloClient({cache: new InMemoryCache(),link: new HttpLink({uri: "https://api.helioadditive.com/graphql",headers: {"Content-Type": "application/json",Authorization: `Bearer ${PAT}`,},}),});main.py import asyncioimport osimport httpxfrom client.client import Client# Load PAT from environmentPAT = os.environ.get("PAT")if not PAT:raise ValueError("PAT environment variable is required")# Create GraphQL clientheaders = {"Authorization": f"Bearer {PAT}"}graphql_client = Client(url="https://api.helioadditive.com/graphql",headers=headers,http_client=httpx.AsyncClient(headers=headers, timeout=60))src/main.rs use graphql_client::{GraphQLQuery, Response};use reqwest::header::{AUTHORIZATION, CONTENT_TYPE};#[derive(GraphQLQuery)]#[graphql(schema_path = "schema.graphqls",query_path = "queries/Printers.graphql",response_derives = "Debug")]struct Printers;// Load from environment in main()let pat = std::env::var("PAT").expect("PAT environment variable must be set");src/main.cpp #include <iostream>#include <string>#include <vector>#include <cstdlib>#include <cpr/cpr.h>#include <boost/json.hpp>#include "PrintersClient.h"#include "graphqlservice/GraphQLResponse.h"#include "graphqlservice/JSONResponse.h"namespace Printers = graphql::client::query::Printers;// Helper function to send HTTP requestsgraphql::response::Value sendHttpRequest(const std::string& query,graphql::response::Value& variables,const std::string& pat) {std::string body = boost::json::serialize(boost::json::object{{"query", query},{"variables", boost::json::parse(graphql::response::toJSON(std::move(variables))).as_object()}});auto response = cpr::Post(cpr::Url{"https://api.helioadditive.com/graphql"},cpr::Header{{"Content-Type", "application/json"},{"Authorization", "Bearer " + pat}},cpr::Body{body});return graphql::response::parseJSON(boost::json::serialize(boost::json::parse(response.text).as_object()["data"].as_object()));}// Load PAT from environmentconst char* pat_env = std::getenv("PAT");if (!pat_env) {std::cerr << "PAT environment variable is required" << std::endl;return 1;}std::string pat(pat_env); -
Query and paginate through printers
Fetch printers page by page until all printers have been retrieved.
async function listPrinters() {let page = 1;const pageSize = 50;const allPrinters: Array<{ id: string; name: string; brand: string }> = [];// Paginate through all printerswhile (true) {const { data } = await client.query({query: PrintersDocument,variables: { page, pageSize },fetchPolicy: "no-cache",});// Collect printers from this pagefor (const printer of data?.printers?.objects ?? []) {if (printer.__typename === "Printer") {allPrinters.push({id: printer.id,name: printer.name,brand: printer.brand?.name ?? "Unknown",});console.log(`Printer: ${printer.name} (${printer.brand?.name})`);console.log(` - Heated Bed: ${printer.heatedBed}`);console.log(` - Heated Chamber: ${printer.heatedChamber}`);console.log(` - Nozzle Diameter: ${printer.nozzleDiameter}mm`);}}// Check if there are more pagesif (!data?.printers?.pageInfo?.hasNextPage) {break;}page++;}return allPrinters;}async def list_printers():page = 1page_size = 50all_printers = []# Paginate through all printerswhile True:result = await graphql_client.printers(page=page, page_size=page_size)# Collect printers from this pagefor printer in result.objects:all_printers.append({"id": printer.id,"name": printer.name,})brand_name = printer.brand.name if printer.brand else "Unknown"print(f"Printer: {printer.name} ({brand_name})")print(f" - Heated Bed: {printer.heated_bed}")print(f" - Heated Chamber: {printer.heated_chamber}")print(f" - Nozzle Diameter: {printer.nozzle_diameter}mm")# Check if there are more pagesif not result.page_info.has_next_page:breakpage += 1return all_printersasync fn list_printers(pat: &str) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> {let client = reqwest::Client::new();let mut page = 1;let page_size = 50;let mut all_printers: Vec<(String, String)> = Vec::new();// Paginate through all printersloop {let variables = printers::Variables {page: Some(page as i64),page_size: Some(page_size),};let response = client.post("https://api.helioadditive.com/graphql").header(CONTENT_TYPE, "application/json").header(AUTHORIZATION, format!("Bearer {}", pat)).json(&Printers::build_query(variables)).send().await?;let body: Response<printers::ResponseData> = response.json().await?;if let Some(errors) = body.errors {return Err(format!("GraphQL errors: {:?}", errors).into());}let data = body.data.expect("No data returned");// Collect printers from this pagefor printer in &data.printers.objects {let brand_name = printer.brand.as_ref().map(|b| b.name.as_str()).unwrap_or("Unknown");println!("Printer: {} ({})", printer.name, brand_name);println!(" - Heated Bed: {}", printer.heated_bed);println!(" - Heated Chamber: {}", printer.heated_chamber);println!(" - Nozzle Diameter: {}mm", printer.nozzle_diameter);all_printers.push((printer.id.clone(), printer.name.clone()));}// Check if there are more pagesif !data.printers.page_info.has_next_page {break;}page += 1;}Ok(all_printers)}struct PrinterInfo {std::string id;std::string name;std::string brand;};std::vector<PrinterInfo> listPrinters(const std::string& pat) {int page = 1;const int pageSize = 50;std::vector<PrinterInfo> allPrinters;// Paginate through all printerswhile (true) {const std::string query = Printers::GetRequestText();graphql::response::Value variables = Printers::serializeVariables(Printers::Variables{.page = page, .pageSize = pageSize});auto response = Printers::parseResponse(sendHttpRequest(query, variables, pat));// Collect printers from this pagefor (const auto& printer : response.printers.objects) {std::string brandName = printer.brand ? printer.brand->name : "Unknown";allPrinters.push_back({printer.id, printer.name, brandName});std::cout << "Printer: " << printer.name << " (" << brandName << ")" << std::endl;std::cout << " - Heated Bed: " << (printer.heatedBed ? "true" : "false") << std::endl;std::cout << " - Heated Chamber: " << (printer.heatedChamber ? "true" : "false") << std::endl;std::cout << " - Nozzle Diameter: " << printer.nozzleDiameter << "mm" << std::endl;}// Check if there are more pagesif (!response.printers.pageInfo.hasNextPage) {break;}page++;}return allPrinters;} -
Put it all together
Run the function and display the results.
// Example usagelistPrinters().then((printers) => {console.log(`\nTotal printers found: ${printers.length}`);}).catch(console.error);if __name__ == "__main__":async def main():printers = await list_printers()print(f"\nTotal printers found: {len(printers)}")asyncio.run(main())#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {let pat = std::env::var("PAT").expect("PAT environment variable must be set");let printers = list_printers(&pat).await?;println!("\nTotal printers found: {}", printers.len());Ok(())}int main() {const char* pat_env = std::getenv("PAT");if (!pat_env) {std::cerr << "PAT environment variable is required" << std::endl;return 1;}std::string pat(pat_env);auto printers = listPrinters(pat);std::cout << "\nTotal printers found: " << printers.size() << std::endl;return 0;}
Running the Example
Section titled “Running the Example”-
Create a
.env.localfile with your PAT:Terminal window PAT="your-personal-access-token" -
Run the example:
Terminal window bun run index.tsTerminal window uv run main.pyTerminal window cargo runTerminal window mkdir build && cd buildcmake .. -DVCPKG_DIR=$(pwd)/../vcpkg/installed/arm64-osxmake./ExampleApp