코드 스펙(Code specs)
코드 스펙(Code specs)
어떤 콜라보레이터든 커스텀 Python 함수, 저장 프로시저, ML Jobs를 콜라보레이션 템플릿과 함께 패키징할 수 있어요. 템플릿은 코드 스펙을 참조해 콜라보레이션에서 복잡한 데이터 작업을 수행해요.
출처: 문서
본문
기능 — 일반 공개(Generally Available)
현재 지원 리전: 이 리전들에서 사용할 수 있어요.
정부 및 VPS 배포에서는 사용할 수 없어요.
어떤 콜라보레이터든 커스텀 Python 함수, 저장 프로시저, ML Jobs를 콜라보레이션 템플릿과 함께 패키징할 수 있어요. 템플릿은 코드 스펙을 참조해 콜라보레이션에서 복잡한 데이터 작업을 수행해요. 일반적인 사용은 쿼리 안에서의 머신러닝 또는 커스텀 데이터 조작이에요. 업로드한 코드는 승인된 Python 패키지 번들과 Snowpark API의 패키지를 가져와 사용할 수 있어요.
커스텀 코드는 템플릿을 통해서만 호출할 수 있고 직접 호출할 수는 없어요.
참고
함수와 저장 프로시저 코드 스펙에 지원되는 프로그래밍 언어는 Python이 유일해요. ML Jobs 코드 스펙도 Python으로 실행되지만,
pip_requirements로 추가 패키지를 설치할 수 있는 컴퓨트 풀의 Snowpark Container Services 컨테이너 안에서 실행돼요.
코드 스펙 유형 선택
코드 스펙은 세 가지 실행 유형을 지원해요. 템플릿이 무엇을 해야 하는지에 따라 선택하세요:
- ML Jobs — 리소스 집약적인 ML 워크로드용: 학습, 스코어링, 하이퍼파라미터 최적화, 또는 GPU 가속·분산 컴퓨트가 필요하거나 Anaconda 번들 너머의 패키지가 필요한 워크로드. Data Clean Rooms의 ML Jobs를 참고하세요.
- 함수(UDF/UDTF) — 값을 계산하고 반환하는 로직으로 SQL에서 인라인으로 호출할 수 있어요. 사용자 정의 함수 개요를 참고하세요.
- 저장 프로시저 — DML 또는 DDL을 실행하거나 여러 데이터베이스 작업을 순서대로 오케스트레이션해야 하는 로직용. 저장 프로시저 개요와 저장 프로시저 또는 UDF 선택을 참고하세요.
다음 섹션에서 코드 스펙을 업로드하고 사용하는 방법을 보여줘요.
커스텀 코드 스펙 구현
코드 스펙을 업로드하고 사용하는 방법은 다음과 같아요:
코드 제출자:
- REGISTER_CODE_SPEC을 호출해 코드를 만들고 등록해요. 코드는 스펙에 인라인으로 넣거나 스테이지에서 링크할 수 있어요.
- 템플릿의
code_specs배열에 코드 스펙 ID로 참조하는 템플릿을 만들어요. 아래 예시처럼 이 필드를 템플릿·파라미터 필드와 같은 레벨에 추가해요:
parameters:
- name: <parameter_name>
description: <parameter_description>
required: <true_or_false>
default: <default_value>
type: <data_type>
code_specs: # Optional: List of code specs used by this template
- <code_spec_id> # One or more code spec IDs.
template: |
<template_content>
- 템플릿을 등록한 뒤 콜라보레이션에 템플릿을 링크해요.
분석 실행자:
RUN을 호출해 표준 방식으로 템플릿을 실행해요.
중요
Snowflake는 업로드된 모든 코드 스펙을 클린룸에 배포하기 전에 보안 검사를 실행해요. 보안 검사가 실패하면 템플릿과 코드 스펙은 배포되지 않고 사용할 수 없어요.
코드 스펙이 있는 템플릿이 배포되어 사용할 준비가 되었는지 확인하려면 다음 단계를 따르세요:
- 코드 스펙을 배포하려는 클린룸 애플리케이션의 이름을 찾아요:
SHOW APPLICATIONS LIKE 'SFDCR_<collaboration name>';
- DESCRIBE APPLICATION 응답에서
upgrade_state값을 확인해요. upgrade state가 COMPLETE이면 보안 검사가 통과되었고 새 템플릿과 코드 스펙을 사용할 수 있어요. 이전 단계에서 반환된 애플리케이션 이름을 다음 예시 같은 SQL로 전달하세요:DESCRIBE APPLICATION <application name>
코드 스펙 생성 및 등록
커스텀 코드를 업로드하는 첫 단계는 코드 스펙을 만들고 등록하는 것이에요.
커스텀 함수는 YAML 코드 스펙으로 정의돼요. 각 코드 스펙은 템플릿이 호출할 수 있는 하나 이상의 함수를 노출해요. 코드 스펙은 코드를 스펙에 인라인으로 포함하거나, Snowflake 스테이지에 있는 코드를 링크할 수 있어요.
콜라보레이터는 REGISTRY.REGISTER_CODE_SPEC을 호출해 스펙을 등록하며, 이 호출은 코드 스펙 ID를 반환해요.
코드 스펙을 참조하는 템플릿이 콜라보레이션에 링크된 뒤에는, 그 코드 스펙을 링크한 템플릿에 접근할 수 있는 콜라보레이션의 모든 사람에게 코드 스펙이 보여요. 콜라보레이션에서 접근 가능한 코드 스펙을 나열하려면 VIEW_CODE_SPECS를 호출하세요.
콜라보레이션에서 코드 스펙을 볼 수 있는 사람은 누구나 그 콜라보레이션에서 자신의 템플릿에서 코드 스펙을 보고 사용할 수 있어요. 인라인 코드는 콜라보레이션의 모든 구성원이 볼 수 있지만, 스테이징된 아티팩트 코드는 콜라보레이터가 볼 수 없어요. 콜라보레이터는 코드 무결성 검증을 위해 참조된 아티팩트의 content_hash가 일치하는지 확인해야 해요.
다음 코드 스펙은 normalize_value라는 단일 Python UDF를 노출하며, 그 스펙에 정의된 normalize 함수를 호출해요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_CODE_SPEC(
$$
api_version: 2.0.0
spec_type: code_spec
name: custom_udf
version: v1
functions:
- name: normalize_value
type: UDF
language: PYTHON
handler: normalize
arguments:
- name: value
type: FLOAT
returns: FLOAT
code_body: |
def normalize(value):
return value / 100.0
$$
);
호출 템플릿 생성 및 등록
코드 스펙이 등록된 뒤 콜라보레이터는 이 코드 스펙을 사용하는 템플릿을 등록해요. 코드 스펙을 사용하려면 템플릿의 code_specs 필드에 코드 스펙 ID를 추가해요. 이 템플릿을 콜라보레이션에 추가하면 코드 스펙도 콜라보레이션에서 사용 가능해져요.
템플릿은 cleanroom.spec_name$function_name 문법으로 커스텀 함수를 호출해요. 리터럴 .과 $ 이름 스코핑 표시에 주의하세요.
참고
템플릿에서 함수를 참조할 때는 스펙 ID가 아니라 스펙 이름을 사용하세요. 그래야 템플릿의 모든 참조를 바꾸지 않고도 코드 스펙 버전을 빠르게 업데이트할 수 있어요.
다음 예시에서 템플릿은 코드 스펙 custom_udf의 normalize_value 함수를 사용해요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: normalization_template
version: v1
type: sql_analysis
code_specs:
- custom_udf_v1 -- Imports the code spec.
template: |
SELECT cleanroom.custom_udf$normalize_value(100) -- Calls the UDF.
AS normalized
FROM {{ source_tables[0] }}
$$
);
템플릿을 콜라보레이션에 추가
함수를 호출하는 템플릿을 표준 방식으로 콜라보레이션에 추가해요. 자세한 내용은 템플릿(Templates)을 참고하세요.
Snowflake는 호출 템플릿이 콜라보레이션에 추가될 때 검증하고 콜라보레이션에 업로드해요. 다음 예시는 기존 콜라보레이션에 템플릿을 추가하는 요청을 보여줘요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.ADD_TEMPLATE_REQUEST(
'my_collaboration',
'normalization_template_v1',
['consumer']
);
참고
코드 스펙이 있는 템플릿을 설치하면 Snowflake 보안 검사가 트리거되고 기본 클린룸의 새 패치가 발행돼요. 프로세스가 완료되고 패치가 설치될 때까지 템플릿은 사용할 수 없어요.
패치 설치 진행 상황을 확인하려면:
- 클린룸 애플리케이션의 이름을 찾아요. 일반적으로
SFDCR_<clean room name>이지만, 검색해서 확인할 수 있어요:-- Find the exact name of the clean room application. SHOW APPLICATIONS LIKE 'SFDCR_%';
- 패치 설치 상태를 확인해요. 다음 쿼리에서
upgrade_state가 COMPLETE가 될 때까지 기다려요:DESCRIBE APPLICATION SFDCR_<application name>;
코드 버전 관리
등록된 모든 코드 스펙은 계정의 모든 레지스트리에서 고유한 이름 + 버전을 가져야 해요. 템플릿은 코드 스펙의 특정 이름과 버전을 로드해요. 코드의 새 버전을 만들거나 소비하려면 code_specs 필드에서 새 코드 버전을 참조하는 템플릿의 새 버전을 제출해야 해요. 템플릿 본문은 바꿀 필요가 없어요. 예:
참고
템플릿과 데이터 오퍼링과 달리 코드 스펙은 등록 취소할 수 없어요. 코드를 변경하려면 새 버전을 등록하고 이 섹션에서 설명한 대로 템플릿에서 참조하세요.
1단계: 코드 스펙 버전 1 소비:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: normalization_template
version: v1
type: sql_analysis
code_specs:
- custom_udf_v1 -- Code spec ID includes the version number.
template: |
SELECT cleanroom.custom_udf$normalize_value(100) -- Calls the UDF.
AS normalized
FROM {{ source_tables[0] }}
$$
);
2단계: 코드 스펙의 새 버전을 업데이트·등록하고, 템플릿이 새 버전을 사용하도록 업데이트:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: normalization_template
version: v2 -- Update the template version.
type: sql_analysis
code_specs:
- custom_udf_v2 -- Use the new code spec.
template: |
SELECT cleanroom.custom_udf$normalize_value(100) -- No change needed here.
AS normalized
FROM {{ source_tables[0] }}
$$
);
함수 이름에는 버전이 포함되지 않으므로, 함수의 새 버전을 업로드할 때 템플릿 본문의 호출 코드를 변경할 필요가 없다는 점을 알아두세요.
예시 스펙
- 코드 본문이 있는 인라인 UDF
- UDTF(사용자 정의 테이블 함수)
- wheel 패키지가 있는 스테이징된 아티팩트
- 저장 프로시저
- 스테이징된 아티팩트로 여러 Python 파일
인라인 코드 본문이 있는 UDF
인라인 Python 코드가 있는 간단한 UDF:
api_version: 2.0.0
spec_type: code_spec
name: string_utils
version: v1
description: String utility functions
functions:
- name: clean_string
type: UDF
language: PYTHON
runtime_version: "3.10"
handler: clean
arguments:
- name: input_str
type: STRING
returns: STRING
description: Removes leading/trailing whitespace and converts to lowercase
code_body: |
def clean(input_str):
if input_str is None:
return None
return input_str.strip().lower()
- name: extract_domain
type: UDF
language: PYTHON
runtime_version: "3.10"
handler: extract
arguments:
- name: email
type: STRING
returns: STRING
description: Extracts domain from email address
code_body: |
def extract(email):
if email is None or '@' not in email:
return None
return email.split('@')[1]
UDTF(사용자 정의 테이블 함수)
이 예시 YAML은 여러 행을 반환하는 UDTF를 정의해요:
api_version: 2.0.0
spec_type: code_spec
name: tokenizer
version: v1
description: Text tokenization UDTF
functions:
- name: tokenize_text
type: UDTF
language: PYTHON
runtime_version: "3.10"
handler: Tokenizer
arguments:
- name: text
type: STRING
- name: delimiter
type: STRING
returns: TABLE(token STRING, position INTEGER)
description: Splits text into tokens and returns each with its position
code_body: |
class Tokenizer:
def process(self, text, delimiter):
if text is None:
return
tokens = text.split(delimiter if delimiter else ' ')
for i, token in enumerate(tokens):
yield (token.strip(), i)
wheel 패키지가 있는 스테이징된 아티팩트
코드 스펙에서 스테이징된 코드를 링크하기 위한 stage_path 문서 요구 사항을 꼭 읽어 보세요.
이 예시 YAML은 스테이징된 Python wheel 패키지를 사용해요:
api_version: 2.0.0
spec_type: code_spec
name: ml_scoring
version: v2
description: ML scoring functions using custom library
artifacts:
- alias: ml_lib
stage_path: "@MY_DB.PUBLIC.CODE_STAGE/libs/ml_scoring_lib-1.0.0-py3-none-any.whl"
description: Custom ML scoring library
content_hash: "a1b2c3d4e5f6..."
functions:
- name: predict_score
type: UDF
language: PYTHON
runtime_version: "3.10"
handler: ml_scoring_lib.predictor.predict
arguments:
- name: features
type: ARRAY
returns: FLOAT
packages:
- numpy
- scikit-learn
imports:
- ml_lib
description: Predicts score using trained ML model
저장 프로시저
이 예시 YAML은 데이터 처리를 위한 저장 프로시저를 정의해요:
api_version: 2.0.0
spec_type: code_spec
name: data_processor
version: v1
description: Data processing procedures
procedures:
- name: aggregate_metrics
language: PYTHON
runtime_version: "3.10"
handler: process
arguments:
- name: table_name
type: STRING
- name: group_column
type: STRING
returns: STRING
packages:
- snowflake-snowpark-python
description: Aggregates metrics by specified column
code_body: |
def process(session, table_name, group_column):
df = session.table(table_name)
result = df.group_by(group_column).count()
result.write.mode("overwrite").save_as_table("aggregated_results")
return f"Aggregated {df.count()} rows into aggregated_results"
스테이징된 아티팩트로 여러 Python 파일
코드 스펙에서 스테이징된 코드를 링크하기 위한 stage_path 문서 요구 사항을 꼭 읽어 보세요.
이 예시 YAML은 여러 스테이징된 Python 소스 파일을 사용해요:
api_version: 2.0.0
spec_type: code_spec
name: analytics_suite
version: v3
description: Analytics suite with multiple modules
artifacts:
- alias: utils
stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/utils.py"
description: Utility functions
- alias: transformers
stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/transformers.py"
description: Data transformation functions
- alias: validators
stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/validators.py"
description: Validation functions
functions:
- name: transform_and_validate
type: UDF
language: PYTHON
runtime_version: "3.10"
handler: transformers.transform_validate
arguments:
- name: data
type: OBJECT
returns: OBJECT
imports:
- utils
- transformers
- validators
description: Transforms and validates input data