Python OSDK 2.x 참조
Python OSDK는 앱에 포함한 온톨로지 유형의 클래스와 조회, 액션 및 함수 호출을 생성합니다. 아래는 가상 생성 패키지 ontology_sdk와 ExampleRestaurant 유형을 사용하며 실제 패키지 이름과 스키마는 Developer Console의 앱 Overview 및 버전별 문서에서 확인합니다.
예제 객체
| 표시 이름 | 온톨로지 API 이름 | 자료형 |
|---|---|---|
| restaurant id, 기본 키 | restaurantId | String |
| restaurant name, 제목 | restaurantName | String |
| address | address | String |
| e mail | String | |
| number of reviews | numberOfReviews | Integer |
| phone number | phoneNumber | String |
| review summary | reviewSummary | String |
Python 속성 이름은 restaurant_id와 restaurant_name처럼 생성된 snake_case를 사용합니다. 필터의 속성 참조는 ExampleRestaurant.object_type에서 가져옵니다.
실행 환경별 클라이언트
Foundry Python 함수, Code Workspaces 노트북과 모델 어댑터에서는 런타임이 호스트와 인증 정보를 제공합니다.
from ontology_sdk import FoundryClient
client = FoundryClient()
독립 Python 앱에는 생성 SDK 설치와 인증 설정이 필요합니다. 지원 Python은 3.10부터 3.14입니다. Developer Console의 앱 Overview에 표시된 SDK 패키지 이름과 패키지 인덱스를 사용합니다.
다음 Bash는 FOUNDRY_TOKEN, FOUNDRY_SDK_PACKAGE 및 FOUNDRY_PYPI_INDEX를 외부 실행 환경에 제공한 경우입니다. FOUNDRY_PYPI_INDEX는 화면의 인덱스 호스트와 경로에서 https://를 제외한 값입니다. 다운로드 토큰을 pip 명령의 인수가 아닌 환경으로 전달합니다.
: "${FOUNDRY_TOKEN:?SDK 읽기 토큰이 필요합니다}"
: "${FOUNDRY_SDK_PACKAGE:?생성 SDK 패키지 이름이 필요합니다}"
: "${FOUNDRY_PYPI_INDEX:?생성 SDK 인덱스의 호스트와 경로가 필요합니다}"
PIP_EXTRA_INDEX_URL="https://:${FOUNDRY_TOKEN}@${FOUNDRY_PYPI_INDEX}" \
python -m pip install --upgrade "$FOUNDRY_SDK_PACKAGE"
토큰이 들어간 환경을 로그로 출력하지 않습니다. 독립 앱에서는 실제 HTTPS Foundry URL과 토큰으로 클라이언트를 만듭니다.
import os
from ontology_sdk import FoundryClient, UserTokenAuth
client = FoundryClient(
auth=UserTokenAuth(token=os.environ["FOUNDRY_TOKEN"]),
hostname=os.environ["FOUNDRY_URL"],
)
client.ontology.objects.ExampleRestaurant.take(1)로 설정을 점검하면 실제 데이터를 조회합니다. 생성 패키지 설치, 인증과 데이터 권한이 모두 필요합니다. 사용자 토큰 대신 서비스 앱으로 인증하는 경우에는 해당 앱의 기밀 OAuth 및 서비스 사용자 구성을 따릅니다.
단일 객체와 RID
get은 기본 키로 객체를 읽으며 없으면 None일 수 있습니다. RID는 기본 읽기에서 접근 가능한 속성으로 포함되지 않으므로 필요하면 include_rid=True를 사용합니다.
from ontology_sdk import FoundryClient
def restaurant_rid(client: FoundryClient, primary_key: str) -> str:
restaurant = client.ontology.objects.ExampleRestaurant.get(primary_key, include_rid=True)
if restaurant is None or restaurant.rid is None:
raise ValueError("RID를 가진 식당 객체를 조회할 수 없습니다.")
return restaurant.rid
include_rid는 page, iterate와 take에도 사용할 수 있습니다.
페이지와 반복자
page(page_size=30, page_token=None)은 한 페이지를 반환합니다. data에 객체 목록, next_page_token에 다음 페이지 토큰이 있습니다. 후속 요청에도 처음 선택한 페이지 크기를 사용합니다.
page_size의 최대는 10,000이며 생략하면 최대 10,000개를 요청합니다. 실제 페이지는 내부 메모리 조건으로 더 작을 수 있으므로 끝 여부는 다음 토큰으로 판단합니다.
from ontology_sdk import FoundryClient
def restaurant_names(client: FoundryClient) -> list[str | None]:
names: list[str | None] = []
token = None
while True:
page = client.ontology.objects.ExampleRestaurant.page(page_size=30, page_token=token)
names.extend(restaurant.restaurant_name for restaurant in page.data)
token = page.next_page_token
if token is None:
return names
iterate()는 모든 페이지를 읽는 반복자이고 list(iterate())는 전체를 메모리에 모읍니다. take(n)는 최대 n개를 목록으로 반환합니다.
OSv1(Phonograph)은 객체 로드가 총 10,000개를 넘으면 ObjectsExceededLimit 오류가 발생합니다. OSv2에는 이 총 결과 개수 한도가 없지만 코드가 모든 객체를 목록에 넣는 메모리 비용은 남습니다.
읽기 옵션
다음은 동기 메서드이며 대응하는 비동기 메서드도 같은 인수를 받습니다.
| 매개변수 | 메서드 | 의미 |
|---|---|---|
| properties | get, page, iterate, take | 생성 속성 참조 목록으로 선택 |
| apply_modifiers | get, page, iterate, take | 속성 표현 변경 |
| include_rid | 같은 네 메서드 | rid 포함. 기본 False |
| load_property_securities | 같은 네 메서드 | 속성별 보안 메타데이터. 기본 False |
| load_ontology_defined_derived_properties | 같은 네 메서드 | 온톨로지 정의 파생 속성 로드 요청 또는 억제 |
| page_size, page_token | page | 페이지 크기 및 이어 읽기 |
| num_items | take | 읽을 최대 객체 수 |
properties를 생략하면 해당 유형에서 일반적으로 로드하는 속성을 반환합니다. 선택할 때는 문자열이 아닌 ExampleRestaurant.object_type.restaurant_name 같은 생성 참조를 전달합니다.
from ontology_sdk.ontology.objects import ExampleRestaurant
page = client.ontology.objects.ExampleRestaurant.page(page_size=30, properties=[
ExampleRestaurant.object_type.restaurant_id,
ExampleRestaurant.object_type.restaurant_name,
])
이후 예제의 client는 위 환경에 맞춰 만든 클라이언트입니다.
속성 환산과 주 값, Beta
배열 속성을 선택하면 환산기가 설정되어도 전체 배열을 반환합니다. apply_modifiers에 생성된 ApplyModifiers 클래스를 전달하면 읽는 표현을 바꿀 수 있습니다.
| modifier | 의미 |
|---|---|
| applyReducers | 환산기가 선택한 배열 원소 |
| extractMainValue | 구조체의 주 값 필드 |
| applyReducersAndExtractMainValue | 구조체 배열의 원소 선택 뒤 주 값 추출 |
properties도 함께 지정하면 modifier를 적용할 모든 속성을 그 목록에 넣어야 하며 빠지면 ValueError가 발생합니다. 가상의 Equipment.maintenance_history는 가장 최근 날짜를 고르는 Date 배열이라고 가정합니다.
from foundry_sdk_runtime import AllowBetaFeatures
from ontology_sdk.ontology.objects import Equipment
from ontology_sdk.ontology.objects.equipment import EquipmentApplyModifiers
with AllowBetaFeatures():
equipment = client.ontology.objects.Equipment.get(
"E-100",
properties=[Equipment.object_type.equipment_id, Equipment.object_type.maintenance_history],
apply_modifiers=EquipmentApplyModifiers(maintenance_history="applyReducers"),
)
if equipment is None or equipment.modified_properties is None:
raise ValueError("장비 또는 환산 결과가 없습니다.")
latest_date = equipment.modified_properties.maintenance_history
E-100은 가상 키입니다. modifier를 적용하면 원래 속성 값은 None이고 변환한 값은 modified_properties에 있습니다. 저장 또는 파생 데이터 자체는 바꾸지 않습니다. 전체 배열이 필요하면 modifier를 빼고 원래 속성을 읽습니다.
정렬과 링크
order_by에 생성 속성의 asc() 또는 desc()를 넣고 여러 번 연결할 수 있습니다. 문자열은 대소문자를 구분하여 숫자, 대문자, 소문자 순서로 정렬하므로 Cat이 bat보다 먼저입니다.
from ontology_sdk.ontology.objects import ExampleRestaurant
ordered = (client.ontology.objects.ExampleRestaurant
.where(~ExampleRestaurant.object_type.restaurant_name.is_null())
.order_by(ExampleRestaurant.object_type.restaurant_name.asc())
.iterate())
객체의 링크는 snake_case 메서드입니다. 단일 관계는 객체 또는 None, 다중 관계는 객체 집합을 반환합니다. 가상의 city와 reviews 링크를 사용한 예입니다.
restaurant = client.ontology.objects.ExampleRestaurant.get("restaurant-example")
if restaurant is None:
raise ValueError("식당 객체가 없습니다.")
city = restaurant.city()
review_count = restaurant.reviews().count().compute()
집합에서는 search_around_reviews()처럼 생성한 메서드를 사용합니다. 실행 중 이름만 아는 경우 search_around("reviews")를 사용할 수 있으며 유효한 링크가 아니면 RuntimeError가 발생합니다. 다중 링크 집합에도 page, where, group_by와 iterate를 사용할 수 있습니다.
필터
where에 object_type 속성으로 만든 조건을 전달합니다. Python의 일반 and/or/not 대신 &, |와 ~를 사용하고 비교식에는 괄호를 둡니다.
| 필터 | 의미 |
|---|---|
| contains_any_term | 공백으로 나눈 토큰 하나 이상, 순서와 대소문자 무관. fuzzy로 근사 검색 가능 |
| contains_all_terms | 모든 토큰, 순서와 대소문자 무관. fuzzy로 근사 검색 가능 |
| contains_all_terms_in_order | 모든 토큰이 순서대로 인접. prefix_last_term 기본 False |
| <, <=, >, >= | 숫자, String 및 날짜/시각 비교 |
| == | Boolean, 숫자, String 및 날짜/시각의 일치 |
| is_null() | 값이 없는지 검사. 인수 없음 |
| ~ | 조건 부정 |
| & | 모든 조건 만족 |
| | | 조건 중 하나 이상 만족 |
foo bar의 any는 bar baz에, all은 hello foo baz bar에, in_order는 hello foo bar baz에 일치하는 예입니다. prefix_last_term=True는 마지막 토큰의 접두사 일치를 허용합니다.
from ontology_sdk.ontology.objects import ExampleRestaurant
restaurants = client.ontology.objects.ExampleRestaurant.where(
(~ExampleRestaurant.object_type.restaurant_name.is_null())
& (ExampleRestaurant.object_type.number_of_reviews >= 10)
& (ExampleRestaurant.object_type.number_of_reviews < 100)
)
with_prefix = client.ontology.objects.ExampleRestaurant.where(
ExampleRestaurant.object_type.restaurant_name.contains_all_terms_in_order(["foo"], prefix_last_term=True)
)
is_member_of는 2.x에서 in_로 바뀌었으며 starts_with는 2.75.0부터 제거되었습니다. 접두사에는 contains_all_terms_in_order의 prefix_last_term을 사용합니다.
집계와 별칭
집계는 count, approximate_distinct, avg, max, min과 sum 뒤 compute를 호출합니다. 숫자 지표는 숫자 속성에 사용합니다. count 기본 이름은 count, 근사 고유값 개수는 distinctCount, 평균은 avg입니다. 이름이 있는 복수 집계는 aggregate에 이름과 연산의 딕셔너리를 전달합니다.
from ontology_sdk.ontology.objects import ExampleRestaurant
count = client.ontology.objects.ExampleRestaurant.count().compute()
average = client.ontology.objects.ExampleRestaurant.avg(
ExampleRestaurant.object_type.number_of_reviews
).compute()
metrics = client.ontology.objects.ExampleRestaurant.aggregate({
"metric_name": ExampleRestaurant.object_type.restaurant_name.approximate_distinct(),
"average_reviews": ExampleRestaurant.object_type.number_of_reviews.avg(),
}).compute()
단일 값 집계는 스칼라 결과를 반환합니다. group_by나 aggregate처럼 여러 값을 반환하는 계산은 AggregateObjectsResponse입니다. data의 group과 metrics, excluded_items와 accuracy를 읽을 수 있으며 to_dict()로 딕셔너리 표현을 얻습니다. raw HTTP의 data 포장을 단일 count 결과로 오해하면 안 됩니다.
그룹화
정확값 그룹은 생성 속성의 exact()를 group_by에 전달합니다. 고려할 최대 그룹 수가 필요하면 exact에 maxGroupCount에 해당하는 인수를 지정합니다.
from ontology_sdk.ontology.objects import ExampleRestaurant
by_name = (client.ontology.objects.ExampleRestaurant
.where(~ExampleRestaurant.object_type.restaurant_name.is_null())
.group_by(ExampleRestaurant.object_type.restaurant_name.exact())
.count().compute())
그룹 수 한도를 넘으면 누락 또는 근사 결과가 될 수 있으므로 accuracy와 제외 항목을 확인합니다. 반환 버킷 수와 객체 로드 한도는 다른 조건입니다.
연결 객체의 속성으로 그룹화
다대일 관계의 속성은 Beta 파생 속성으로 가져온 뒤 그룹화할 수 있습니다. 가상의 linked_object 링크와 linked_property 속성을 자신의 스키마에 맞춰 바꿉니다.
from foundry_sdk_runtime import AllowBetaFeatures
from ontology_sdk.ontology.objects import ExampleRestaurant
with AllowBetaFeatures():
result = (
client.ontology.objects.ExampleRestaurant.with_properties(
linked_property=ExampleRestaurant.object_type.derived.linked_object().linked_property.get()
)
.where(~ExampleRestaurant.object_type.derived.property("linked_property").is_null())
.group_by(ExampleRestaurant.object_type.derived.property("linked_property").exact())
.aggregate({"sum": ExampleRestaurant.object_type.number_of_reviews.sum()})
.compute()
.to_dict()
)
동적으로 추가한 속성에서 null을 제외하고 그룹 키로 사용한 뒤 지표를 계산하는 순서입니다.
액션
생성 액션은 client.ontology.actions에서 호출합니다. 다음은 가상의 action_example이 String parameter_example을 받는 계약입니다. action_config로 검증 및 실행 모드와 편집 반환을 정합니다.
from foundry_sdk_runtime.types import ActionConfig, ActionMode, ReturnEditsMode
from ontology_sdk import FoundryClient
def execute_action(client: FoundryClient, value: str):
response = client.ontology.actions.action_example(
parameter_example=value,
action_config=ActionConfig(mode=ActionMode.VALIDATE_AND_EXECUTE, return_edits=ReturnEditsMode.ALL),
)
if response.validation.result != "VALID":
raise ValueError("액션의 입력 또는 제출 조건을 충족하지 못했습니다.")
return response.edits
반환 타입은 SyncApplyActionResponse입니다. ValidationResult는 enum이 아니라 문자열 Literal이므로 "VALID"와 비교합니다. validation의 submission_criteria와 parameters에서 조건별 결과를 확인할 수 있습니다. REST Apply Action 요청에서 options.mode를 "VALIDATE_ONLY"로 지정하면 검증만 수행하며 실제 온톨로지 편집은 하지 않습니다.
배치 액션
client.ontology.batch_actions에 같은 액션의 요청 목록을 전달합니다. 생성한 BatchRequest 클래스와 BatchActionConfig를 사용하며 반환 타입은 BatchApplyActionResponse입니다.
from foundry_sdk_runtime.types import BatchActionConfig, ReturnEditsMode
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.action_types import ActionExampleBatchRequest
def execute_batch(client: FoundryClient, values: list[str]):
return client.ontology.batch_actions.action_example(
batch_action_config=BatchActionConfig(return_edits=ReturnEditsMode.ALL),
requests=[ActionExampleBatchRequest(parameter_example=value) for value in values],
)
한 요청이 실패하면 배치의 온톨로지 편집을 모두 적용하지 않습니다. 실제 외부 시스템 효과의 원자성은 액션 일관성을 따릅니다.
생성 쿼리의 반환
client.ontology.queries의 호출 인수는 모두 키워드 인수입니다. 반환 선언에 따라 다음을 실제 인스턴스로 받습니다.
| 함수 출력 | Python OSDK 2.x 반환 |
|---|---|
| 객체 | 객체 인스턴스. 기본 키 숫자나 문자열이 아님 |
| 객체 집합 | 객체 집합 인스턴스. 집합 RID가 아님 |
| 첨부 파일 | Attachment 인스턴스 |
| 2차원 집계 | QueryTwoDimensionalAggregation의 groups |
| 3차원 집계 | QueryThreeDimensionalAggregation의 groups 안에 NestedQueryAggregation.groups |
| 맵 | 선언한 키와 값 타입의 dict |
예를 들어 가져온 query_object_output이 object_id를 받으면 client.ontology.queries.query_object_output(object_id=1)로 호출합니다. 1은 해당 예제 쿼리의 숫자 키 입력이며 생성된 계약에 맞춰 실제 값과 타입을 사용합니다.
쿼리 집계의 groups 구조는 함수 작성용 functions.api.ThreeDimensionalAggregation의 buckets 구조와 다릅니다.
첨부 파일
upload(file_path, attachment_name)는 Attachment를 반환합니다. 다음은 호출자가 제공한 실제 로컬 파일을 업로드하고 메타데이터를 읽는 helper입니다.
from ontology_sdk import FoundryClient
def upload_attachment(client: FoundryClient, file_path: str, attachment_name: str):
attachment = client.ontology.attachments.upload(file_path=file_path, attachment_name=attachment_name)
return attachment, attachment.get_metadata()
read().getvalue()는 원본 바이트를 읽습니다. 업로드 후 1시간 안에 액션으로 객체의 첨부 속성에 연결하지 않으면 파일과 내용을 삭제하며, 연결 전에는 업로더만 읽을 수 있습니다. 함수에서 첨부 파일 처리는 생성과 연결의 예제를 제공합니다.
표지, 미디어와 벡터
Marking 및 Vector 속성은 Beta이며 AllowBetaFeatures 문맥에서 읽습니다. 보안 표지는 모든 적용된 요건을 만족한 사용자만 접근하게 하는 강제 통제입니다. 벡터는 float 목록을 담는 Vector이며 최근접 이웃 필터에도 사용할 수 있습니다.
from foundry_sdk_runtime import AllowBetaFeatures
from ontology_sdk.ontology.objects import Object
with AllowBetaFeatures():
object = client.ontology.objects.Object.get(1, properties=[Object.object_type.vector_property])
if object is None:
raise ValueError("대상 객체가 없습니다.")
vector = object.vector_property
Object, 키 1과 vector_property는 가상 스키마의 예입니다. 표지도 같은 Beta 문맥에서 해당 속성을 읽습니다.
Media 속성은 직접 읽을 수 있습니다. get_media_content는 BytesIO, get_media_metadata는 path, size_bytes와 media_type, get_media_reference는 미디어 집합 및 뷰와 항목 참조를 제공합니다. 타입별 전체 메타데이터 및 변환은 미디어 API를 따릅니다.
시나리오
시나리오는 Experimental이며 플랫폼 인스턴스의 제공 여부를 확인해야 합니다. 생성 패키지의 ScenarioClient.create는 실제 플랫폼에 시나리오를 만들고, 기존 RID를 제공하면 그 시나리오를 사용하는 클라이언트를 구성합니다.
from foundry_sdk_runtime import AllowBetaFeatures
from ontology_sdk import FoundryClient, ScenarioClient
def read_scenario_restaurant(client: FoundryClient, scenario_rid: str, primary_key: str):
with AllowBetaFeatures():
scenario = ScenarioClient(client, scenario_rid=scenario_rid)
return scenario.ontology.objects.ExampleRestaurant.get(primary_key)
이 조회는 시나리오의 격리된 상태에 적용합니다. 생성, 액션 및 병합과 버전 조건은 OSDK 시나리오, 1.x에서 옮기는 경우는 Python SDK 이전을 따릅니다.