Skip to content
Table of contents

ChitUI: A local bridge to resin printers

ChitUI places a browser interface in front of SDCP resin printers. A Python process serves the web assets, discovers printers on the local network and translates browser actions into printer communication.

Application and services Fork API Docker Workflow
  • Updated
  • JavaScript · 48.61%
SDCP 3.0DockerBrowser UILocal network Python Upstream credited
Documented components
2Explore modules
Source documents
1Read the instructions
Repository languagesJavaScript 48.61%5

Shares calculated from GitHub Linguist bytes.

JavaScript48.61%
48.61%21,743 bytes
HTML24.57%
24.57%10,991 bytes
Python22.86%
22.86%10,226 bytes
CSS3.51%
3.51%1,572 bytes
Language%Bytes
JavaScript48.61%21,743
HTML24.57%10,991
Python22.86%10,226
CSS3.51%1,572
Dockerfile0.45%200

1. Overview

1.1. Why it exists

Full-featured web control interface for Chitubox SDCP 3.0 resin printers with LAN UDP discovery.

1.2. Best fit

Headless remote management and real-time print monitoring for SLA 3D printers.

2. Use cases

Flask web UI that finds Chitubox SDCP 3.0 resin printers on the LAN, uploads files and starts prints.

Use-case diagram for ChitUI: Discover printers on the LAN; Watch printer status; Upload a print file; List and delete files; Start a printChitUIDiscover printers on the LANWatch printer statusUpload a print fileList and delete filesStart a printPrinter operator«system»SDCP resin printer
People on the left, external systems on the right; each oval is a use case backed by the files cited below.
Discover printers on the LAN
Printer operatorSDCP resin printer

At start-up, discover_printers in main.py broadcasts M99999 over UDP port 3000, saves the replies and opens a WebSocket to each printer at ws://<ip>:3030/websocket.

Watch printer status
Printer operatorSDCP resin printer

The browser asks over Socket.IO; main.py sends SDCP commands 0 (status) and 1 (attributes) and relays printer messages to web/js/chitui.js and sdcp.js.

Upload a print file
Printer operatorSDCP resin printer

POST /upload accepts .ctb, .goo and .prz files, computes an MD5 and sends 1 MB parts to http://<ip>:3030/uploadFile/upload; /progress streams the percentage.

List and delete files
Printer operatorSDCP resin printer

printer_files sends SDCP command 258 with a storage path; action_delete sends command 259 with the file list.

Start a print
Printer operatorSDCP resin printer

action_print sends SDCP command 128 with the file name and StartLayer 0.

2.1. Scenario: Send a sliced model to a resin printer from a browser

  1. Install requirements.txt in a virtualenv and run python main.py, or use docker run --net=host so UDP broadcast works.
  2. At start-up, ChitUI broadcasts M99999 on UDP port 3000 and connects to each printer’s WebSocket on port 3030.
  3. Open http://127.0.0.1:54780/ to see the discovered printers and their status.
  4. Upload a .ctb file; ChitUI saves it to /tmp and sends it in 1 MB parts with an MD5 check.
  5. Pick the file in the printer’s file list and start the print.

Files readREADME.mdmain.pyrequirements.txtDockerfileTODO.txtweb/js/chitui.jsweb/js/sdcp.js

3. Getting started

These commands come from the repository documentation. They were not run during this review.

README.md · Setup
python -mvenv .venv
source .venv/bin/activate
pip install -r requirements.txt
README.md · Usage
python main.py
README.md · Docker
docker build -t chitui:latest .
docker run --rm --name chitui --net=host chitui:latest

4. Repository references

Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.

Configuration and usage

4.1. Usage

README.md

After creating the virtual environment and installing the requirements, you can run ChitUI like this:
Read the full instructions ↗

4.2. Configuration

README.md

Configuration is done via environment variables:

  • PORT to set the HTTP port of the web interface (default: 54780)
  • DEBUG to enable debug logging, log colorization and code reloading (default: False)
Read the full instructions ↗
Source documentation

1 documents read from 1 candidates.

5. Features and components 2

Browser and local server
main.py builds a Flask application with web as its static folder and attaches Flask-SocketIO. Printer and WebSocket registries live in process memory. Discovery uses the local network, which explains the README’s Docker host-network requirement.
File transfer
The upload route validates the extension and saves the incoming file temporarily. The printer upload helper calculates an MD5 checksum and sends one-megabyte parts with offsets. A separate event-stream route reports upload progress.

6. Architecture

Expand a component to follow its connections, or explore the full diagram.

System components Context
Mermaid Interactive diagram

System overview of the components and connections verified in the repository.

Static architecture view for ChitUI
Static preview. The interactive diagram replaces it after Mermaid loads.
flowchart LR

subgraph group_server["Server and discovery"]
  node_app["HTTP and Socket.IO server<br/>[main.py]"]
  node_discovery["Printer discovery<br/>[main.py]"]
  node_upload["File upload handling<br/>[main.py]"]
  node_transfer["Printer file transfer<br/>[main.py]"]
end

subgraph group_printer["Printer communication"]
  node_commands["SDCP commands<br/>[main.py]"]
  node_connection["Printer WebSocket connection<br/>[main.py]"]
end

subgraph group_webui["Browser interface"]
  node_index["Web page entry<br/>[index.html]"]
  node_ui["Printer dashboard and actions<br/>[chitui.js]"]
  node_protocol["SDCP constants<br/>[sdcp.js]"]
  node_theme["Theme preferences<br/>[color-modes.js]"]
end

node_user(("Operator"))
node_browser(("Web browser"))
node_printer["SDCP printer"]

node_user -->|"uses"| node_browser
node_browser -->|"opens interface"| node_app
node_app -->|"serves"| node_index
node_user -->|"operates"| node_ui
node_ui -->|"sends events"| node_app
node_app -->|"emits updates"| node_ui
node_app -->|"runs discovery"| node_discovery
node_discovery -->|"broadcasts discovery"| node_printer
node_app -->|"connects printers"| node_connection
node_connection -->|"opens WebSocket"| node_printer
node_app -->|"dispatches requests"| node_commands
node_commands -->|"sends SDCP"| node_printer
node_printer -->|"sends messages"| node_connection
node_connection -->|"routes printer events"| node_app
node_browser -->|"posts print file"| node_upload
node_app -->|"handles upload"| node_upload
node_upload -->|"starts transfer"| node_transfer
node_transfer -->|"uploads file"| node_printer
node_ui -->|"uses constants"| node_protocol
node_index -.->|"loads interface code"| node_ui
node_index -.->|"loads theme control"| node_theme


class node_app,node_discovery,node_upload,node_transfer,node_browser toneBlue
class node_commands,node_connection toneAmber
class node_index,node_ui,node_protocol,node_theme toneMint
class node_user,node_printer toneIndigo

A browser control panel for Chitubox SDCP 3.0 resin printers. The server discovers printers, opens WebSocket connections, routes commands and status events, and transfers uploaded print files while the browser presents printer controls.

Components
13
Connections
21
Evidence-backed links
16/21
Text version of the diagram
  • Browser UI → Flask and SocketIO
  • Flask and SocketIO → Printer discovery and session
  • Printer discovery and session → SDCP printer
  • SDCP printer → Printer discovery and session
Follow one path through the code

Follow /upload through the temporary file and the printer transfer helper. Transfer progress is global in this implementation, so simultaneous uploads would need per-job state to avoid mixing their percentages.

7. Technical dossier

Built from the source at commit a423617 (7 files). Each item comes from a pattern match in the code, so open the linked file before relying on it.

7.1. Layers and modules

Folders are sorted into layers by name, from the user interface down to data access. Because the sorting uses names only, the diagram says nothing about calls between layers.

Mermaid Layered view
flowchart TB
  subgraph L_presentation["Presentation"]
    direction TB
    presentation_0["web/js<br/>3 files"]
    presentation_1["web<br/>1 file"]
    presentation_2["web/css<br/>1 file"]
  end
  subgraph L_interface["Entry points and API"]
    direction TB
    interface_0["(root)<br/>1 file"]
  end
  subgraph L_hosting["Build, CI and hosting"]
    direction TB
    hosting_0["(root)<br/>1 file"]
  end
  L_presentation ~~~ L_interface
  L_interface ~~~ L_hosting
Modules and their main layer
ModuleLayerFilesTypesExtensions
web/jsPresentation30.js
(root)Entry points and API10.py
webPresentation10.html
web/cssPresentation10.css

7.2. C4 model

From system context to code declarations. Each level reflects the available source evidence.

UML 1 · System context
1 · System context

The widest C4 view: who uses the project and which outside systems and data stores it relies on. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
Person(P_http, "HTTP client")
System(SYS, "ChitUI", "ChitUI places a browser interface in front of SDCP resin printers")
Rel(P_http, SYS, "Uses")
@enduml
UML 2 · Containers
2 · Containers

One level closer: the parts that run separately inside the project, their main language and how calls flow between them. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
Person(P_http, "HTTP client")
System_Boundary(SYS, "ChitUI") {
  Container(APP, "ChitUI", "JavaScript")
}
Rel(P_http, APP, "Uses")
@enduml
UML 3 · Components and layers
3 · Components and layers

Modules grouped by source-layer classification. Boundaries show organization, not runtime isolation or call relationships. Rendered with uml-mcp.

PlantUML source
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "ChitUI") {
Boundary(L0, "Presentation", "layer") {
Component(M0_0, "web/js", "JavaScript", "6 files")
Component(M0_1, "web/css", ".css", "3 files")
Component(M0_2, "web", "HTML", "1 files")
}
Boundary(L1, "Entry points and API", "layer") {
Component(M1_0, "(root)", "Python", "1 files")
}
Boundary(L2, "Build, CI and hosting", "layer") {
Component(M2_0, "(root)", "Dockerfile", "1 files")
}
}
@enduml
UML 4 · Code
4 · Code

Selected declarations, fields and methods grouped by source file. No inheritance or call edges are inferred. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "ChitUI" {
object "main.py" as FN0 {
  web_index()
  progress()
  publish_progress()
  get_upload_progress()
  upload_file()
  allowed_file()
}
}
@enduml

7.3. Data flow

The calls from the GitDiagram graph, in the order you meet them from the entry points. GitDiagram generates the graph with AI; the file paths it cites were checked against the repository tree.

Mermaid Sequence diagram
sequenceDiagram
  autonumber
  participant P0 as Operator
  participant P1 as Web browser
  participant P2 as Printer dashboard and actions
  participant P3 as HTTP and Socket.IO server
  participant P4 as File upload handling
  participant P5 as SDCP constants
  participant P6 as Web page entry
  participant P7 as Printer discovery
  participant P8 as Printer WebSocket connection
  participant P9 as SDCP commands
  participant P10 as Printer file transfer
  participant P11 as Theme preferences
  participant P12 as SDCP printer
  P0->>P1: uses
  P0->>P2: operates
  P1->>P3: opens interface
  P1->>P4: posts print file
  P2->>P3: sends events
  P2->>P5: uses constants
  P3->>P6: serves
  P3->>P2: emits updates
  P3->>P7: runs discovery
  P3->>P8: connects printers
  P3->>P9: dispatches requests
  P3->>P4: handles upload
  P4->>P10: starts transfer
  P6--)P2: loads interface code
  P6--)P11: loads theme control
  P7->>P12: broadcasts discovery
Steps as text
  1. Operator to Web browser uses
  2. Operator to Printer dashboard and actions operates
  3. Web browser to HTTP and Socket.IO server opens interface
  4. Web browser to File upload handling posts print file
  5. Printer dashboard and actions to HTTP and Socket.IO server sends events
  6. Printer dashboard and actions to SDCP constants uses constants
  7. HTTP and Socket.IO server to Web page entry serves
  8. HTTP and Socket.IO server to Printer dashboard and actions emits updates
  9. HTTP and Socket.IO server to Printer discovery runs discovery
  10. HTTP and Socket.IO server to Printer WebSocket connection connects printers
  11. HTTP and Socket.IO server to SDCP commands dispatches requests
  12. HTTP and Socket.IO server to File upload handling handles upload
  13. File upload handling to Printer file transfer starts transfer
  14. Web page entry to Printer dashboard and actions loads interface code
  15. Web page entry to Theme preferences loads theme control
  16. Printer discovery to SDCP printer broadcasts discovery
  17. Printer WebSocket connection to SDCP printer opens WebSocket
  18. Printer WebSocket connection to HTTP and Socket.IO server routes printer events
  19. SDCP commands to SDCP printer sends SDCP
  20. Printer file transfer to SDCP printer uploads file
  21. SDCP printer to Printer WebSocket connection sends messages

7.4. Public interface

Outside code can use everything listed here. The project also declares 0 public types.

UML Use cases
Use cases

Each actor is a kind of caller, linked to what it can ask the project to do. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
left to right direction
actor "HTTP client" as A_http
rectangle "ChitUI" {
  usecase "ANY /" as U0
  usecase "ANY /progress" as U1
  usecase "ANY /upload" as U2
}
A_http --> U0
A_http --> U1
A_http --> U2
@enduml

HTTP routes 3

Mermaid Route map by prefix
flowchart LR
  api(["HTTP API"])
  g0["/"]
  api --> g0
  g0r0["ANY /"]
  g0 --> g0r0
  g1["/progress"]
  api --> g1
  g1r0["ANY /progress"]
  g1 --> g1r0
  g2["/upload"]
  api --> g2
  g2r0["ANY /upload"]
  g2 --> g2r0
MethodPathSource
ANY/main.py:43
ANY/progressmain.py:48
ANY/uploadmain.py:61

Entry points

7.5. Business logic

No classes were extracted, so these are the largest source files and their functions.

main.py
web_index, progress, publish_progress, get_upload_progress, upload_file, allowed_file

7.6. Database and persistence

7.7. External integrations

HTTP clients

requests

7.8. Stack and dependencies

Python requirements.txt 5 runtime

Open the manifest

External dependencies

5 declared packages (5 runtime, 0 development) in requirements.txt.

Package table 5
External dependencies
PackageVersionScopePurposeRegistry
flask==3.0.3runtimeWeb frameworkpypi.org
flask-socketio==5.4.1runtimeWeb frameworkpypi.org
websocket-client==1.8.0runtimeReal-time messagingpypi.org
requests==2.32.3runtimeHTTP clientpypi.org
loguru==0.7.2runtimeLogging and observabilitypypi.org

7.9. CI/CD pipeline

No CI/CD pipeline in the repository apart from GitLab CI. The code is built and run by hand, as described above.

7.10. Deployment

Mermaid Deployment diagram
flowchart LR
  repo[("GitHub repository")]
  ci_GitLab_CI[["GitLab CI"]]
  image["Docker image<br/>FROM python:3.12-alpine"]
  repo --> ci_GitLab_CI
  repo -->|"docker build"| image
UML Deployment
Deployment

The outer node is where the code runs. Each base image points to what it builds, solid arrows lead to databases and dashed ones to outside services. Rendered with uml-mcp.

PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Docker image" as H {
  artifact "ChitUI" as APP
}
artifact "FROM python:3.12-alpine" as IMG0
IMG0 ..> APP : builds
cloud "WebSocket" as E0
APP ..> E0
@enduml

Where it runs

Docker base images

python:3.12-alpine

7.11. Monitoring

What the code logs, measures and exposes to tell whether it is working.

7.12. Security

Environment variables 2

The page lists names without their values and underlines the ones that look like secrets.

PORT DEBUG

Nothing found for: Private interface, Services, Entities, Testing.

8. Workflow

Step-by-step view of the path inspected in the repository. This is not a live run.

9. Printer upload API

POST /upload accepts multipart fields file and printer. The printer identifier selects an entry in the discovered-printers dictionary. Supported extensions are ctb, goo and prz. The server stores a temporary file and transfers chunks to the printer’s port 3030 upload endpoint.

Access checks read from the handlers. A README label of admin appears here only when the code checks it.
MethodPathVerified access checkFile
POST/uploadNo authentication check in the inspected handler. Multipart fields file and printer are required.main.py
GET/uploadNo authentication check. The inspected handler returns 405.main.py
GET/progressNo authentication check in the inspected handler. The response is a text/event-stream shared across uploads.main.py
Request example
POST /upload
Content-Type: multipart/form-data

file: [supported print file]
printer: [identifier returned by discovery]

9.1. Response and errors

The success body is {“upload”:“success”,“msg”:“File uploaded”}. Missing file or printer fields and unsupported extensions return 400. GET /upload returns 405. GET /progress streams text/event-stream updates.
Verify the file on the printer after a transfer. The helper sets progress to 100 and returns true even after a failed part causes the loop to break. A success response alone therefore does not prove delivery. The calculation also divides by the number of whole 1 MiB chunks, which is zero for files smaller than 1 MiB.
Authentication, limits and pagination

The inspected handlers have no authentication or rate limiter. Keep this interface on a trusted network. Progress is shared globally across uploads, so it cannot identify concurrent jobs. Pagination does not apply to this upload operation.

10. Deployment and operations

The ports, storage, and startup relationships below come from the repository configuration. depends_on records startup order, not service readiness.

Network. Host network (--net=host), requested in the README so UDP broadcast can reach the LAN.

11. Reference

6 / 6 eligible files read (31 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.

What the scan covers

Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.

Linguist statistics cover the whole repository and may include other languages.

13. Files to read 3

14. Glossary

Repository

The versioned source files, configuration, and history of a project.

README

The repository’s entry document, usually covering its purpose and initial setup.

Dependency

A library, tool, or service that another component needs to build or run.

HTTP

A request-and-response protocol used by browsers and web services. A method, path, headers, and optional body describe a request.

Session

State kept across related requests, often to track a signed-in user. Authentication and permission checks remain separate concerns.

Container

An isolated process environment created from an image. Persistent data needs storage outside the container’s disposable filesystem.

Published port

A host port mapped to a service’s container port. Publishing a port can expose that service beyond its container network.

CLI

A text interface in which commands and arguments select operations. Exit codes let scripts detect success or failure.

Build

The steps that turn source files and dependencies into a runnable program or distributable artifact.

15. References

  1. antoinebou12. (2026, November 5). ChitUI. [Software repository] github.com.
  2. antoinebou12. (2026, November 5). ChitUI: README. [Repository documentation] github.com.
  3. antoinebou12. (2026, November 5). main.py. [Source file] github.com.
  4. antoinebou12. (2026, November 5). Dockerfile. [Source file] github.com.
  5. antoinebou12. (2026, November 5). requirements.txt. [Source file] github.com.
  6. Boucher, A. (2026, October 23). ChitUI: A local bridge to resin printers. [Project article] antoineboucher.info.

Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.