Types and Nodes#
Every procedure in CaptureGraph has a return type and fits into a node category. Understanding these is essential for building valid workflows.
The PType System#
Every procedure returns a PType:
import capturegraph.procedures as cgp
image: cgp.Procedure[cgp.PImage] = cgp.CaptureImage(label="Take a photo")
text: cgp.Procedure[cgp.PString] = cgp.UserInputString(label="Enter notes")
flag: cgp.Procedure[cgp.PBool] = cgp.UserInputBool(label="Is this correct?")
Note: You always work with
Procedure[PType]objects, not rawPTypevalues. The procedure represents the node that will produce the value at runtime.
Common PTypes#
| Type | Description | Example |
|---|---|---|
PImage |
Photo or image data | cgp.CaptureImage() |
PString |
Text data | cgp.UserInputString() |
PNumber |
Numeric value | cgp.UserInputNumber() |
PBool |
Boolean flag | cgp.UserInputBool() |
PLocation |
GPS coordinates | cgp.CaptureLocation() |
PDirectory |
Directory reference | cgp.GetRootDirectory() |
PFile |
File reference | session.new_file("x") |
PVoid |
No return value | session.new_file("x").save(...) |
PVoid and ProcedureSequence#
ProcedureSequence chains multiple procedures together. All sub-procedures must return PVoid:
return cgp.ProcedureSequence(
label="My Workflow",
procedures=[
# .save() returns PVoid ✓
session.new_file("photo").save(cgp.CaptureImage()),
session.new_file("notes").save(cgp.UserInputString(label="Notes")),
]
)
If you accidentally use a procedure that returns data instead of PVoid:
cgp.ProcedureSequence(
procedures=[
# .cache() returns PImage, not PVoid ✗
session.new_file("photo").cache(cgp.CaptureImage()),
]
)
You'll get a clear error:
TypeError: Substeps for 'ProcedureSequence' must return 'PVoid',
but 'CacheProcedureToFile' returns 'PImage' instead.
Node Taxonomy#
Nodes are categorized by their runtime behavior:
Automatic Nodes (Invisible)#
Execute instantly without user interaction:
- Control:
cgp.IfThenElse,cgp.switch_case - Operators:
cgp.BoolAnd, comparisons - Constants:
cgp.ConstantString,cgp.ConstantNumber,cgp.ConstantBool - Conversions:
cgp.ConvertImageToThumbnail - Structural:
cgp.ProcedureSequence,cgp.ProcedureSet
These handle computation and logic—users never see them directly. See the Automatic Nodes API.
Action Nodes (Visible)#
Block execution until user input is provided:
- Capture:
cgp.CaptureImage,cgp.CaptureLocation,cgp.CaptureImageSequence - User Input:
cgp.UserInputString,cgp.UserInputNumber,cgp.UserInputBool,cgp.UserInputOptimalSolarTime
These render UI elements in the app. See the Action Nodes API.
Storage Nodes#
Handle file system operations. See the Filesystem Nodes API.
- Create:
cgp.NewFile,cgp.NewDirectory,cgp.NewSessionDirectory - Save:
cgp.CacheProcedureToFile - Load: File
.load()method
Labels#
Any node can have a label parameter, but only Action Nodes display it to users:
# Label shown to user
cgp.CaptureImage(label="Take the daily photo")
# Label used for debugging only
cgp.ConvertImageToThumbnail(label="generate thumbnail", image=photo)
Keyword Arguments#
All procedure parameters must be keyword arguments:
# ✗ Wrong - positional argument
cgp.ProcedureSequence([
session.new_file("photo").save(image),
])
# ✓ Correct - keyword argument
cgp.ProcedureSequence(
procedures=[
session.new_file("photo").save(image),
]
)
This ensures clarity and prevents parameter ordering mistakes.
Type Validation#
Type checking happens at three stages:
- Static analysis via Python type hints
- Runtime via
__post_init__validation - Device execution in the iOS app
This catches errors before they reach the device, speeding up development.
See Also#
- Fluent API —
.save(),.cache(),.load()method chaining - Targets and Sessions — File system organization
- Control Flow — Conditional logic and operators
- Full Types API — Complete PType reference
- Full Nodes API — All available nodes