Skip to content

Instantly share code, notes, and snippets.

@dantetemplar
Created November 20, 2025 08:25
Show Gist options
  • Select an option

  • Save dantetemplar/e217d25a73cff1d136b2189aedb4a8bf to your computer and use it in GitHub Desktop.

Select an option

Save dantetemplar/e217d25a73cff1d136b2189aedb4a8bf to your computer and use it in GitHub Desktop.
OrcaSlicer slice via API

Project: OrcaSlicer HTTP API Wrapper

Contact: https://t.me/dantetemplar

Background

We need a way to slice 3D models programmatically from a Python backend, without any manual GUI interaction. Initially this was attempted with CuraEngine, but in practice it turned out to be hard to configure, debug, and run reliably in a headless environment.

OrcaSlicer, on the other hand, provides a modern slicing pipeline, good default profiles, and an active community. However, it is primarily a desktop GUI tool. The goal of this project is to wrap OrcaSlicer into a small, well-documented HTTP service that can be called from other systems, especially Python-based backends.

The primary application on our side is to generate toolpaths not for a typical desktop 3D printer, but for a large manipulator used in additive manufacturing. From the API perspective, this is “just another machine profile”, but this is the context in which the service will be used.

Prior Work and Motivation

Based on this discussion there are at least two related open projects:

  • AFKFelix/orca-slicer-api
    A TypeScript REST API with a nice OpenAPI schema. It works out of the box for .3mf projects exported from OrcaSlicer. It claims to support profiles, but in practice requires manually uploading all default profiles (not only user-defined ones), which makes it inconvenient for general use. I have forked it and experimented with it: https://github.com/dantetemplar/orca-slicer-api.

  • LukaCek/slice_api
    An example Python API for print price calculation. It allows choosing print quality and then slicing using predefined BambuLab profiles. It returns a price, .3mf file, and G-code. The code is more of a prototype and is tightly focused on that specific use case.

Both of these projects are designed to run via Docker setups, which greatly simplifies the environment and dependency management for OrcaSlicer-based services.

This task takes inspiration from these projects (REST API around OrcaSlicer, OpenAPI schema, Python integration, Docker-first deployment), but aims to produce a cleaner, more general, and better documented solution.

Task

Design and implement an open-source HTTP API wrapper around OrcaSlicer that can be used as a standalone slicing service. All detailed API design decisions (endpoint layout, request/response schemas, error model, internal data model, etc.) are up to the author, as long as the capabilities below are covered and documented.

The project must be released under the MIT license.

The service is expected to be packaged and run only via Docker (e.g., Dockerfile + docker-compose.yml or similar), following the approach of the existing projects mentioned above.

Functional Scope

The service should:

  1. Expose OrcaSlicer as an HTTP API

    • Headless service that can be run and deployed as a Docker container.
    • The service is responsible for orchestrating OrcaSlicer calls and managing temporary files.
    • The primary supported deployment method is via Docker; local bare-metal setups are not required.
  2. Support input formats

    As input, the API must accept models/projects in the following formats:

    • .stl
    • .step
    • .3mf
  3. Provide outputs

    For a slicing request, the API must be able to return:

    • G-code.
    • .3mf project (with applied profile/settings).
    • Print metadata (e.g., estimated time, material usage, layer count, etc.) in a machine-readable format such as JSON.

    The exact structure of the metadata is up to the author, but it should be documented.

  4. Handle profiles

    The API must work with slicing profiles in a way that covers:

    • Using standard/default OrcaSlicer profiles.
    • Creating and saving new profiles.
    • Updating and deleting custom profiles.
    • Applying temporary overrides of individual settings for a single slicing job (without permanently changing the underlying profile).

    The internal representation of profiles, storage mechanism, and how they are referenced through the API (IDs, names, etc.) are up to the author, but must be clearly described in the documentation.

  5. Allow per-request setting overrides

    • It should be possible to modify specific slicing parameters for a single job (e.g., layer height, infill) without persisting those changes to any profile.
    • The mechanism (e.g., a separate “overrides” field in the API) is up to the author.
  6. Provide documentation and OpenAPI/Swagger

    • The API must have a clear, machine-readable OpenAPI (Swagger) schema.
    • There should be an interactive Swagger UI (or equivalent) for manual exploration and testing.
    • The documentation must describe:
      • Available endpoints.
      • Main request/response formats.
      • How profiles and overrides work.
      • Example flows (e.g., “upload model → choose profile → slice → download G-code”).
  7. Provide a Python client

    • A small Python library that wraps the HTTP API and exposes a convenient interface for common operations (e.g., slicing a file with a chosen profile).
    • The client should:
      • Handle basic configuration (base URL, timeouts, etc.).
      • Surface server errors in a meaningful way (with exceptions and access to error information).
    • The author is free to choose the error and exception model, but it should be consistent and documented.
  8. Logging and errors

    • The server should log requests and slicing operations in a way that helps debug issues (e.g., what profile was used, which file was sliced, whether OrcaSlicer failed).
    • The API should return clear error responses for typical failure cases (invalid input, missing profile, slicer failure, etc.).
    • The exact logging format and error schema are up to the author, but they should be described briefly in the documentation.

Non-Functional Expectations

  • The project should be reasonably structured and maintainable.
  • The only supported way to run the service should be via Docker:
    • Provide a Dockerfile that builds a runnable image with OrcaSlicer and the API server.
    • Optionally provide a docker-compose.yml for local development/testing.
    • The README should include a short “Quickstart” showing how to build and run the container and how to access the API and Swagger UI.
  • Host OS–level manual setup instructions are not required, as long as the Docker setup is self-contained and documented.

Deliverables

  • Source code of the HTTP API server that wraps OrcaSlicer.
  • Docker-based setup (at minimum: Dockerfile, plus any scripts needed for container startup).
  • OpenAPI/Swagger specification and interactive docs.
  • Python client library with basic usage examples.
  • Documentation (README or separate docs) explaining:
    • Background and motivation.
    • How to build and run the Docker image/container.
    • How to use the API and Python client to:
      • List/use/create/update/delete profiles.
      • Slice models in supported formats and retrieve outputs.
  • MIT license file in the repository.
@dantetemplar
Copy link
Author

Firstly, install OrcaSlicer on your machine and perform your first slicing.

This how is possible to export .3mf and different profiles:
image

image

@dantetemplar
Copy link
Author

root@3017433de2c4:/app# /app/squashfs-root/AppRun --help
[2025-11-20 14:55:38.884956] [0x00007f2e98009540] [trace]   Initializing StaticPrintConfigs
OrcaSlicer-01.10.01.50:
Usage: orca-slicer [ OPTIONS ] [ file.3mf/file.stl ... ]

OPTIONS:
 --allow-multicolor-oneplate
                     If enabled, the arrange will allow multiple color on one plate
 --allow-newer-file option
                     Allow 3mf with newer version to be sliced
 --allow-rotations   If enabled, the arrange will allow rotations when place object
 --avoid-extrusion-cali-region
                     If enabled, the arrange will avoid extrusion calibrate region when place object
 --clone-objects "1,3,1,10"
                     Clone objects in the load list
 --datadir           Load and store settings at the given directory. This is useful for maintaining
                     different profiles or including configurations from a network storage.
 --debug level       Sets debug logging level. 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:trace
 --downward-check    if enabled, check whether current machine downward compatible with the machines
                     in the list
 --downward-settings "machine1.json;machine2.json;..."
                     the machine settings list need to do downward checking
 --enable-timelapse  If enabled, this slicing will be considered using timelapse
 --load-assemble-list assemble_list.json
                     Load assemble object list from config file
 --load-custom-gcodes custom_gcode_toolchange.json
                     Load custom gcode from json
 --load-filament-ids "1,2,3,1"
                     Load filament ids for each object
 --load-filaments "filament1.json;filament2.json;..."
                     Load filament settings from the specified file list
 --load-settings "setting1.json;setting2.json"
                     Load process/machine settings from the specified file
 --makerlab-name name
                     MakerLab name to generate this 3mf
 --makerlab-version version
                     MakerLab version to generate this 3mf
 --metadata-name "name1;name2;..."
                     metadata name list added into 3mf
 --metadata-value "value1;value2;..."
                     metadata value list added into 3mf
 --outputdir dir     Output directory for the exported files.
 --skip-modified-gcodes option
                     Skip the modified gcodes in 3mf from Printer or filament Presets
 --skip-objects "3,5,10,77"
                     Skip some objects in this print
 --uptodate-filaments "filament1.json;filament2.json;..."
                     load uptodate filament settings from the specified file when using uptodate
 --uptodate-settings "setting1.json;setting2.json"
                     load uptodate process/machine settings from the specified file when using
                     uptodate
 --arrange option    Arrange options: 0-disable, 1-enable, others-auto
 --assemble          Arrange the supplied models in a plate and merge them in a single model in order
                     to perform actions once.
 --convert-unit      Convert the units of model
 --ensure-on-bed     Lift the object above the bed when it is partially below. Disabled by default
 --orient            Orient options: 0-disable, 1-enable, others-auto
 --repetitions count Repetions count of the whole model
 --rotate            Rotation angle around the Z axis in degrees.
 --rotate-x          Rotation angle around the X axis in degrees.
 --rotate-y          Rotation angle around the Y axis in degrees.
 --scale factor      Scale the model by a float factor
 --downward-check "machine1.json;machine2.json;..."
                     check whether current machine downward compatible with the machines in the list
 --export-3mf filename.3mf
                     Export project as 3MF.
 --export-settings settings.json
                     Export settings to a file.
 --export-slicedata slicing_data_directory
                     Export slicing data to a folder.
 --export-stl        Export the objects as single STL.
 --export-stls       Export the objects as multiple STLs to directory
 --help, -h          Show command help.
 --info              Output the model's information.
 --load-defaultfila option
                     Load first filament as default for those not loaded
 --load-slicedata slicing_data_directory
                     Load cached slicing data from directory
 --min-save option   export 3mf with minimum size.
 --mstpp time        max slicing time per plate in seconds.
 --mtcpp count       max triangle count per plate for slicing.
 --no-check          Do not run any validity checks, such as gcode path conflicts check.
 --normative-check option
                     Check the normative items.
 --pipe pipename     Send progress to pipe.
 --slice option      Slice the plates: 0-all plates, i-plate i, others-invalid
 --uptodate          Update the configs values of 3mf to latest.

Print settings priorites:
        1) setting values from the command line (highest priority)
        2) setting values loaded with --load_settings and --load_filaments
        3) setting values loaded from 3mf(lowest priority)

Example profile setup:

root@1a0607c94727:/app/squashfs-root# ls resources/profiles
 Anker              Creality          Geeetech                   Positron3D            TwoTrees
 Anker.json         Creality.json     Geeetech.json              Positron3D.json       TwoTrees.json
 Anycubic           Custom           'Ginger Additive'           Prusa                 UltiMaker
 Anycubic.json      Custom.json      'Ginger Additive.json'      Prusa.json            UltiMaker.json
 Artillery          DeltaMaker        InfiMech                   Qidi                  Vivedino
 Artillery.json     DeltaMaker.json   InfiMech.json              Qidi.json             Vivedino.json
 BBL                Dremel            Kingroon                   Raise3D               Volumic
 BBL.json           Dremel.json       Kingroon.json              Raise3D.json          Volumic.json
 BIQU               Elegoo            Lulzbot                    Ratrig                Voron
 BIQU.json          Elegoo.json       Lulzbot.json               Ratrig.json           Voron.json
 Blocks             Eryone            MagicMaker                 RolohaunDesign        Voxelab
 Blocks.json        Eryone.json       MagicMaker.json            RolohaunDesign.json   Voxelab.json
 CONSTRUCT3D        FLSun             Mellow                     SecKit                Vzbot
 CONSTRUCT3D.json   FLSun.json        Mellow.json                SecKit.json           Vzbot.json
 Chuanying          Flashforge        OrcaArena                  Snapmaker             Wanhao
 Chuanying.json     Flashforge.json   OrcaArena.json             Snapmaker.json        Wanhao.json
'Co Print'          FlyingBear        OrcaFilamentLibrary        Sovol                 blacklist.json
'Co Print.json'     FlyingBear.json   OrcaFilamentLibrary.json   Sovol.json            check_unused_setting_id.py
 Comgrow            Folgertech        Peopoly                    Tronxy                hotend.stl
 Comgrow.json       Folgertech.json   Peopoly.json               Tronxy.json


root@1a0607c94727:/app/squashfs-root# ls resources/profiles/Anker
'Anker M5 All-Metal Hot End_cover.png'  'Anker M5_cover.png'   M5-CE-texture.svg   filament   process
'Anker M5C_cover.png'                    M5-CE-bed.stl         M5C-CE-bed.stl      machine


root@1a0607c94727:/app/squashfs-root# cat resources/profiles/Anker.json 
{
    "name": "Anker",
    "version":  "02.03.00.03",
    "force_update": "0",
    "description": "Anker configurations",
    "machine_model_list": [
        {
            "name": "Anker M5",
            "sub_path": "machine/Anker M5.json"
        },
        {
            "name": "Anker M5 All-Metal Hot End",
            "sub_path": "machine/Anker M5 All-Metal Hot End.json"
        },
        {
            "name": "Anker M5C",
            "sub_path": "machine/Anker M5C.json"
        }
    ],
    "process_list": [
        {
            "name": "fdm_process_common",
            "sub_path": "process/fdm_process_common.json"
        },
        {
            "name": "fdm_process_anker_common_0_2",
            "sub_path": "process/fdm_process_anker_common_0_2.json"
        },
        ... // more processes
        {
            "name": "0.30mm Standard 0.6mm nozzle @Anker",
            "sub_path": "process/0.30mm Standard 0.6mm nozzle @Anker.json"
        },
        {
            "name": "0.35mm Draft 0.6mm nozzle @Anker",
            "sub_path": "process/0.35mm Draft 0.6mm nozzle @Anker.json"
        },
        {
            "name": "0.40mm Superdraft 0.6mm nozzle @Anker",
            "sub_path": "process/0.40mm Superdraft 0.6mm nozzle @Anker.json"
        }
    ],
    "filament_list": [
        {
            "name": "fdm_filament_common",
            "sub_path": "filament/fdm_filament_common.json"
        },
        ... // more filaments
        {
            "name": "fdm_filament_tpu",
            "sub_path": "filament/fdm_filament_tpu.json"
        },
        {
            "name": "Anker Generic ABS @base",
            "sub_path": "filament/Anker Generic ABS @base.json"
        },
        ... // more filaments
    ],
    "machine_list": [
        {
            "name": "fdm_machine_common",
            "sub_path": "machine/fdm_machine_common.json"
        },
        {
            "name": "fdm_marlin_common",
            "sub_path": "machine/fdm_marlin_common.json"
        },
        {
            "name": "Anker M5 0.2 nozzle",
            "sub_path": "machine/Anker M5 0.2 nozzle.json"
        },
        ... // more machines
    ]
}

root@1a0607c94727:/app/squashfs-root# cat "resources/profiles/Anker/machine/Anker M5 0.2 nozzle.json"
{
    "type": "machine",
    "name": "Anker M5 0.2 nozzle",
    "inherits": "fdm_marlin_common",
    "from": "system",
    "setting_id": "GM004",
    "instantiation": "true",
    "nozzle_diameter": [
        "0.2"
    ],
    "max_layer_height": [
        "0.16"
    ],
    "printer_model": "Anker M5",
    "printer_variant": "0.2",
    "auxiliary_fan": "0",
    "bed_exclude_area": [],
    "default_filament_profile": [
        "Anker Generic PLA+"
    ],
    "default_print_profile": "0.10mm Standard 0.2mm nozzle @Anker",
    "extruder_clearance_height_to_lid": "250",
    "extruder_clearance_height_to_rod": "30",
    "extruder_clearance_max_radius": "45",
    "extruder_clearance_radius": "45",
    "printer_structure": "i3",
    "nozzle_type": "brass",
    "printable_height": "250",
    "printable_area": [
        "0x0",
        "235x0",
        "235x235",
        "0x235"
    ],
    "retraction_length": [
        "0.75"
    ],
    "upward_compatible_machine": []
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment