Flow 코드와 PXFLOW Studio의 관계
pipelinexlab SDK 하나에서 계산 구조는 px.Flow, 문서는 px.Report로 작성합니다. Python에서 시작한 SDK-linked Flow는 Python source와 dependency lock이 편집 원본이고, PXFLOW Studio는 여기서 검증해 만든 Flow revision을 엽니다. 화면에서 시작한 PXFLOW-native Flow는 .pxflow revision이 편집 원본입니다. Report는 어느 방식으로 시작해도 저장된 .pxreport revision이 문서 원본입니다.
현재 Component 구현 경계
현재 공개 Python facade는 px.component, px.Results, px.Record, px.Settings와 marker px.input, px.result, px.setting을 제공합니다. target port의 type은 일반 Python parameter annotation과 px.Results의 annotated field가 정하고, marker가 그 선언부에 description·unit을 더합니다. px.setting 문법은 component-declared-settings@1이 소유합니다. decorator @px.record, px.field와 px.Table은 contract_only 계획 이름입니다.
@px.component 등록은 portable declaration·executor package를 자동 생성하지 않습니다. 현재 V1의 기존 presentation·settings wire는 호환을 위해 보존하고 production Flow reader는 이미 저장된 Component target을 read-only unsupported로 표시합니다. current internal/test resolver primitive는 live px.Client로 exact ComponentRef를 저장하는 내부 경로입니다. exact ProjectScope data-path isolation은 구현됐지만 신규 install·placement·activation의 제품 노출은 Project authorization과 execution-trust closure가 닫힌 뒤에만 엽니다. 후속 V2 Canvas는 package UI를 마운트하지 않고 host-owned component.declarative@2만 사용합니다. settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich surface는 RFC-016이 소유하는 component-rich-surface-declaration@1 범위이고, bridge는 Node context 읽기와 settings 제안까지만 허용합니다. 해당 화면 이미지는 계획된 제품 흐름의 prototype입니다.
| 만들려는 것 | Python에서 시작 | 화면에서 시작 | 저장 문서 |
|---|---|---|---|
| Node와 연결로 이루어진 계산 | px.Flow(...) | PXFLOW Studio | SDK-linked: Python source · PXFLOW-native: .pxflow |
| 본문·값·표와 Flow 결과를 담는 문서 | px.Report(...) | Report Workbench | .pxreport |
Python을 사용하지 않아도 두 화면에서 같은 작업을 시작할 수 있습니다. Python으로 전체 과정을 먼저 보려면 Report와 Flow 함께 만들기를, API 이름을 바로 찾으려면 Python SDK API reference를 여세요. 이 페이지의 아래 내용은 px.Flow와 PXFLOW Studio Canvas가 1:1로 대응하는 방식을 자세히 설명합니다.
px.와 flow.를 함께 쓰는 이유
SDK는 from pipelinexlab import px 하나로 시작합니다. px.Flow(...)는 새 Flow를 만들고, 그 다음부터 flow.input(...), flow.node(...), flow.connect(...), flow.result(...)가 그 Flow의 Canvas 내용을 구성합니다.
from pipelinexlab import px
from bridge_checks import check_capacity
flow = px.Flow(
"strength_check",
label="Strength check",
description="Checks the applied load against member capacity.",
)
load = flow.input(
"load",
float,
unit="kN",
description="Applied design load.",
)
check = flow.node("capacity_check", check_capacity)
flow.connect(load, check.inputs.load)
flow.result("utilization", check.results.utilization)px.는 SDK에서 새로 만드는 타입과 계약을 빠르게 찾게 해 줍니다. flow.는 지금 수정하는 Flow를 정확히 가리킵니다. 한 Flow authoring module은 public Flow 객체 하나만 export합니다. 추가 Flow는 별도 module에서 작성해 import합니다. 같은 파일에는 public Flow 하나와 public Report 하나를 함께 둘 수 있으며, Report는 px.Report(...)를 만든 뒤 report.section(...)과 report.connect_flow(...)로 작성합니다.
전체 namespace 표와 Report·실행 예제 보기
코드가 Canvas에 나타나는 순서
Python에서 작성한 Flow는 다음 순서로 PXFLOW Studio의 같은 Flow가 됩니다.
변환 과정과 host projection 계약이 필요한 개발자는 SDK 문법과 materialize 규격을 확인하세요.
SDK에서 Studio 연결선을 만드는 방법
SDK의 flow.connect(source, destination) 호출 하나가 Flow의 연결 하나를 정의합니다. source에는 Flow input이나 앞 Node의 result port를, destination에는 다음 Node의 input port를 지정합니다. PXFLOW Studio는 같은 연결을 두 port 사이의 선으로 표시합니다. flow.result(...)는 Node 사이의 연결이 아니라 Node result를 Flow 바깥에 공개하는 result binding입니다.
같은 structured public input을 여러 Node에 전달하면 연결의 의미와 주소는 그대로 각각 유지됩니다. Canvas는 복잡도를 낮추기 위해 이 반복선을 boundary band의 binding count로 묶어 표시할 수 있습니다. 이 표시는 연결을 합치는 동작이 아니며, Python에서는 각 flow.connect(...) 선언을 그대로 확인하고 이동할 수 있습니다.
from pipelinexlab import px
class EffectResults(px.Results):
effect: float
@px.function(
key="calculate_effect",
version="1.0.0",
description="Calculates a factored load effect.",
)
def calculate_effect(load: float) -> EffectResults:
return EffectResults(effect=load * 1.2)
class SafetyResults(px.Results):
utilization: float
@px.function(
key="check_safety",
version="1.0.0",
description="Checks a factored effect against capacity.",
)
def check_safety(effect: float) -> SafetyResults:
return SafetyResults(utilization=effect / 100.0)
flow = px.Flow(
"load_check",
label="Load check",
description="Calculates one load utilization.",
)
load = flow.input("load", float, unit="kN", description="Applied load.")
effect = flow.node("load_effect", calculate_effect)
check = flow.node("safety_check", check_safety)
flow.connect(load, effect.inputs.load)
flow.connect(effect.results.effect, check.inputs.effect)
flow.result("utilization", check.results.utilization)| SDK 표현 | Studio Canvas |
|---|---|
flow.input("load", ...) | Flow 경계의 load input port |
flow.node("load_effect", ...) | load_effect Node |
effect.results.effect | load_effect의 오른쪽 result port |
check.inputs.effect | safety_check의 왼쪽 input port |
flow.connect(source, destination) | type과 unit을 확인하는 두 port 사이 연결선 |
flow.result("utilization", ...) | Flow 경계에 공개된 utilization result |
source에는 Flow input 또는 앞 Node의 results.<portKey>를, destination에는 다음 Node의 inputs.<portKey>를 사용합니다. 코드가 가리키는 port와 Canvas에서 선을 잇는 port가 같으므로 Studio가 type과 unit을 같은 기준으로 검증합니다.
Report에서 이 Flow를 사용하는 방법
SDK와 Studio는 Flow의 계산 구조를 작성합니다. Report Workbench 또는 px.Report는 Report 값을 어느 Flow input에 보내고 Flow result를 어디에 표시할지 작성합니다.
Python에서는 먼저 report = px.Report(...)로 Report 객체를 만들고, connection = report.connect_flow(...)로 Connected Flow handle을 받습니다. 아래 표의 .bind()와 .show()는 이 connection handle에서 호출합니다.
| 관계 | 정의·편집 위치 | 저장 위치 |
|---|---|---|
| Flow public input | SDK의 flow.input(...) 또는 Studio의 Flow input | owning SDK source 또는 .pxflow |
| Flow 내부 port 연결 | SDK의 flow.connect(...) 또는 Studio Canvas 연결선 | owning SDK source 또는 .pxflow |
| Flow public result | SDK의 flow.result(...) 또는 Studio의 Flow result | owning SDK source 또는 .pxflow |
| Report 작성값 → Flow input | Workbench의 Use report input 또는 Connected Flow handle의 .bind() | .pxreport |
| Flow result → Report 위치 | Workbench의 Show result 또는 Connected Flow handle의 .show() | .pxreport |
Report에서 연결을 추가하면 저장한 Flow의 public port 계약을 선택하고 .pxreport mapping을 갱신합니다. SDK-linked Flow의 Python source와 Flow 내부 Canvas 연결은 그대로 유지됩니다. 따라서 같은 Flow를 여러 Report에서 서로 다른 작성값과 결과 위치로 재사용할 수 있습니다.
Report의 연결 확인 화면에서는 public input부터 내부 Node를 거쳐 public result까지의 경로를 읽기 전용으로 확인하고, Open in PXFLOW Studio로 Flow 편집 화면을 엽니다. 실제 연결 순서는 Report에서 Flow 입력과 결과 연결하기, 정확한 저장 계약은 Report↔Flow 연결 명세에서 이어집니다.
Decorator를 고르는 기준
Canvas에서 실행되는 계산은 @px.function으로 정의합니다. 이 규칙은 현재 Project에서 한 번만 쓰는 계산과 여러 Flow가 공유하는 계산에 똑같이 적용됩니다. 계산 안에서만 쓰는 작은 도우미는 일반 Python def로 작성해 Function body에서 호출합니다. 현재 @px.component는 process-local companion metadata target만 등록하며 installed release를 resolve하거나 durable ComponentRef를 만들지 않습니다. 저장돼 있던 exact Component target은 read-only unsupported로 보존합니다. 후속 V2 Node 화면은 host-owned component.declarative@2만 사용하고 instance settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다.
| 필요한 범위 | 작성 방식 | Studio에서 배치한 모습 |
|---|---|---|
| Canvas에서 실행할 계산 | @px.function(key=..., version=..., description=...) | Function Reference Node |
| 두 P0 closure 뒤 admitted Component release를 exact ref로 배치 | @px.component companion target | current production에서는 새 배치 없음; successor에서 exact ComponentRef |
| 후속 V2 Component Canvas UI | host-owned component.declarative@2 · contract_only | 공통 host Node surface |
| Component settings | px.Settings subclass의 px.setting(...) field | host control registry가 그리는 control |
| rich surface | component-rich-surface-declaration@1 선언 | RFC-016이 소유하는 격리 editor |
| Function·Component 내부에서만 쓰는 계산 도우미 | 일반 Python def | Canvas에는 별도 Node로 나타나지 않음 |
| Record·App·문서 template 같은 schema·surface | 해당 definition decorator | Definitions·schema·전용 surface에서 사용 |
Decorator의 key가 이름·계약·검색·version 관리의 기준이 됩니다. current production에서는 @px.function target을 flow.node("node_key", target)에 전달해 새 Node를 배치하고 포트 관계를 flow.connect(...)로 명시합니다. Component에 같은 spelling을 쓰는 제품 경로는 두 P0 closure 뒤에만 노출됩니다. Decorator 전체 계약 보기
SDK와 Definitions UI
각 항목을 선택하면 해당 문법, 화면 또는 다음 동작의 상세 설명으로 이동합니다.
| 위치 | 여기서 하는 일 | 다음 화면 |
|---|---|---|
| Python source·IDE | @px.function, @px.component, 내부 helper와 px.Flow 작성 | pxlab studio open으로 같은 Project·Flow 열기 |
| PXFLOW Studio Definitions → Functions | 공유 Function의 source, contract, version과 사용처 확인 | Place Node로 Canvas 배치 |
| PXFLOW Studio Components dock · 계획 | post-closure admitted Component 검색 | 두 P0 closure 뒤 Add로 Canvas 배치 |
| host-owned V2 Node · 계획 | exact identity와 declared Port 확인 | Validate 후 저장 |
Function의 작성 원본은 SDK source 또는 owning package이며 현재 Definitions에서 계약을 확인한 뒤 Flow에 배치합니다. Component의 owning package·Components 탐색·신규 배치는 post-closure 제품 경로입니다. current reader는 저장된 exact target만 unsupported로 복구합니다. 전체 제품 이동은 제품 연결과 화면 위치를 확인하세요.
| Python에서 작성 | 화면에서 찾는 이름 | Flow에 나타나는 시점 |
|---|---|---|
일반 Python def | Function은 helpers=[...]로 선언, Component는 module 내부 helper | Canvas에 별도 Node로 나타나지 않음 |
@px.function | Definitions → Functions의 Function | Place Node 또는 flow.node(...)로 배치할 때 Function Reference Node가 생김 |
Component package의 public module에서 @px.component import | post-closure admitted Component resolver target | current production에서는 새 third-party placement 없음; successor에서 flow.node(...)가 exact ComponentRef 저장 |
flow = px.Flow(...) | Flow | Studio에서 같은 Flow 열기 후 Node와 연결을 확인 |
계획된 Component package와 더 넓은 Extension의 분류는 Extensions와 Integrations에서 비교합니다. 현재 저장된 Component의 read-only 복구 경계와 post-closure 설치·배치 계약은 Components 사용하기에서 구분해 확인합니다. Extension 전용 SDK 문법과 artifact 계약은 카탈로그에서 연결되는 각 상세 문서가 설명합니다.
Function을 현재 Flow에 배치하면 Canvas Node가 생깁니다. Component는 이미 저장된 exact target만 current production Canvas에서 read-only unsupported로 표시됩니다. 새 exact target을 문서에 저장하는 제품 placement는 post-closure입니다.
Function을 만들고 Flow에 배치하기
화면에서는 Function이라고 부릅니다. SDK/API 기술 이름은 FunctionDescriptor입니다. 재사용 Function 하나를 Definitions, PXFLOW와 Runtime이 같은 기능으로 이해하도록 만든 이름·version·input/result 설명입니다. Canvas Node는 이 Function을 flow.node(...)로 배치할 때 생성됩니다.
Python source에 @px.function을 작성하면 build/materialize가 FunctionDescriptor를 생성합니다. Definitions → Functions에서 생성된 계약을 확인하고 Place Node를 누르면 현재 Flow에 Function Reference Node가 배치됩니다.
SDK에서는 Function을 한 번 정의하고, 사용할 Flow에서 import한 symbol을 flow.node(...)의 target으로 배치합니다. Function decorator는 재사용 정의를 등록하고 Flow의 top-level 선언이 실제 사용처와 연결을 만듭니다.
작성 원본은 Function을 소유한 Python SDK source입니다. 화면에서는 Project Definitions → Functions에서 계약·version·사용처를 확인하고 Place Node로 배치하며, 배치된 Node modal의 Function source는 읽기 전용으로 표시합니다.
Function 제공자의 SDK source:
from pipelinexlab import px
class GirderResults(px.Results):
utilization: float
@px.function(
key="girder_utilization",
version="1.0.0",
description="Calculates girder utilization from span and design moment.",
)
def girder_utilization(span: float, design_moment: float) -> GirderResults:
resistance = span * 100.0
return GirderResults(utilization=design_moment / resistance)위 코드에서 함수 본문의 두 줄이 실제 계산입니다. -> GirderResults는 결과값을 함수 끝에 붙여 보내는 문법이 아니라 반환할 result 묶음의 타입 계약이고, return GirderResults(utilization=...)가 계산한 값을 이름 있는 utilization port에 담습니다. Studio는 Python 문장마다 Node를 만들지 않고 이 Function 전체를 Reference Node 하나로 표시합니다.
설치한 package를 사용하는 Flow source:
from pipelinexlab import px
from structural_checks import girder_utilization
flow = px.Flow(
"girder_review",
label="Girder utilization",
description="Checks one girder design case.",
)
span = flow.input("span", float, unit="m", description="Clear span.")
design_moment = flow.input(
"design_moment",
float,
unit="kN.m",
description="Factored design bending moment.",
)
utilization_check = flow.node("utilization_check", girder_utilization)
flow.connect(span, utilization_check.inputs.span)
flow.connect(design_moment, utilization_check.inputs.design_moment)
flow.result("utilization", utilization_check.results.utilization)이 계산식은 SDK 연결을 설명하는 Quickstart 예제입니다. 실제 package에는 검증된 공학 계산과 허용오차 시험을 사용합니다.
girder_utilization · 1.0.0이 FunctionDescriptor이고, utilization_check는 그 Function을 girder_review Flow에 배치한 Function Reference Node입니다. SDK source에서는 @px.function을 편집하고, 화면에서는 Project Definitions → Functions에서 같은 계약과 사용처를 확인합니다.
Project Definitions의 Contract & usage — girder_utilization · 1.0.0의 span, design_moment와 utilization 계약을 배치 전에 확인합니다.
| 구분 | FunctionDescriptor | Canvas Node |
|---|---|---|
| 사용자에게 보이는 이름 | girder_utilization · 1.0.0 | utilization_check |
| 뜻 | 여러 곳에서 공유하는 Function 정의와 계약 | 특정 Flow에 배치한 한 사용처 |
| 포함하는 것 | package/function/version, 설명, input/result type·unit, capability와 실행 정책 | nodeKey, 위치, binding과 exact Function ref |
| 편집 위치 | Definitions → Functions → Open source로 여는 owning SDK source | Node modal의 표시 이름·연결; Function source는 읽기 전용 |
| 변경 영향 | source 변경은 새 Function version 후보가 되며, 영향 분석 뒤 승인한 사용처 ref를 새 Flow revision에서 함께 갱신 | 이 Node의 배치·연결만 변경 |
화면에서는 이 객체를 Function으로 표시하고, SDK·API 명세에서 정확한 생성 계약을 가리킬 때 FunctionDescriptor라는 이름을 사용합니다.
- Definitions → Functions에서 Function을 선택합니다.
- Contract & usage에서 version, input/result, type·unit과 사용 중인 Node를 확인합니다.
- Place Node를 눌러 현재 Flow의 고유한
nodeKey를 정합니다. - 공유 Function source를 바꾸면 기존 version을 덮어쓰지 않고 새 Function version 후보를 만듭니다. 모든 사용처의 영향을 보여 준 뒤 승인한 Node ref를 새 Flow revision에서 함께 갱신합니다. 특정 Node만 다르게 만들려면 Function을 Duplicate / branch하고 그 Node만 새 Function ref로 바꿉니다.
Component target 등록과 후속 V2 host surface
현재 Component authoring facade의 @px.component는 재사용 target의 key, label, description, 선택적 category와 Python annotation에서 읽은 port shape를 process-local registry에 등록합니다. 이 등록만으로 portable Component declaration, executor entry, signed package나 전용 화면이 생성되지는 않습니다. 설치된 declaration과 executor container는 별도 artifact 계약을 따릅니다.
현재 installer는 trust authority가 없을 때 signed Component를 기록 전에 거부하고, 명시적으로 수용한 unsigned Component만 absent·not-checked로 기록합니다. 현재 production은 새 third-party Component placement를 제공하지 않고, 저장돼 있던 exact ComponentRef만 read-only unsupported로 보존합니다. current internal/test primitive에서는 live px.Client가 같은 Project의 exact release resolver를 호출해 ComponentRef를 저장할 수 있습니다. exact ProjectScope data-path isolation은 구현됐지만 Project authorization과 execution-trust closure가 닫히지 않았으므로 caller/release policy가 이 primitive를 production third-party install·placement·activation 경로로 노출하지 않습니다. 남은 closure 뒤 제품 노출이 successor semantics입니다. 후속 V2 Canvas는 host-owned component.declarative@2만 사용하며 package renderer·modal·settings schema를 받지 않습니다. 현재 Project에서 직접 작성하는 계산은 @px.function으로 정의한 뒤 flow.node(...)로 배치합니다. 일반 Python def는 내부 helper로 사용합니다. Function이 부르는 helper는 @px.function(..., helpers=[...])로 선언해야 그 Function revision에 저장되어 실행 시 존재합니다.
아래 ModelRef, ModelSelection과 display_model은 이 package가 함께 제공하는 domain type/runtime helper입니다. 실제 source에서는 package의 public module에 정의하거나 그 module의 공개 경로에서 import합니다.
Component package 제공자 · model_view_pack/components.py
from pipelinexlab import px
class ModelViewerResults(px.Results):
selection: str
@px.component(
key="model_viewer",
label="Model viewer",
description="Displays a connected MIDAS Civil model.",
category="review",
subcategory="model",
)
def model_viewer(
model: str,
) -> ModelViewerResults:
... # companion descriptor symbol; executor is packaged separately아래 Flow 코드는 post-closure 제품 authoring shape를 설명하는 contract_only 예제입니다. 제품 경로가 열린 뒤 같은 public target을 Node 하나로 배치하고 input을 명시적으로 연결합니다. 현재 설치·배치 절차와 internal/test resolver primitive 호출은 이 예제 범위 밖입니다.
from pipelinexlab import px
from model_view_pack.components import model_viewer
flow = px.Flow(
"model_review",
label="Model review",
description="Displays a model and exposes the current selection.",
)
model = flow.input("model", str, description="Model reference to display.")
view = flow.node(
"model_view",
model_viewer,
)
flow.connect(model, view.inputs.model)
flow.result("selection", view.results.selection)| 확인할 것 | SDK source | PXFLOW Studio |
|---|---|---|
| current companion definition | package module의 @px.component symbol model_viewer | process-local metadata와 port shape 확인 |
| current saved 사용처 | 이미 저장된 exact ComponentRef | read-only unsupported |
| post-closure 신규 사용처 | flow.node("model_view", ...) · contract_only | admitted exact ComponentRef 저장 |
| current input/result | Python parameter annotation, px.Results annotated field | 저장된 declaration과 key parity 확인 |
| 후속 V2 presentation | host-owned component.declarative@2 | 공통 Node shell·Port · 계획 |
| V2 settings | component-declared-settings@1 · 선언당 최대 8개 | host control registry가 그리는 control |
| rich surface | component-rich-surface-declaration@1 선언 | RFC-016이 소유하는 격리 editor |
계획 prototype — Components dock에서 package가 제공하는 Component를 고르고 이름과 Port를 확인하는 목표 흐름입니다. V2 Canvas는 host-owned component.declarative@2으로만 배치하며 이 이미지는 package Settings나 editor를 약속하지 않습니다.
FunctionDescriptor는 여러 Flow에서 공유할 계산 기능의 계약입니다. 계획된 full ComponentDescriptor는 typed port·result와 제한된 host presentation metadata를 소유하고, Node body는 host-owned component.declarative@2이 그 projection으로 그립니다. setting은 별도 versioned settings 계약 전에는 소유하지 않으며 rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유합니다. 현재 decorator는 local companion metadata만 등록하며 durable ComponentRef를 만들지 않습니다. current internal/test resolver primitive가 exact ref를 저장하는 범위는 내부 절차로 유지합니다. 두 P0 closure 뒤 successor에서만 explicit flow.node(...) Component placement를 제품에 노출합니다.
Extension 전용 SDK 문법은 해당 Extension의 template·artifact 구성을 작성합니다. Component package target을 flow.node(...)로 신규 배치해 exact ref를 저장하는 제품 경로는 post-closure이고, current reader는 이미 저장된 exact ref만 unsupported로 표시합니다.
SDK로 만든 Flow를 PXFLOW Studio에서 확인·편집하기
화면에서는 Flow라고 부릅니다. SDK/API 기술 이름은 FlowDocument입니다. Flow input/result, 배치한 Node, input binding, Group과 화면 배치를 함께 가진 실행 가능한 계산 흐름입니다. SDK에서는 한 .py module이 module-level flow = px.Flow(...) 하나를 export하고, 각 flow.node(...)가 Canvas Node 하나를 만듭니다. 복잡한 Flow도 top-level 선언을 이어서 작성합니다.
같은 Flow는 PXFLOW Studio의 Canvas에서 열립니다. sdkLinked에서는 Python source, pxflowNative에서는 .pxflow가 편집 원본이며 Studio는 그 원본에 적용될 변경을 보여 준 뒤 저장합니다.
from pipelinexlab import px
from structural_checks import girder_utilization
flow = px.Flow(
"girder_review",
label="Girder utilization",
description="Checks one girder design case.",
)
span = flow.input("span", float, unit="m", description="Clear span.")
design_moment = flow.input(
"design_moment",
float,
unit="kN.m",
description="Factored design bending moment.",
)
utilization_check = flow.node("utilization_check", girder_utilization)
flow.connect(span, utilization_check.inputs.span)
flow.connect(design_moment, utilization_check.inputs.design_moment)
flow.result("utilization", utilization_check.results.utilization)| SDK에 작성한 것 | Canvas에서 보이는 것 |
|---|---|
flow = px.Flow("girder_review", ...) | Flow 하나와 검증·실행에 쓰는 SDK-linked direct projection |
flow.input(...)의 span, design_moment | 공개 Flow input |
flow.node("utilization_check", ...) | Function Reference Node 하나 |
두 flow.connect(...) 호출 | Flow input에서 Node input으로 가는 typed 연결 |
flow.result("utilization", ...) | 공개 Flow result |
PXFLOW Studio — FlowDocument의 Node와 연결을 Canvas에서 확인하고 Validate → Save → Run 상태를 읽습니다.
SDK-linked Flow는 Python source가 편집 원본이고 Studio 변경은 source diff를 검토한 뒤 적용합니다. PXFLOW-native Flow는 .pxflow가 편집 원본입니다. 현재 새 Function placement는 exact Function target을 참조하고, 이미 저장된 Component Node의 exact target은 read-only unsupported로 보존합니다. FlowGroup은 이 Flow 안의 Node membership을 맡고 실행 target과 revision은 현재 FlowDocument가 계속 소유합니다.
같은 Flow를 Visual 또는 Python으로 편집하기
SDK-linked Flow를 열고 상단에서 Flow를 선택하면 Visual / Python 전환이 나타납니다. 작업 방식에 맞춰 둘 중 하나를 선택합니다. Python에서는 한 Flow module 안에 public input, Node 배치, typed 연결과 public result를 모두 작성할 수 있습니다. Visual은 그 source를 검증해 만든 같은 Flow를 Canvas로 보여 주므로 Python에서 완성한 구조를 다시 배치하지 않습니다.
- Visual은 Node와 연결을 Canvas에서 편집합니다.
- Python은 같은 Flow module의
px.Flow,flow.input,flow.node,flow.connect,flow.result, Group과 Subflow 선언을 편집합니다. - Python에서 바꾼 내용은 Update Flow를 눌러 검증한 뒤 Canvas에 반영합니다. 화면만 전환해도 코드가 자동 저장되지는 않습니다.
- 검증에 실패하면 Python 화면에 진단을 남기고, Visual은 마지막으로 정상 확인된 Flow를 계속 보여 줍니다.
- 적용하지 않은 Python 변경이 있으면 Visual은 마지막 정상 Flow라는 상태를 표시하고 구조 편집을 잠급니다. Update Flow 또는 Discard로 초안을 정리한 뒤 다시 편집합니다.
- 왼쪽 Flow outline에서 Node를 선택하면 Visual에서는 해당 Node로 이동하고 Python에서는 해당
flow.node(...)선언으로 이동합니다.
공유 @px.function 구현은 Project Definitions에서 편집합니다. 이미 저장된 Component target의 구현은 해당 package가 소유하지만 current Canvas에서는 읽기 전용 unsupported로만 보존합니다. PXFLOW-native Flow에서는 Python을 구조 확인용 읽기 전용 보기로 제공하며, 편집하려면 SDK-linked Flow module 또는 PXFLOW-native Canvas 중 하나를 작성 원본으로 선택합니다.
Studio에서 편집한 내용을 저장하는 방법
같은 Flow가 Canvas에 보여도 저장되는 작성 원본은 시작 방식에 따라 달라집니다.
| 작성 상태 | 작성 원본 | Studio에서 변경할 때 |
|---|---|---|
| SDK-linked | Python Flow source와 dependency lock | source에 안전하게 표현할 수 있는 변경을 diff로 검토하고 Apply한 뒤 다시 materialize |
| PXFLOW-native | .pxflow direct object 또는 managed Flow revision | typed Flow 변경을 새 revision으로 직접 저장 |
materialize는 Python 선언에서 Flow input/result, current Function Node 배치, exact target, 연결과 Group을 읽어 검증 가능한 Flow를 만드는 SDK→Studio 단계입니다. 저장된 Component target은 read-only 복구 경계로 다룹니다. 계산 body와 Run을 실행하지 않으며 Component declaration·executor package를 생성하지도 않습니다. 현재 decorator의 책임은 local registration까지이며 Component 설정 schema 선언·검증은 별도 versioned settings contract가 승인되기 전에는 열지 않습니다. SDK-linked에서 만든 direct Flow는 검증·실행용 projection이며 Python source와 dependency lock이 작성 원본을 계속 소유합니다.
SDK-linked 변경을 source에 반영하는 순서
- Studio가 화면 변경을 exact Node·port를 가진 의미 변경으로 정리합니다. 기존 V1 setting을 다룰 때만 보존된 V1 member를 함께 추적합니다.
- 현재 source와 dependency lock이 Flow를 열 때와 같은지 확인합니다.
- 기존 declaration에 적용할 code action, Python diff와 영향 범위를 보여 줍니다.
- 사용자가 Apply하면 변경 후보를 staging 상태에서 검증합니다.
- 후보 source와 lock으로 Flow revision을 materialize하고 검토한 변경과 의미상 같은지 확인합니다.
- 모두 통과하면 source revision과 Flow revision을 한 commit 경계에서 함께 확정합니다.
검증, materialize 또는 parity 검사가 완료되지 않으면 이전 source와 Flow revision을 유지합니다. Node 위치, pan, zoom처럼 실행 의미가 없는 변경은 Python이 아니라 presentation state에 저장합니다.
전체 Python 파일을 재생성하지 않는 이유
Studio→SDK는 SDK-linked Flow에서 기존 source를 보존하는 source-safe code action으로 지원합니다. Flow direct object에는 Python 계산 body, helper, module 구성, import alias, 주석과 formatting이 포함되지 않으며 서로 다른 Python source가 같은 Flow로 materialize될 수 있습니다. 따라서 PXFLOW-native Flow의 코드 보기는 Flow 구조를 설명하는 파생 preview로 제공하고, 기존 Python 파일의 작성 원본으로 사용하지 않습니다.
source-safe code action으로 표현하기 어려운 변경은 owning source를 열어 코드에서 수정하거나 편집 가능한 PXFLOW 사본 만들기를 선택합니다. 이 사본은 .pxflow가 원본인 새 PXFLOW-native Flow로 저장되며 원래 SDK source와 자동 동기화하지 않습니다.
| 변경할 내용 | 편집 위치 |
|---|---|
| Flow input/result, Node 배치·key, 연결, Group | SDK-linked는 Flow module, PXFLOW-native는 Studio |
| 기존 V1 Component instance setting | V1 wire 그대로 보존; V2로 자동 이관하지 않음 |
current Project의 @px.function body·contract | Definitions → Functions → Open Function이 여는 owning source |
설치한 package의 @px.function body·contract | Node에서는 읽기 전용으로 확인하고 owning package에서 편집 |
installed @px.component companion target | owning package; current Flow surface는 unsupported |
| External reference 내부 | Edit source Flow로 여는 owning Flow |
| Node 위치·pan·zoom·panel 상태 | presentation state |
| Run input과 Result | Run ledger와 ResultSnapshot |
post-closure Component 연결 계약과 값 타입을 구분하기
이 절은 Component 제품 placement가 두 P0 closure 뒤에 노출될 때의 contract_only 연결 모델입니다. current production은 새 third-party Component Node를 만들지 않고 이미 저장된 exact target만 unsupported로 보존합니다.
현재 Function과 Component의 Python parameter annotation과 px.Results annotated field가 typed port를 정의하고, px.input(...)·px.result(...) marker가 description·unit을 더하며, Flow의 flow.input(...)·flow.result(...)가 공개 interface를 만듭니다. Component도 같은 endpoint를 사용합니다. 연결할 값이 한 개의 숫자나 문자면 scalar type을 사용하고, 값 하나가 여러 field를 가지면 px.Record subclass를 씁니다. 같은 Record의 여러 행을 한 값으로 전달하는 px.Table[RecordType]은 계획 계약입니다.
| 연결하려는 값 | port 작성 |
|---|---|
| scalar 한 개 | float, str, bool 같은 parameter annotation |
| 여러 field를 묶은 객체 한 개 | 향후 Record type annotation |
| 같은 field 구조의 표 전체 | 향후 px.Table[RecordType] annotation |
현재 Function Flow 먼저 열기
- Canvas에서 실행할 현재 계산은
@px.function으로 정의합니다. 일반 Pythondef는 Function body 안에서 쓰는 helper로 두고, Function이라면helpers=[...]에 선언합니다. - module-level
flow = px.Flow(...)를 만들고 Function target을flow.node("node_key", target)으로 배치합니다. flow.input,flow.connect,flow.result로 공개 interface와 typed wiring을 작성합니다.pxlab studio open . --flow <flow_key>로 같은 Flow를 Studio에서 엽니다.- Node·port·연결을 확인하고, 화면에서 바꿀 때는 source diff를 검토한 뒤 Apply합니다.
pxlab studio open은 Python source를 작성 원본으로 유지한 채 같은 Flow를 SDK-linked 상태로 엽니다. 독립 .pxflow 파일도 필요하면 다음 명령으로 저장합니다.
pxlab flow materialize . --flow <flow_key> --output <flow_key>.pxflow이 명령은 Node 계산을 실행하는 대신 input, Node, 연결과 result를 검증해 .pxflow로 저장합니다. Flow 저장 명령 자세히 보기
현재 Function decorator는 재사용 정의와 schema를 등록하고 실제 Function Node instance는 flow.node("node_key", target)이 만듭니다. @px.component는 current companion metadata만 등록합니다. Component에 같은 placement spelling을 쓰는 제품 경로는 post-closure입니다.
SDK 요소 먼저 고르기
| 하려는 일 | 사용할 문법 | PXFLOW Studio에서 확인할 위치 |
|---|---|---|
| 여러 field를 가진 값 타입 만들기 | px.Record subclass의 annotated field (decorator @px.record와 px.field는 planned contract_only) | input/result 상세의 Record schema와 field 목록 |
같은 Record를 여러 행으로 전달하기 · planned contract_only | px.Table[RecordType] | Table type의 input/result port와 column schema |
| 이름 있는 결과 만들기 | px.Results annotated field + px.result(...) metadata marker | Node result port shape |
| Canvas에서 실행할 계산 만들기 | @px.function(...) | Definitions → Functions |
| 계산 내부 helper 만들기 | 일반 Python def (+Function은 helpers=[...] 선언) | Canvas에 별도 Node로 나타나지 않음 |
| Component companion target 등록 | @px.component(...) | current는 process-local metadata만 등록; 저장된 exact ref는 unsupported |
| 후속 V2 Component Canvas UI | host-owned component.declarative@2 · contract_only | 공통 Node shell·Port |
| Component settings | px.setting(...) | component-declared-settings@1 · 선언당 최대 8개 |
| rich surface | component-rich-surface-declaration@1 | RFC-016이 소유하는 격리 editor |
| 실행할 Flow 만들기 | flow = px.Flow(...) | Flow Canvas |
| current Function target을 Canvas에 배치하기 | flow.node("node_key", target) | Function Node instance 하나 |
| Component target 신규 배치 · post-closure | 같은 flow.node(...) spelling · contract_only | admitted exact ComponentRef |
| 같은 Flow의 Node를 nested Canvas로 묶기 | flow.group(...) | editable Subflow · Group |
| 별도 Flow를 읽기 전용 reference로 배치하기 | flow.subflow(...) | read-only Subflow · External reference |
현재 px.Results annotated field, px.Record subclass와 지원되는 원소 annotation의 list[T]가 Node 값 shape를 정의합니다. decorator @px.record, px.field와 px.Table은 planned contract_only 문법입니다. Canvas 구성은 flow.node(...) placement와 flow.connect(...)로 만듭니다.
코드와 화면의 대응
from pipelinexlab import px
class GirderResults(px.Results):
utilization: float
@px.function(
key="girder_resistance",
version="1.0.0",
description="주어진 경간의 거더 사용률을 계산합니다.",
)
def girder_resistance(span: float, design_cases: list[float]) -> GirderResults:
value = calculate_utilization(span, design_cases)
return GirderResults(utilization=value)
flow = px.Flow("girder_review", label="거더 검토", description="거더 검토 결과를 생성합니다.")
span = flow.input(
"span",
float,
unit="m",
description="Bearing centre-line 사이의 순경간입니다.",
constraints={"exclusiveMinimum": 0},
)
design_cases = flow.input(
"design_cases",
list[float],
description="검토할 설계 하중 case입니다.",
)
resistance_check = flow.node("resistance_check", girder_resistance)
flow.connect(span, resistance_check.inputs.span)
flow.connect(design_cases, resistance_check.inputs.design_cases)
flow.result("utilization", resistance_check.results.utilization)| SDK에 작성한 것 | PXFLOW Studio에서 보이는 것 |
|---|---|
@px.function 함수 | Definitions에서 찾는 shared Function |
version="1.0.0" | 고정된 Function version |
flow = px.Flow("girder_review", ...) | Flow 하나와 화면에 보이는 이름 |
flow.node("resistance_check", ...) | resistance_check Node 하나 |
list[float] | 현재 facade에서 설계 하중 값 collection을 전달하는 input port 하나 |
class GirderResults(px.Results) | 이름 있는 result port를 묶은 반환 타입 |
plain parameter span | input port span |
annotated field utilization | result port utilization |
flow.connect(...) | Flow input에서 Node input으로 가는 연결 |
flow.result("utilization", ...) | Flow의 공개 result port |
현재 캔버스에는 새로 배치한 Function Node와 이미 저장돼 있던 unsupported Component target이 나타납니다. post-closure 뒤에는 admitted Component도 flow.node(...) placement로 추가됩니다. target body가 호출하는 일반 Python helper는 내부 구현으로 유지되며 별도 Node가 되지 않습니다. Function의 helper는 helpers=[...] 선언으로 revision에 함께 저장됩니다.
구조화 값과 Table 결과가 필요할 때
계획된 rich type marker
이 절의 decorator @px.record, px.field, px.Table spelling은 향후 rich authoring 계약입니다. px.input(...)과 px.result(...)는 current marker이고, 현재 record schema는 px.Record subclass의 annotated field로 선언합니다.
Flow와 Component의 연결은 target의 px.input(...)·px.result(...) port를 flow.connect(...)로 이어 만듭니다. @px.record는 그 port 하나로 전달할 값이 여러 field를 가질 때 선택하는 value schema입니다. 연결할 값의 shape에 따라 다음 type을 고릅니다.
| 연결할 값 | port annotation | @px.record 사용 |
|---|---|---|
| 숫자·문자·boolean 셀 하나 | float, str, bool 등 | scalar type을 직접 사용 |
| 여러 field를 가진 객체 한 개 | LoadCase, Section, Material 같은 Record type | 해당 type을 @px.record로 정의 |
| 같은 구조의 여러 행을 표 전체로 전달 | px.Table[LoadCase] | Table row type LoadCase를 @px.record로 정의 |
- 여러 값을 한 타입으로 전달하려면 class에
@px.record("record_key", ...)를 붙입니다.record_key는 직접 정하는 stablelower_snake_casekey입니다. - class field에는 Python type과
px.field(...)를 작성합니다. field name이 stablefieldKey, annotation이 type과 nullability,default=유무가 required/default를 정하고 marker가 설명·단위·제약을 추가합니다. - Record 한 개를 받는 port에는
LoadCase, 같은 Record의 여러 행을 받는 port에는px.Table[LoadCase]를 annotation으로 사용합니다. - 반환값은
px.Resultssubclass에px.result(...)field로 이름을 붙입니다. Table 결과는px.Table[CheckResult]처럼 result field의 type으로 선언합니다. - Studio에서 Node를 열어 input/result 상세의 Record field, Table column, type과 unit이 SDK 선언과 같은지 확인합니다.
이 예제는 contract_only 목표 문법이며, 현재 설치본에서는 실행 상태로 표시된 current 예제를 사용하세요.
@px.record(
"check_result",
description="한 설계 case의 검토 결과입니다.",
row_key="case_key",
)
class CheckResult:
case_key: str = px.field(description="원본 하중 case key입니다.")
utilization: float = px.field(unit="1", description="수요-저항 비율입니다.")
class CheckResults(px.Results):
rows: px.Table[CheckResult] = px.result(
description="case별 검토 결과입니다."
)row_key="case_key"는 Table 안에서 각 row를 안정적으로 식별할 때 사용합니다. 지정한 field는 required·non-null str 또는 int로 작성합니다. Flow port는 portKey가 연결 주소를 맡고, row_key는 Table result의 정렬·비교·부분 진단에서 row를 찾습니다.
px.Table[LoadCase] port 하나를 Node에 연결하면 target은 Table 전체를 값 하나로 받아 한 번 실행합니다. 여러 scalar input set은 batch caller가 같은 saved Flow revision을 명시적으로 여러 번 실행합니다. 반복 횟수와 각 input set은 Batch Run에 표시됩니다.
px.Results subclass는 결과가 하나일 때도 사용하고, 각 px.result(...) field가 독립적인 result portKey이며 Flow 연결과 Component에서는 그 field 이름을 선택합니다.
Record와 Table의 전체 type 규칙은 Python SDK 문법의 @px.record, px.field와 px.Table, 결과 규칙은 px.Results를 확인하세요.
@px.component와 px.setting 경계
현재 @px.component는 companion metadata target만 등록합니다. runnable shape는 Component target 등록의 일반 annotation 예제를 따릅니다.
px.setting(...)은 px.Settings subclass의 field가 선언하는 current marker이고, 그 선언 schema는 component-declared-settings@1이 소유합니다. UI와 migration schema는 이 페이지가 정의하지 않습니다. portable Component V2 placement는 settings를 선언당 최대 8개까지 받고 host control registry가 그립니다. 선언이 없는 기존 V1 non-empty settings wire는 호환을 위해 보존하며 V2로 자동 변환하지 않습니다.
settings 계약과 rich surface 계약은 별개입니다. settings가 승인돼도 package renderer·modal을 허용한다는 뜻이 아니며, rich surface의 entry·message shape는 RFC-016의 component-rich-surface-declaration@1이 정의하고 command shape는 열지 않습니다.
flow.node(...)가 배치할 수 있는 target
| target | Canvas 표현 | source 편집 위치 |
|---|---|---|
@px.function | Function Reference Node | Node modal은 read-only; Open Function으로 owning Project·SDK package 확인 |
post-closure admitted package에서 import한 @px.component | successor exact ComponentRef; 저장된 current target은 unsupported | package-owned artifact; V2 Canvas는 host-owned projection만 사용 |
두 target은 같은 flow.node("node_key", target) spelling을 사용합니다. current internal/test resolver primitive는 활성 px.Client로 exact release를 resolve해 ComponentRef를 저장하는 내부 경로입니다. caller/release policy는 새 Component install·placement·activation을 차단하고 저장돼 있던 exact target만 unsupported로 보존합니다. 두 P0 closure 뒤에만 같은 resolver와 spelling을 제품 경로로 노출합니다.
flow.group(...)은 같은 Flow에 이미 배치된 Node handle의 membership을 저장하는 authoring 구조입니다. stable groupKey를 따로 정하고 members에는 같은 Flow의 Node handle을 둘 이상 넣습니다. materialize된 Flow는 각 handle의 exact nodeKey를 membership으로 저장합니다. 한 Node는 direct Group 하나에 배치하고 Group 안에 Group을 넣는 대신 한 단계의 editable nested Canvas를 사용합니다. Group/ungroup 뒤에도 member Node, input binding, public interface와 execution slot은 그대로 유지됩니다.
별도 Flow는 import한 px.Flow object를 flow.subflow("subflow_key", imported_flow)로 배치합니다. Studio는 이를 Subflow · External reference로 표시하고 내부 Flow를 읽기 전용으로 엽니다.
from structural_sections.flows.section_properties import flow as section_properties_flow
geometry = flow.input(
"geometry",
SectionGeometry,
description="Section geometry passed to the referenced Flow.",
)
section_properties = flow.subflow("section_properties", section_properties_flow)
flow.connect(geometry, section_properties.inputs.geometry)
flow.result("area", section_properties.results.area)section_properties는 별도 Flow의 interface를 가리키는 placement handle입니다. caller는 input/result를 연결하고 내부 Node는 owning Flow에서 편집합니다.
@px.function의 key, version과 source owner
@px.function(key="...", ...)의 명시적인key가 stablefunctionKey입니다. Python 함수 이름은 구현 이름이므로 key를 유지한 채 바꿀 수 있습니다.key,version과description은 필수이며 version에는 SemVer를 사용합니다.- Function version은 input/result와 계산 의미의 version이고 package version은 설치·배포 묶음의 version입니다.
- materialize 단계가 dependency lock에서 exact package release와 Function ref를 고정합니다.
- current Project가 소유한 Function은 Open Function으로 owning source에서 편집합니다. 설치한 exact package release의 Function은 같은 화면에서 계약과 source를 읽고, 변경할 때는 새 package version 또는 project-owned 분기를 만듭니다.
Project Definitions → Functions — Function 목록, 공유 source와 사용처를 한 화면에서 관리합니다. Canvas에는 Flow에 배치한 Function Reference Node가 표시됩니다.
px.Flow와 binding 작성 규칙
px.Flow("flow_key", label=..., description=...)의 첫 번째 값이 stableflowKey입니다.- 한
.pyFlow module은 module-levelflowobject 하나를 export합니다. flow.input(...)으로 공개 input을 만들고flow.node(...)로 current Function target을 배치합니다. Component 신규 placement는 post-closure 제품 경로입니다.flow.connect(source, node.inputs.<port>)로 Flow input이나 이전 Node result를 exact inputportKey에 연결합니다.- 기존 V1
flow.node(..., settings={...})는 해당 V1 contract의 값을 보존합니다. 후속 V2는 settings를component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. flow.result("result_key", source)로 공개 typed Result를 선택합니다.flow.group(...)은 같은 Flow의 editable visual membership을,flow.subflow(...)는 import한 별도 Flow의 read-only External reference placement를 만듭니다.- 복잡한 Flow도 top-level declarative statement를 이어서 작성하고 실제 계산과 I/O는 target body에 둡니다.
사람이 읽고 AI가 찾는 이름
px.Flow("flow_key", ...)의 첫 번째 값이flowKey,@px.function(key="...")의key가functionKey,@px.component(key="...")의key가componentKey입니다.- Function·Component의 parameter 이름과
px.Resultsfield 이름이portKey가 됩니다. - source에 직접 적는
recordKey,nodeKey,groupKey와subflowKey를 포함한 모든 public key는 stablelower_snake_case로 정합니다. - Node key는 Flow 안에서 고유해야 합니다.
- label은 화면 표시에 사용하고, 연결 주소에는 stable key를 사용합니다.
- key를 바꾸는 일은 단순한 제목 변경이 아니라 연결에 영향을 주는 작업입니다.
- UUID, 파일 경로, 캔버스 위치와 Python 지역 변수명은 사용자 연결 주소로 쓰지 않습니다.
예를 들어 사용자는 girder_review → resistance_check → utilization을 보고 대상을 찾습니다. 내부 시스템 식별자는 제품이 관리합니다.
Port 정보의 단일 선언
현재 Function과 Component에서는 Python parameter와 px.Results annotated field가 port key를 소유합니다. Flow에서는 flow.input("key", type, ...)와 flow.result("key", source)가 공개 port key를 소유합니다. marker 규칙은 다음과 같습니다.
px.input(...)은 Function과 Component parameter에 작성합니다.px.result(...)는px.Resultsfield에 작성합니다.flow.input(...)과flow.result(...)는 Flow module의 top-level에 작성합니다.px.input(required=False)를 쓰면 optional input이 됩니다.- 현재 marker는
description,unit,required를 받고 업무 기본값은 계획 계약으로 남습니다. - nullable 여부는 타입에
None이 포함되는지에 따라 결정됩니다. connection의 기본값은True입니다.- 공학 숫자는 canonical unit, 무차원 숫자는 unit
"1"을 사용합니다.
계획 계약에서는 지원되는 Python scalar·Record·collection·resource type을 annotation으로 작성하고 marker에 단위, 설명, 제약과 연결 가능 여부를 덧붙입니다. 이 단일 선언을 SDK, Studio, V2 host renderer와 AI가 함께 읽습니다. 전체 public type 목록은 Python type과 wire type을 확인하세요.
외부 연결을 숨기기
내부 진단처럼 다른 Flow, host discovery surface나 AI가 연결해서는 안 되는 port만 명시적으로 숨깁니다.
이 예제는 contract_only 목표 문법이며, 현재 설치본에서는 실행 상태로 표시된 current 예제를 사용하세요. planned px.Evidence와 px.result(..., connection=False) discovery metadata를 설명합니다.
class SolverResults(px.Results):
trace: px.Evidence = px.result(
description="계산 내부 확인용 trace입니다.",
connection=False,
)connection=False여도 같은 Flow 내부의 Node 연결에는 사용할 수 있습니다. connection은 외부 discovery를 제어하고, 사용자 계정의 읽기·쓰기·실행 권한은 Project ACL과 실행 정책에서 별도로 검사합니다.
같은 Function을 여러 번 사용하기
flow = px.Flow(
"girder_review",
label="ULS·SLS 거더 검토",
description="ULS와 SLS를 함께 검토합니다.",
)
span = flow.input("span", float, unit="m", description="순경간입니다.")
uls = flow.input("uls", list[float], description="ULS 하중 case입니다.")
sls = flow.input("sls", list[float], description="SLS 하중 case입니다.")
uls_check = flow.node("uls_check", girder_resistance)
sls_check = flow.node("sls_check", girder_resistance)
flow.connect(span, uls_check.inputs.span)
flow.connect(uls, uls_check.inputs.design_cases)
flow.connect(span, sls_check.inputs.span)
flow.connect(sls, sls_check.inputs.design_cases)
flow.result("uls", uls_check.results.utilization)
flow.result("sls", sls_check.results.utilization)uls_check.results.utilization과 sls_check.results.utilization은 Function의 exact result portKey를 선택하고, 두 flow.result(...) 선언이 값을 Flow-level result로 공개합니다.
uls_check와 sls_check는 서로 다른 Node지만 같은 Function version을 사용합니다. 둘 사이에 데이터 의존성이 없고 Function이 parallel_safe=True로 선언되었으면 Runtime이 허용된 자원 범위에서 병렬로 실행할 수 있습니다. 실행 순서는 data dependency가 결정합니다.
저장과 이동
.pxflow는 Flow 구조를 편집하고 검토하는 direct 문서입니다.- SDK-linked Flow의 source 위치는 권한 있는 로컬 앱 상태에서 관리하며 portable 파일에 절대 경로를 넣지 않습니다.
- 다른 장치에서도 완전히 재현 가능한 실행이 필요하면 project source, SDK package, lock과 asset을 포함한 Project package가 필요합니다.
- Recent에는 source와 파생 snapshot을 중복 항목으로 표시하지 않습니다.
문제를 발견했을 때
| 상태 | 의미 | 해결 방법 |
|---|---|---|
| Source changed | Studio를 연 뒤 source가 변경됨 | 새 source를 읽고 변경을 다시 검토 |
| Unsupported visual edit | source-safe 변환을 보장할 수 없음 | 코드 편집 또는 PXFLOW-native 사본 생성 |
| Missing target | Node가 참조한 Function version, Component identity 또는 External Flow revision 확인 필요 | package/source/lock 복구 또는 명시적 업그레이드 |
| Component dependency required | 저장된 Component Node에 exact package dependency 필요 | 현재 third-party는 차단 상태로 exact ref를 보존; package artifact owner가 retained한 경우에만 bytes를 evidence로 사용; gate가 닫힌 후에만 required package 추가·Validate |
| Package version mismatch | 필요한 package version과 설치한 package version이 다름 | 현재 third-party는 실행하지 않고 exact ref 보존; gate가 닫힌 후 Install required version 또는 Review update |
| Package information unavailable | catalog 또는 registry를 조회할 수 없음 | Retry 또는 Locate package |
| Unknown Component | dependency·import·저장 target 정보가 없어 원래 Component를 식별할 수 없음 | source/lock을 복구하거나 정확한 package를 직접 지정; 유사 이름으로 자동 대체하지 않음 |
| Function source required | Project-owned Function의 exact source와 dependency lock 확인 필요 | owning Project source를 찾아 digest와 lock 확인 |
| Port mismatch | key·type·unit이 source와 화면에서 다름 | 자동 추측하지 말고 진단 경로를 따라 수정 |
| Newer change saved | 다른 변경이 먼저 저장됨 | 최신 상태를 불러와 차이를 검토한 뒤 다시 적용 |
화면에서는 Newer change saved로 안내합니다. SDK·API 진단에서는 예상 generation이 현재 값과 다를 때 정확한 code PX_GENERATION_STALE을 사용합니다.
현재 production third-party Component data path는 exact ProjectScope로 격리되지만 install admission과 activation은 authenticated-principal authorization·execution-trust closure와 production gate가 닫힐 때까지 차단합니다. 이 gate가 닫힌 뒤 package를 설치하거나 version을 바꿀 때에는 Port 계약과 기존 V1 setting 차이를 검토하고 Validate를 통과한 다음 실행합니다. 복구 중에는 package artifact owner가 실제로 retained한 경우에만 original package bytes를 evidence로 사용합니다. Flow/current reader가 무조건 보존하는 값은 exact ComponentRef, 저장된 Node·connection·기존 V1 setting과 사용처에서 유도한 일부 Port뿐이며 bytes를 이 값들에서 추론하지 않습니다. full last-verified Port snapshot은 저장하거나 약속하지 않습니다. 후속 V2 settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다.
이 페이지 다음에 확인할 SDK 범위
이 페이지는 SDK target을 Flow Canvas에 배치하는 core 범위를 다룹니다. 다음 기능은 정확한 계약 문서에서 이어서 확인합니다.
| 필요한 기능 | 기준 문서 |
|---|---|
| cache·retry·병렬 안전성 | px.policy |
| file·network·secret·GPU 권한 상한 | capability |
| Binary·Artifact·Evidence·CalculationTrace | Python type과 wire type |
| 사용자에게 반환할 입력 오류 | 예외 |
| Extension 전용 template·artifact | Extensions와 Integrations과 해당 Extension의 SDK 문서 |
사용자용 App 화면 · planned contract_only | @px.app과 App Builder |



