본문으로 건너뛰기

실행할 Project Client 만들기

용도

px.Client는 Flow를 직접 실행하거나 Report connection을 실행하고, 그 Run과 Result를 조회할 Project 범위를 선택합니다.

화면에서 보이는 것

Project Home에서 현재 Project를 연 뒤 Report Workbench 또는 PXFLOW Studio에서 Run을 시작하는 범위와 같습니다. 시작한 Run은 Project Activity에서 확인합니다.

문법

python
px.Client(workspace=..., project=...)

예제

python
from pipelinexlab import px

client = px.Client(workspace="engineering", project="bridge_project")

정식 서비스에 접속하기

python
import os
from pipelinexlab import px

with px.Client(
    workspace="engineering",
    project="bridge_project",
    service_url=os.environ["PXL_SERVICE_URL"],
    access_token=os.environ["PXL_ACCESS_TOKEN"],
    organization=os.environ["PXL_ORGANIZATION"],
) as client:
    run = client.get_run("saved_run_key")
    png = run.read_result("geometry", max_bytes=4 * 1024 * 1024)

위 환경 변수는 예제가 명시적으로 읽는 값입니다. SDK가 자동으로 선택하는 설정이 아닙니다. service_url에는 배포에서 제공한 operation endpoint 전체 주소를 지정합니다. 세 접속 인자는 함께 지정하며, 토큰에는 해당 operation과 Project의 권한이 필요합니다. 토큰 발급·로그인과 Project 생성은 이 생성자가 수행하지 않습니다. 토큰을 소스나 문서에 저장하지 마세요.

기본 TLS 인증서·호스트 이름 검증을 사용합니다. HTTP는 숫자 loopback 주소의 로컬 서비스 검사에만 허용합니다. redirect·자동 재시도·실패 후 로컬 런타임 자동 시작은 하지 않습니다. 서비스 접속 인자를 생략하면 기존 로컬 자동 시작 동작을 사용합니다.

현재 HTTP는 일반 Flow·Report 저장, 실행, Run별 수치·파일의 chunk 조회를 지원합니다. 서버가 전송 session을 지원하고 토큰에 product.runtime.transfer 권한이 있으면 대용량 Report 전송과 client.import_documents()의 첨부 업로드를 자동 협상합니다. 업로드에는 해당 Project의 읽기·쓰기 권한도 필요합니다. 기존 서버나 전송 권한이 없는 토큰은 기존의 작은 요청·응답 경로를 사용합니다. 전송당 최대 32MiB, chunk당 최대 64KiB이며 서버의 전체 보관 메모리 한도도 적용됩니다.

python
# 열린 서비스 Client의 with 블록 안에서 실행합니다.
# 로컬 export_documents()로 만든 bundle을 서비스 Project로 가져옵니다.
imported = client.import_documents("./exported-notes", command_id="upload-notes-1")
# 중단 후에는 같은 bundle과 command_id로 재시도합니다.

전송 session은 사용자·Organization·토큰·Project에 묶이며 유휴 60초 또는 서버 재시작 뒤에는 다시 업로드해야 합니다. import_documents()를 같은 command_id로 재호출하면 첨부를 다시 전송하고 이미 적용된 문서는 기존 receipt로 확인합니다. 서버 replica 간 session 공유는 지원하지 않으므로 한 session의 요청은 같은 서버 인스턴스로 전달해야 합니다.

직접 첨부 저장을 지원하는 서버에서는 아래처럼 save()할 수도 있습니다. 토큰에는 product.report.ingest_attachment operation도 필요합니다. 파일은 첨부를 지정할 때가 아니라 save()할 때 PC에서 읽습니다. 서버에는 파일 경로를 보내지 않습니다.

python
# 열린 서비스 Client의 with 블록 안에서 실행합니다.
note = px.Report("drawing_note", title="Drawing")
note.section("body", title="Body").attachment("drawing", "./drawing.png", media_type="image/png")
client.save(note)

SDK는 서버의 직접 첨부 기능도 별도로 협상합니다. 이를 지원하지 않는 이전 서버에서는 명시적으로 거절하므로 export/import 경로를 사용해야 합니다. 같은 bytes의 첨부 등록 재시도는 같은 content identity를 사용합니다. 파일이 바뀌면 다음 저장 시도는 변경된 bytes를 읽습니다. 첨부 등록과 Report 리비전 저장은 별도 단계이므로 저장 충돌이 생겨도 첨부 등록을 되돌리거나 파일을 즉시 삭제하지 않습니다. 서버 파일 경로를 입력해 파일을 대신 읽는 방식은 허용하지 않습니다. 연결이 끊기거나 시간이 초과되면 적용 결과는 불명확할 수 있으므로 같은 요청 ID의 receipt를 확인해야 합니다. 새 요청 ID로 무조건 재실행하지 마세요.

매개변수

이름설명
workspace실행 대상 Project를 포함하는 Workspace stable key 또는 exact ref
project실행 권한, 저장된 Flow·Report와 Run 이력을 찾을 Project 식별값
timeout요청 시간 제한(초). 기본 120초, None은 제한 없음
service_url선택 사항. 서비스 operation endpoint 전체 주소
access_token서비스가 발급한 bearer access token
organization해당 서비스에서 사용할 정확한 Organization 식별값

반환

run, run_many, run_batch를 호출할 Project-scoped client를 반환합니다.

규칙

  • Client는 선택한 Project의 권한과 저장된 revision을 기준으로 실행합니다.
  • Flow를 직접 실행하면 전달한 input과 Flow revision을, Report connection을 실행하면 저장된 input 연결·결과 위치와 Flow revision을 Run 시작 시 고정합니다.
  • Client 생성은 계산 Run을 시작하지 않습니다.
  • 같은 pipelinexlab package와 from pipelinexlab import px import를 Report·Flow 작성과 Runtime에 함께 사용합니다.
  • 현재 공개 facade에는 px.client() 편의 함수가 없습니다. hosted surface를 포함한 모든 공개 Python 호출은 위 예제처럼 px.Client(workspace="...", project="...")로 범위를 명시합니다.

다음 단계

Workspace 검색

client.search_catalog()는 기존 project_searchworkspaceItems 범위를 사용합니다. 한 호출은 현재 권한으로 확인한 결과 한 페이지를 반환합니다. 웹 화면에 불러온 Project 개수와 무관하게 지정한 Workspace 전체를 검색하며, 자동 페이지 순회나 다른 서버로의 대체 호출은 하지 않습니다.

python
with px.Client(workspace="engineering", project="structures") as client:
    options = {"workspace_ref": "catalog:engineering", "name_prefix": "Quarter", "kind": "report"}
    page = client.search_catalog(**options)
    for item in page["items"]:
        print(item["name"], item["itemRef"])
    if page["nextCursor"] is not None:
        page = client.search_catalog(**options, cursor=page["nextCursor"])

workspace_ref는 서비스가 제공한 불투명 catalog 참조입니다. 계정명이나 Client의 SDK Workspace key로 추정하지 않습니다. name_prefix=None은 이름 필터 없음이며 문자열을 주면 대소문자·공백을 그대로 유지하는 정확한 접두어 검색입니다. kindproject, folder, pxflow, report, pdf 또는 필터 없음인 None입니다. sortnameAscending 또는 updatedDescending이며, 동률은 정확한 항목 참조의 UTF-8 바이트 순서로 정렬합니다. limit은 기본 50, 범위 1–500입니다.

반환값은 itemsnextCursor를 가진 사전입니다. 다음 페이지에는 같은 Workspace·필터·정렬을 사용합니다. 각 페이지는 현재 Project 접근권한을 확인하며, 커서는 권한이나 고정된 검색 시점의 스냅샷을 부여하지 않습니다. 기존 세 범위만 지원하는 서버는 새 범위를 거부하므로 해당 서버의 공통 Runtime을 갱신해야 합니다. 거절은 기존 px.Error와 구조화된 진단으로 전달됩니다.

개인 서비스 Project 만들기

python
import os
from pipelinexlab import px

with px.Client(
    workspace="personal",
    project="section_analysis",
    service_url=os.environ["PXL_SERVICE_URL"],
    access_token=os.environ["PXL_ACCESS_TOKEN"],
    organization=os.environ["PXL_ORGANIZATION"],
) as client:
    project_ref = client.create_project(
        name="단면 분석",
        command_id="create_section_analysis",
    )
    # 이어서 같은 Client의 save(), run(), open_report()를 사용합니다.

서명은 client.create_project(*, name: str, command_id: str) -> str입니다. 반환값은 서버의 opaque catalog Project 참조이며 SDK의 project key나 표시 이름과 다릅니다. 생성할 Workspace·Project key는 Client의 것을 사용합니다. namecommand_id는 비어 있지 않은 문자열로, 제어 문자를 포함할 수 없으며 UTF-8 기준 최대 1,024 bytes입니다. Project key는 기존 Core key 문법을 따릅니다.

서버가 연결한 개인 계정, 두 Workspace의 현재 멤버십, V1 이용 자격과 명시적 Project 생성 권한이 필요합니다. 토큰에는 접속의 product.runtime.handshake·project_search와 생성의 product.project.create operation이 필요합니다. 이후 저장·실행에는 그 작업의 operation scope도 필요합니다. 예를 들어 Flow 저장에는 pxflow_validate, pxflow_describe, pxflow_plan_change, pxflow_apply_change를 사용합니다. Project 권한이 생겼다고 토큰의 허용 operation이 늘지는 않습니다.

응답을 잃었으면 같은 Client scope·이름·command_id로 다시 호출합니다. 최초 Project를 반환하며 권한이나 감사 기록을 중복 생성하지 않습니다. 다음 거절은 px.Error.diagnostics로 확인합니다.

상황Diagnostic / params
같은 요청 ID의 내용을 바꿈PX_REQUEST_SHAPE_INVALID, member="commandId", reason="memberValueInvalid"
기존 Project key를 다른 생성 요청에 사용PX_REQUEST_SHAPE_INVALID, member="scope", reason="memberValueInvalid"
현재 생성 권한 또는 이용 자격 부족PX_PERMISSION_DENIED, requiredPermission="workspace.projects.create"
최초 생성 receipt가 현재 대상을 확인할 수 없음PX_TARGET_NOT_FOUND, targetKey=<command_id>

기존 공유 Project를 이 호출로 채택하거나 회수된 권한을 다시 만들지 않습니다. 알려진 과거 문서가 있는 unbound key도 신규 생성으로 덮어쓰지 않습니다. 로컬-only Client는 개인 서비스 생성에 대한 structured refusal을 받으며, 기존 로컬 save()·run() 사용에 이 호출은 필요하지 않습니다. 새 operation descriptor를 지원하는 SDK·서버 조합이 필요합니다. 이 API의 구현이 공개 서비스 배포나 기존 모든 계정의 생성 권한 공급을 뜻하지는 않습니다.

서비스 Home에서도 새 프로젝트로 같은 생성 API를 사용할 수 있습니다. 화면은 현재 선택한 Workspace의 저장된 귀속을 서버에서 확인합니다. 응답을 확인하지 못하면 제출한 이름을 유지한 같은 요청으로 재시도하며, 이 탭을 새로고침해도 요청이 복원됩니다. 창을 닫는 동작은 서버의 생성을 취소하지 않습니다. 생성 후 목록 조회만 실패하면 이미 생성된 Project를 다시 엽니다. 이 동작은 대응 Runtime과 생성 host를 함께 연결한 Home에 적용되며 읽기 전용 sample에는 제공되지 않습니다.

웹 화면과 SDK의 접속 주소

서비스 운영자가 제공한 SDK endpoint를 service_url에 사용합니다. 정식 배포 구성에서는 https://app.pipelinexlab.com/v1/sdk/runtime을 SDK용 주소로 준비하고 있습니다. 현재 설정 파일이 준비된 상태이며, 이 문서만으로 해당 공개 주소의 이용 가능성을 보장하지 않습니다. 브라우저의 /v1/runtime은 세션 쿠키와 CSRF를 사용하는 BFF 주소이므로 SDK bearer 접속에 사용하지 않습니다. 토큰과 Organization 참조는 운영자가 제공한 현재 값을 사용합니다.

기존 save(), open_report(), run(), get_run()Run.read_result()를 그대로 사용합니다. 큰 문서·첨부는 SDK가 협상한 전송 세션과 chunk로 전송합니다. 서비스 재시작으로 전송이 끊기면 같은 요청 ID를 지원하는 작업은 해당 API의 재시도 계약을 따릅니다. 접속 주소를 추가해도 저장 파일·리비전 형식이나 Run의 계산 성공 의미는 달라지지 않습니다.