函数类型参考手册
TypeScript 函数要发布到注册表,所有入参和返回值都必须显式标注类型。这一篇是全部可用类型的完整清单,写代码时当字典查。
https://www.palantir.com/docs/foundry/functions/types-reference/
原始标题:Functions > Types reference
先记住这几条
写在前面
要将 TypeScript 函数发布到注册表,必须为所有输入参数添加显式类型注解,并指定显式返回类型。以下列出了当前支持的全部函数注册表类型及其对应的语言类型。
在 Pipeline Builder 中将 Python 函数用作用户自定义函数(UDF)?下面这些标量类型(如 str 或 int)就是 UDF 返回的值,因为函数对每一行执行一次,其返回值会成为新的一列。你不需要返回 DataFrame。详细说明请查看Python 函数在 Pipeline Builder 中如何处理数据。
| Function registry type | TypeScript v1 type | TypeScript v2 type | Python type | ||||
|---|---|---|---|---|---|---|---|
| Attachment | Attachment | Attachment | Attachment | Example | |||
| Boolean | boolean | boolean | bool | Example | |||
| Binary | Not supported | Not supported | bytes | Example | |||
| Byte | Not supported | Not supported | int* | Example | |||
| Classification marking | ClassificationMarking | ClassificationMarking | ClassificationMarking | Example | |||
| Date | LocalDate | DateISOString | datetime.date | Example | |||
| Decimal | Not supported | Not supported | decimal.Decimal | Example | |||
| Double | Double | Double | float* | Example | |||
| Float | Float | Float | float | Example | |||
| GeoPoint | GeoPoint | Point | GeoPoint | Example | |||
| GeoShape | GeoShape | Geometry | GeoShape | Example | |||
| Group | Group | GroupId | GroupId | Example | |||
| Integer | Integer | Integer | int | Example | |||
| Interface | Not supported | Osdk.Instance<MyInterface> | Not supported | Example | |||
| Interface object set | Not supported | ObjectSet<MyInterface> | Not supported | Example | |||
| List | T[] or Array<T> | T[] or Array<T> | list[T] | Example | |||
| Long | Long | Long | int* | Example | |||
| Mandatory marking | MandatoryMarking | MandatoryMarking | MandatoryMarking | Example | |||
| Map | FunctionsMap<K, V> | Record<K, V> | dict[K, V] | Example | |||
| Media reference | MediaItem | Media | Media | Example | |||
| Notification | Notification | Notification | Notification | Example | |||
| Object | MyObjectType | Osdk.Instance<MyObjectType> | MyObjectType | Example | |||
| Object set | ObjectSet<MyObjectType> | ObjectSet<MyObjectType> | MyObjectTypeObjectSet | Example | |||
| Ontology edit | void | Edits | OntologyEdit | Example | |||
| Optional | `T \ | undefined` | `T \ | undefined` | typing.Optional or `T \ | None` | Example |
| Principal | Principal | Principal | Principal | Example | |||
| Range | IRange<T> | Range<T> | Range[T] | Example | |||
| Set | Set<T> | Not supported | set[T] | Example | |||
| Short | Not supported | Not supported | int* | Example | |||
| String | string | string | str | Example | |||
| Struct/custom type | interface | interface | dataclasses.dataclass | Example | |||
| Timestamp | Timestamp | TimestampISOString | datetime.datetime | Example | |||
| Two-dimensional aggregation | TwoDimensionalAggregation<K, V> | TwoDimensionalAggregation<K, V> | TwoDimensionalAggregation[K, V] | Example | |||
| Three-dimensional aggregation | ThreeDimensionalAggregation<K, S, V> | ThreeDimensionalAggregation<K, S, V> | ThreeDimensionalAggregation[K, S, V] | Example | |||
| User | User | UserId | UserId | Example |
尽管 Integer 和 Long 都对应 Python 的 int 类型,但函数签名中直接标注为 int 的字段会被注册为 Integer 类型。因此,我们建议改用 API 中的 Integer 或 Long 类型来注册数值型数据。Float 和 Double 同理:如果函数签名中直接写了 Python 的 float 类型,默认会被注册为 Float。
标量类型
标量类型
标量类型表示单个值,通常用于保存文本、数值或时间数据。
在 JavaScript 和 TypeScript 中,只有一个 number 类型,通常既用来表示整数也表示浮点数。为了提供更强的类型校验与结构约束,我们仅支持从 @foundry/functions-api 包(TypeScript v1 函数)和 @osdk/functions 包(TypeScript v2 函数)导出的数值别名类型。类似地,在 Python 函数中使用数值类型时,我们建议使用 functions.api 模块导出的类型别名。
Boolean
import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public isEven(num: Integer): boolean {
return num % 2 === 0;
}
}import { Integer } from "@osdk/functions";
function isEven(num: Integer): boolean {
return num % 2 === 0;
}
export default isEven;from functions.api import function, Integer
@function
def is_even(num: Integer) -> bool:
return n % 2 == 0String
import { Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public greet(name: string): string {
return `Hello, ${name}!`;
}
}function greet(name: string): string {
return `Hello, ${name}!`;
}
export default greet;from functions.api import function
@function
def greet(name: str) -> str:
return f"Hello, {name}!"Short
表示 -32,768 到 32,767 之间的整数值。
在 Python 函数中,Short 类型是内置 int 类型的别名。
from functions.api import function, Short
@function
def increment(num: Short) -> Short:
return num + 1Integer
表示 (-2<sup>31</sup>) 到 (2<sup>31</sup> - 1) 之间的整数值。
- 在 TypeScript v1 和 v2 函数中,
Integer类型都是内置number类型的别名。 - 在 Python 函数中,
Integer类型是内置int类型的别名。
import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public sum(a: Integer, b: Integer): Integer {
return a + b;
}
}import { Integer } from "@osdk/functions";
function sum(a: Integer, b: Integer): Integer {
return a + b;
}
export default sum;from functions.api import function, Integer
@function
def sum(a: Integer, b: Integer) -> Integer:
return a + bLong
表示 -(2<sup>53</sup> - 1) 到 (2<sup>53</sup> - 1) 之间的整数值。这些边界对应 JavaScript 中的 Number.MIN_SAFE_INTEGER 和 Number.MAX_SAFE_INTEGER,用于在函数从浏览器上下文调用时避免精度丢失。
- 在 TypeScript v1 函数中,
Long类型是内置number类型的别名;在 TypeScript v2 函数中,Long类型是内置string类型的别名。 - 在 Python 函数中,
Long类型是内置int类型的别名。
import { Function, Long } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public subtract(a: Long, b: Long): string {
return (BigInt(a) - BigInt(b)).toString();
}
}import { Long } from "@osdk/functions";
function subtract(a: Long, b: Long): string {
return (BigInt(a) - BigInt(b)).toString();
}
export default subtract;from functions.api import function, Long
@function
def subtract(a: Long, b: Long) -> str:
return str(a - b)Float
表示 32 位浮点数。
- 在 TypeScript v1 和 v2 函数中,
Float类型都是内置number类型的别名。 - 在 Python 函数中,
Float类型是内置float类型的别名。
import { Float, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public multiply(a: Float, b: Float): Float {
return a * b;
}
}import { Float } from "@osdk/functions";
function multiply(a: Float, b: Float): Float {
return a * b;
}
export default multiply;from functions.api import function, Float
@function
def multiply(a: Float, b: Float) -> Float:
return a * bDouble
表示 64 位浮点数。
- 在 TypeScript v1 和 v2 函数中,
Double类型都是内置number类型的别名。 - 在 Python 函数中,
Double类型是内置float类型的别名。
import { Double, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public divide(a: Double, b: Double): Double {
return a / b;
}
}import { Double } from "@osdk/functions";
function divide(a: Double, b: Double): Double {
return a / b;
}
export default divide;from functions.api import function, Double
@function
def divide(a: Double, b: Double) -> Double:
return a / bDecimal
from decimal import Decimal
from functions.api import function
@function
def return_pi() -> Decimal:
return Decimal('3.1415926535')Date
表示日历日期。
import { Function, LocalDate } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public returnDate(): LocalDate {
return LocalDate.fromISOString("1999-10-17");
}
}import { DateISOString } from "@osdk/functions";
function returnDate(): DateISOString {
return "1999-10-17";
}
export default returnDate;from datetime import date
from functions.api import function, Date
@function
def return_date() -> Date:
return date.fromisoformat('1999-10-17')Timestamp
表示时间轴上的一个时间点(时刻)。
import { Function, Timestamp } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getCurrentTimestamp(): Timestamp {
return Timestamp.now();
}
}import { TimestampISOString } from "@osdk/functions";
function getCurrentTimestamp(): TimestampISOString {
const now = new Date();
return now.toISOString();
}
export default getCurrentTimestamp;from datetime import datetime
from functions.api import function, Timestamp
@function
def get_current_timestamp() -> Timestamp:
return datetime.now()Binary
在 Python 函数中,Binary 类型是内置 bytes 类型的别名。
from functions.api import function
@function
def encode_utf8(param: str) -> bytes:
return param.encode('utf-8')Byte
在 Python 函数中,Byte 类型是内置 int 类型的别名。
from functions.api import function, Byte
@function
def get_first_byte(param: str) -> Byte:
if len(param) == 0:
raise Exception("String length cannot be zero.")
return param.encode('utf-8')[0]Mandatory marking
标记(Marking)是一种强制访问控制,要求用户必须拥有特定标记才能访问相应数据。
import { OntologyEditFunction, MandatoryMarking } from "@foundry/functions-api";
import { Employee, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee)
@OntologyEditFunction()
public async editMandatoryMarkings(markings: MandatoryMarking[]): Promise<void> {
const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0];
employeeOne.markingsProperty = markings;
}
}import { Client } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { Edits, createEditBatch, MandatoryMarking } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee>;
function editMandatoryMarkings(markings: MandatoryMarking[]): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
const employeeOne = await client(Employee).fetchOne(1);
batch.update(employeeOne, { markingsProperty: markings });
return batch.getEdits();
}
export default editMandatoryMarkings;from foundry_sdk_runtime import Marking
from functions.api import function, MandatoryMarking, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee
@function
def edit_mandatory_markings(markings: list[MandatoryMarking]) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
employee: Optional[Employee] = client.ontology.objects.Employee.get("primary_key")
if employee is None:
return []
editable_employee = ontology_edits.objects.Employee.edit(employee)
editable_employee.markings_property = [Marking(m) for m in markings]
# Assigning type "list[MandatoryMarking]" also works, but gives an LSP warning:
# editable_employee.markings_property = markings
return ontology_edits.get_edits()Classification marking
基于分类的访问控制(CBAC)是一种强制访问控制,用于保护敏感的政府信息。它要求用户必须拥有特定分类标记才能访问相应信息。
import { OntologyEditFunction, ClassificationMarking } from "@foundry/functions-api";
import { Employee, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee)
@OntologyEditFunction()
public async editClassificationMarkings(markings: ClassificationMarking[]): Promise<void> {
const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0];
employeeOne.markingsProperty = markings;
}
}import { Client } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { Edits, createEditBatch, ClassificationMarking } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee>;
function editClassificationMarkings(markings: ClassificationMarking[]): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
const employeeOne = await client(Employee).fetchOne(1);
batch.update(employeeOne, { markingsProperty: markings });
return batch.getEdits();
}
export default editClassificationMarkings;from foundry_sdk_runtime import Marking
from functions.api import ClassificationMarking, function, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee
@function
def edit_classification_markings(markings: list[ClassificationMarking]) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
employee: Optional[Employee] = client.ontology.objects.Employee.get("primary_key")
if employee is None:
return []
editable_employee = ontology_edits.objects.Employee.edit(employee)
editable_employee.markings_property = [Marking(m) for m in markings]
# Assigning type "list[ClassificationMarking]" also works, but gives an LSP warning:
# editable_employee.markings_property = markings
return ontology_edits.get_edits()集合类型
集合类型
集合类型由其他类型参数化。例如,Array[String] 是字符串列表,Map[String, Integer] 是以字符串为键、整数为值的字典。必须显式指定参数化类型,且该类型必须是另一种受支持的类型。Map 的键只能是标量类型或 Ontology 对象类型。
List
import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public filterForEvenIntegers(nums: Integer[]): Integer[] {
return nums.filter(num => num % 2 === 0);
}
}import { Integer } from "@osdk/functions";
function filterForEvenIntegers(nums: Integer[]): Integer[] {
return nums.filter(num => num % 2 === 0);
}
export default filterForEvenIntegers;from functions.api import function, Integer
@function
def filter_for_even_integers(nums: list[Integer]) -> list[Integer]:
return [n for n in nums if n % 2 == 0]Map
Map 通常用于以标量类型为键,访问与之关联、且可为任何其他函数注册表类型的值。
import { Function, FunctionsMap } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getMap(): FunctionsMap<string, string> {
const myMap = new FunctionsMap<string, string>();
myMap.set("Name", "Phil");
myMap.set("Favorite Color", "Blue");
return myMap;
}
}function getMap(): Record<string, string> {
const myMap: Record<string, string> = {};
myMap["Name"] = "Phil";
myMap["Favorite Color"] = "Blue";
return myMap;
}
export default getMap;from functions.api import function
@function
def get_map() -> dict[str, str]:
my_map = {}
my_map["Name"] = "Phil"
my_map["Favorite Color"] = "Blue"
return my_map此外,Map 还支持以 Ontology 对象作为键。
import { Function, FunctionsMap } from "@foundry/functions-api";
import { Airplane } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public getObjectMap(aircraft: Airplane[]): FunctionsMap<Airplane, Integer | undefined> {
const myMap = new FunctionsMap<Airplane, Integer | undefined>();
aircraft.forEach(obj => {
myMap.set(obj, obj.capacity);
});
return myMap;
}
}import { ObjectSpecifier, Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane } from "@ontology/sdk";
function getObjectMap(aircraft: Osdk.Instance<Airplane>[]): Record<ObjectSpecifier<Airplane>, Integer | undefined> {
const myMap: Record<ObjectSpecifier<Airplane>, Integer | undefined> = {};
aircraft.forEach(obj => {
myMap[obj.$objectSpecifier] = obj.capacity;
});
return myMap;
}
export default getObjectMap;from functions.api import function, Integer
from ontology_sdk.ontology.objects import Airplane
@function
def get_object_map(aircraft: list[Airplane]) -> dict[Airplane, Integer | None]:
my_map = {}
for a in aircraft:
my_map[a] = a.capacity
return my_mapSet
import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getSizeOfSet(mySet: Set<Integer>): Integer {
return mySet.size;
}
}from functions.api import function, Integer
@function
def get_size_of_set(my_set: set[Integer]) -> Integer:
return len(my_set)Optional
- 在 TypeScript 函数中,可选参数声明为
varName?: T或varName: T | undefined。例如,一个带有名为value的可选整数参数的函数,可声明为value?: Integer或value: Integer | undefined。TypeScript 函数也可以通过指定T | undefined类型来声明可选返回类型。例如,一个可能返回Integer或不返回任何值的函数,其返回类型为Integer | undefined。 - 在 Python 函数中,可选参数和返回值可使用
typing.Optional[T]或T | None声明。T | None语法需要 Python 3.10 或以上版本。 - 在 TypeScript 和 Python 函数中,都必须显式指定参数化类型
T,且它必须是另一种受支持的类型。
import { Function } from "@foundry/functions-api";
export class MyFunction {
@Function()
public greet(name?: string): string | undefined {
if (name === undefined) {
return undefined;
}
return `Hello, ${name}!`;
}
}function greet(name?: string): string | undefined {
if (name === undefined) {
return undefined;
}
return `Hello, ${name}!`;
}
export default greet;from functions.api import function
@function
def greet(name: str | None) -> str | None:
if name is None:
return None
return f"Hello, {name}!"函数还支持在函数签名中使用默认值。
import { Double, Function } from "@foundry/functions-api";
import { Customer } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public computeRiskFactor(customer: Customer, weight: Double = 0.75): Double {
// ...
}
}import { Double } from "@osdk/functions";
import { Osdk } from "@osdk/client";
import { Customer } from "@ontology/sdk";
function computeRiskFactor(customer: Osdk.Instance<Customer>, weight: Double = 0.75): Double {
// ...
}
export default computeRiskFactor;from functions.api import function, Double
from ontology_sdk.ontology.objects import Customer
@function
def compute_risk_factor(customer: Customer, weight: Double = 0.75) -> Double:
# ...Struct/custom type
自定义类型由其他受支持的类型(包括其他自定义类型)组合而成,可用于函数签名。
函数签名中使用的自定义类型,与用于 Ontology 结构体属性的生成类不同。若要在 Python 函数中编辑 Ontology 结构体属性,请使用生成的 struct 属性类,详见编辑结构体属性。
- 在 TypeScript 函数中,自定义类型是使用
interface关键字定义的 TypeScript 接口。 - 可选字段可通过
?可选标记,或与undefined组成的联合类型来支持。
- 在 Python 函数中,自定义类型是用户自定义的 Python 类。
- 要成为有效的自定义类型,该类必须满足以下要求:
- 类的所有字段都必须有类型注解。
- 字段类型必须是受支持的类型;可使用基础 API 类型或原生 Python 类型(如上文表格中所定义)。
__init__方法只能接受命名参数,且参数名与类型注解必须与字段一致。- 可使用 dataclasses.dataclass ↗ 装饰器自动生成符合上述要求的
__init__方法。
import { Function, Integer } from "@foundry/functions-api";
import { Passenger } from "@foundry/ontology-api";
interface PassengerInfo {
name?: string;
age?: Integer;
}
export class MyFunctions {
@Function()
public getPassengerInfo(passenger: Passenger): PassengerInfo {
return {
name: passenger.name,
age: passenger.age,
};
}
}import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Passenger } from "@ontology/sdk";
interface PassengerInfo {
name?: string;
age?: Integer;
}
function getPassengerInfo(passenger: Osdk.Instance<Passenger>): PassengerInfo {
return {
name: passenger.name,
age: passenger.age,
};
}
export default getPassengerInfo;from dataclasses import dataclass
from functions.api import function, Integer
from ontology_sdk.ontology.objects import Passenger
@dataclass
class PassengerInfo:
name: str | None
age: Integer | None
@function
def get_passenger_info(passenger) -> PassengerInfo:
return PassengerInfo(
name=passenger.name,
age=passenger.age
)聚合类型
聚合类型
聚合类型可从函数返回,供平台的其它部分使用,例如 Workshop 中的图表。
支持两种聚合类型:
聚合可以按以下几种类型作为键:
- Boolean 分桶表示值为
true或false。 - String 分桶可用于表示分类值。
- Range 分桶表示以值区间作为分桶键的聚合。可用于在图表中表示直方图或日期轴。
- 数值区间(包括 Integer 和 Double)表示对数值的分桶聚合。
- 日期与时间区间(包括 Date 和 Timestamp)表示对日期区间的分桶聚合。
Range
各版本字段名不同。TSv1 的 IRange<T> 和 Python 的 Range[T] 使用 min 和 max;TSv2 的 Range<T> 使用 startValue 和 endValue,且可省略其中之一以表示开区间。
import { Function, Integer, IRange } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getRange(min: Integer, max: Integer): IRange<Integer> {
return {
min,
max,
};
}
}import { Integer, Range } from "@osdk/functions";
function getRange(min: Integer, max: Integer): Range<Integer> {
return {
startValue: min,
endValue: max,
};
}
export default getRange;from functions.api import function, Integer, Range
@function
def get_range(min: Integer, max: Integer) -> Range[Integer]:
return Range(
min=min,
max=max
)Two-dimensional aggregation
import { Double, Function, TwoDimensionalAggregation } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public myTwoDimensionalAggregation(): TwoDimensionalAggregation<string, Double> {
return {
buckets: [
{ key: "bucket1", value: 5.0 },
{ key: "bucket2", value: 6.0 },
],
};
}
}import { Double, TwoDimensionalAggregation } from "@osdk/functions";
function myTwoDimensionalAggregationFunction(): TwoDimensionalAggregation<string, Double> {
return [
{ key: "bucket1", value: 5.0 },
{ key: "bucket2", value: 6.0 },
];
}
export default myTwoDimensionalAggregationFunction;from functions.api import (
function,
Double,
TwoDimensionalAggregation,
SingleBucket
)
@function
def my_two_dimensional_aggregation_function() -> TwoDimensionalAggregation[str, Double]:
return TwoDimensionalAggregation(
buckets=[
SingleBucket(key="bucket1", value=Double(5.0)),
SingleBucket(key="bucket2", value=Double(6.0)),
]
)Three-dimensional aggregation
分桶结构在各版本间不同。TSv1 将外层分桶包裹在 buckets 键下,内层以 value 为键。TSv2 返回一个扁平数组,内层位于 groups 下,因此 ThreeDimensionalAggregation<T, U, V> 解析为 { key: T; groups: { key: U; value: V }[] }[]。Python 与 TSv1 一样包裹外层分桶,并通过 NestedBucket 和 SingleBucket 类构建。
import { Double, Function, ThreeDimensionalAggregation } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public myThreeDimensionalAggregation(): ThreeDimensionalAggregation<string, string, Double> {
return {
buckets: [
{
key: "group-by-1",
value: [
{ key: "partition-by-1", value: 5.0 },
{ key: "partition-by-2", value: 6.0 },
],
},
{
key: "group-by-2",
value: [
{ key: "partition-by-1", value: 7.0 },
{ key: "partition-by-2", value: 8.0 },
],
},
]
};
}
}import { Double, ThreeDimensionalAggregation } from "@osdk/functions";
function myThreeDimensionalAggregation(): ThreeDimensionalAggregation<string, string, Double> {
return [
{
key: "group-by-1",
groups: [
{ key: "partition-by-1", value: 5.0 },
{ key: "partition-by-2", value: 6.0 },
],
},
{
key: "group-by-2",
groups: [
{ key: "partition-by-1", value: 7.0 },
{ key: "partition-by-2", value: 8.0 },
],
},
];
}
export default myThreeDimensionalAggregation;from functions.api import (
function,
Double,
ThreeDimensionalAggregation,
SingleBucket,
NestedBucket,
)
@function
def my_three_dimensional_aggregation_function() -> (
ThreeDimensionalAggregation[str, str, Double]
):
return ThreeDimensionalAggregation(
buckets=[
NestedBucket(key="group-by-1", buckets=[
SingleBucket(key="partition-by-1", value=Double(5.0)),
SingleBucket(key="partition-by-2", value=Double(6.0)),
]),
NestedBucket(key="group-by-2", buckets=[
SingleBucket(key="partition-by-1", value=Double(7.0)),
SingleBucket(key="partition-by-2", value=Double(8.0)),
])
]
)本体类型
本体类型
要在函数签名中使用对象类型,必须先将它们导入到你的代码仓库。了解有关 Ontology 导入的更多信息。
Object
来自你的 Ontology 的对象类型,既可作为函数签名的输入,也可作为输出。若要接收或返回单个对象类型实例,请从 Ontology SDK 导入该对象类型,并用它来注解你的函数。
import { Function, Integer } from "@foundry/functions-api";
import { Airplane } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public getCapacity(airplane: Airplane): Integer {
return airplane.capacity;
}
}import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane } from "@ontology/sdk";
function getCapacity(airplane: Osdk.Instance<Airplane>): Integer {
return airplane.capacity;
}
export default getCapacity;from functions.api import function, Integer
from ontology_sdk.ontology.objects import Airplane
@function
def get_capacity(airplane: Airplane) -> Integer:
return airplane.capacity在 TypeScript v2 中,对对象类型的引用可作为 struct 参数字段使用。若要接收包含对象类型实例的 struct 或 struct 列表,请创建一个带有 Ontology SDK 对象类型字段的自定义类型输入。它可以与 Ontology 编辑 配合,支持诸如「从其它对象类型派生出多个对象类型实例」之类的工作流。
import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane, Passenger, Ticket } from "@ontology/sdk";
type TicketEdit = Edits.Object<Ticket>
interface TicketInfo {
airplane?: Osdk.Instance<Airplane>;
passenger?: Osdk.Instance<Passenger>;
seat?: String;
}
function createTickets(ticketInfo: TicketInfo[]): TicketEdit[] {
const batch = createEditBatch<TicketEdit>(client);
ticketInfo.forEach(i => batch.create(TicketEdit, {
flightNumber: i.airplane.flightNumber,
passengerName: i.passenger.name,
seat: i.seat}))
return batch.getEdits();
}
export default createTickets;Object set
将对象集合传入或传出函数有两种方式:具体的对象集合(如数组),或对象集(object set)。
将对象数组传入函数,可以对一份具体的对象列表执行逻辑,代价是需要预先将所有对象加载到函数执行环境中。而对象集允许你执行筛选、周边检索和聚合操作,并且仅在请求时才加载最终结果。
我们建议使用对象集而非数组,因为对象集通常性能更好,且允许向函数传入超过 10,000 个对象。
下面的示例展示了如何在不将对象加载到内存的情况下筛选对象集,从而可将筛选后的对象集返回给应用的其他部分。
import { Function } from "@foundry/functions-api";
import { Airplane, ObjectSet } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public filterAircraft(aircraft: ObjectSet<Airplane>): ObjectSet<Airplane> {
return aircraft.filter(a => a.capacity.range().gt(200));
}
}import { ObjectSet } from "@osdk/client";
import { Airplane } from "@ontology/sdk";
function filterAircraft(aircraft: ObjectSet<Airplane>): ObjectSet<Airplane> {
return aircraft
.where({
capacity: {
$gt: 200,
}
});
}
export default filterAircraft;from functions.api import function
from ontology_sdk.ontology.objects import Airplane
from ontology_sdk.ontology.object_sets import AirplaneObjectSet
@function
def filter_aircraft(aircraft: AirplaneObjectSet) -> AirplaneObjectSet:
return aircraft.where(Airplane.object_type.capacity > 200)Interface
来自你的 Ontology 的接口类型,在 TypeScript v2 函数签名中既可作为输入也可作为输出。TypeScript v1 和 Python 不支持接口类型。
import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Person } from "@ontology/sdk";
function getAge(person: Osdk.Instance<Person>): Integer {
return person.age;
}
export default getAge;Interface object set
接口对象集在 TypeScript v2 函数签名中既可作为输入也可作为输出。
import { ObjectSet } from "@osdk/client";
import { Person } from "@ontology/sdk";
function filterPeople(people: ObjectSet<Person>): ObjectSet<Person> {
return people
.where({
age: {
$gt: 200,
}
});
}
export default filterPeople;Ontology edit
除了编写从 Ontology 读取数据的函数,你还可以编写创建对象、编辑对象属性及对象间链接的函数。有关编辑函数工作方式的更多细节,请参阅概览页。
要注册为编辑函数,TypeScript v1 函数需要在签名中声明 void 返回类型;而 TypeScript v2 和 Python 函数则需要显式返回一组 Ontology 编辑。
import { Edits, OntologyEditFunction } from "@foundry/functions-api";
import { Employee, LaptopRequest, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee, LaptopRequest)
@OntologyEditFunction()
public assignEmployee(newEmployee: Employee, leadEmployee: Employee): void {
const newLaptopRequest = Objects.create().laptopRequest(Date.now().toString());
newLaptopRequest.employeeName = newEmployee.name;
newEmployee.lead.set(leadEmployee);
}
}import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
import { Employee, LaptopRequest } from "@ontology/sdk";
type EmployeeEdit =
| Edits.Object<Employee>
| Edits.Object<LaptopRequest>
| Edits.Link<Employee, "lead">;
function assignEmployee(
client: Client,
newEmployee: Osdk.Instance<Employee>,
leadEmployee: Osdk.Instance<Employee>
): EmployeeEdit[] {
const batch = createEditBatch<EmployeeEdit>(client);
batch.create(LaptopRequest, {
id: Date.now().toString(),
employeeName: newEmployee.name,
});
batch.link(newEmployee, "lead", leadEmployee);
return batch.getEdits();
}
export default assignEmployee;from functions.api import function, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee, LaptopRequest
from time import time
@function
def assign_employee(new_employee: Employee, lead_employee: Employee) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
new_laptop_request = ontology_edits.objects.LaptopRequest.create(str(int(time() * 1000)))
new_laptop_request.employee_name = new_employee.name
new_employee.lead.set(lead_employee)
return ontology_edits.get_edits()Attachment
import { Attachment, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public loadAttachmentContents(attachment: Attachment): Promise<string> {
return attachment.readAsync().then(blob => blob.text());
}
}import { Attachment } from "@osdk/functions";
function loadAttachmentContents(attachment: Attachment): Promise<string> {
return attachment.fetchContents().then(response => response.text());
}
export default loadAttachmentContents;from functions.api import function, Attachment
@function
def load_attachment_contents(attachment: Attachment) -> str:
return attachment.read().getvalue().decode('utf-8')Notification
Notification 类型可从函数返回,用于灵活配置平台中应发送的通知。例如,你可以编写一个函数,接收 User 和某个对象类型等参数,并返回一条带有配置好消息内容的 Notification。
Notification由两个字段组成:ShortNotification和EmailNotificationContent。ShortNotification表示通知的精简版本,会在 Foundry 平台内展示。它包含一个简短的heading、content,以及一组Link。EmailNotificationContent表示通知的富文本版本,可通过邮件外发。它包含一个subject、由无头(headless)HTML 组成的body,以及一组Link。Link具有面向用户的label和linkTarget。LinkTarget可以是 URL、一个OntologyObject,或 Foundry 中任意资源的rid。
有关如何使用 Notifications API 的示例,请参阅我们的指南。
import {
EmailNotificationContent,
Function,
Notification,
ShortNotification,
} from "@foundry/functions-api";
export class MyFunctions {
@Function()
public buildNotification(): Notification {
return Notification.builder()
.shortNotification(ShortNotification.builder()
.heading("Issue reminder")
.content("Investigate this issue.")
.build())
.emailNotificationContent(EmailNotificationContent.builder()
.subject("New issue")
.body("hello")
.build())
.build();
}
}import {
Notification
} from "@osdk/functions";
export default function buildNotification(): Notification {
return {
platformNotification: {
heading: "Issue reminder",
content: "Investigate this issue.",
links: []
},
emailNotification: {
subject: "New issue",
body: "hello",
links: []
}
};
}from functions.api import function, Notification, PlatformNotification, EmailNotification
@function()
def buildNotification() -> Notification:
return Notification(
platform_notification=PlatformNotification(
heading="Issue reminder",
content="Investigate this issue.",
links=[]
),
email_notification=EmailNotification(
subject="New issue",
body="hello",
links=[]
),
)
媒体类型
媒体类型
Media
函数可以接收和返回媒体项。在 TypeScript v1 中使用 MediaItem 类型;在 TypeScript v2 和 Python 中,使用 Media 作为入参和出参类型。调用方可以将已有的 MediaReference(例如对象上的媒体属性)传入函数。下游使用者可利用返回值获取内容、获取元数据,或将其附加到另一个对象上。更多信息请参阅媒体指南。
import { Function, MediaItem } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public async echoMedia(media: MediaItem): Promise<string | undefined> {
const mimeType: string = media.mimeType;
// Fetch type-specific metadata (page count, dimensions, duration, and so on)
const metadata = await media.getMetadataAsync();
// Read the binary contents as a Blob
const contents: Blob = await media.readAsync();
// Narrow to a specialized subtype to call type-specific methods
if (MediaItem.isDocument(media)) {
const text = await media.extractTextAsync({ startPage: 0, endPage: 1 });
} else if (MediaItem.isAudio(media)) {
const transcript = await media.transcribeAsync();
}
return undefined;
}
}import type { Media } from "@osdk/client";
export default async function echoMedia(media: Media): Promise<Media> {
// Get the underlying MediaReference
const mediaReference = media.getMediaReference();
// Fetch slim metadata: path, sizeBytes, mediaType
const metadata = await media.fetchMetadata();
// Fetch contents as a Response; call .blob() or .arrayBuffer() for bytes
const response = await media.fetchContents();
const contents = await response.blob();
return media;
}from foundry_sdk.v2.core.models import MediaReference
from functions.api import function, Media
@function
def echo_media(media: Media) -> Media:
# Get the underlying MediaReference
media_reference: MediaReference = media.get_media_reference()
# Fetch slim metadata: path, size_bytes, media_type
metadata = media.get_media_metadata()
# Fetch type-specific metadata (page count, dimensions, duration, and more by type)
full_metadata = media.get_media_full_metadata()
# Fetch the binary contents as a BytesIO stream
contents = media.get_media_content()
return media用户、组与主体
用户、组与主体
Principal 表示 Foundry 用户账户或用户组。这些类型可以传入函数,以便访问与用户或用户组关联的信息,例如用户组名称、用户的姓与名或电子邮件地址。所有 Principal 类型都从 @foundry/functions-api 包导出。
User始终拥有 username,并可能拥有firstName、lastName或email。它还包含与Principal关联的所有字段。Group拥有一个 name。它还包含与Principal关联的所有字段。Principal可以是User或Group。你可以检查type字段来判断某个Principal是User还是Group。除了User和Group各自的字段外,Principal还拥有id、realm,以及一个attributes字典。
User
import { Function, User } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getUserEmail(user: User): string {
return user.email;
}
}import { UserId } from "@osdk/functions";
import { Users } from "@osdk/foundry.admin";
import { Client } from "@osdk/client";
export default function getUserEmail(client:Client, userId: UserId): string {
const user = Users.get(client, userId)
return user.email;
}from functions.api import function, UserId
from foundry_sdk import FoundryClient
import foundry_sdk
@function()
def getUserEmail(user_id: UserId) -> string:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
user = client.admin.User.get(user_id)
return user.emailGroup
import { Function, Group } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getGroupName(group: Group): string {
return group.name;
}
}import { GroupId } from "@osdk/functions";
import { Groups } from "@osdk/foundry.admin";
import { Client } from "@osdk/client";
export default function getGroupName(client: Client, groupId: GroupId): string {
const group = Groups.get(client, groupId)
return group.name;
}from functions.api import function, GroupId
from foundry_sdk import FoundryClient
import foundry_sdk
@function()
def getGroupName(group_id: GroupId) -> string:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
group = client.admin.Group.get(group_id)
return group.namePrincipal
import { Function, Principal } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getPrincipalType(principal: Principal): string {
switch (principal.type) {
case "user":
return "User";
case "group":
return "Group";
default:
return "Unknown";
}
}
}import { GroupId, Principal, UserId } from "@osdk/functions";
export default async function getPrincipals(client: Client, userId: UserId, groupId: GroupId): Principal[] {
return [{type: "user", id: userId}, {type: "group", id: groupId}];
}from functions.api import Array, function, GroupId, Principal, UserId
@function()
def getPrincipals(user_id: UserId, group_id: GroupId) -> Array[Principal]:
return [Principal.user(user_id), Principal.group(group_id)]几何类型
几何类型
几何类型表示函数中的空间数据与地理形状。支持两种几何类型:
- GeoPoint 表示具有经纬度坐标的单个地理点。
- GeoShape 表示任意合法的 GeoJSON 几何,包括点(Points)、多边形(Polygons)、线(LineStrings)及其它形状。
这些类型遵循 GeoJSON 规范 ↗,可用于空间运算、地图绘制和地理分析。位置参数遵循 GeoJSON 规范中的「经度、纬度」顺序。
GeoPoint
下面的示例展示了如何创建并返回 GeoPoint。
import { Function, GeoPoint } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public createPoint(): GeoPoint {
return GeoPoint.fromCoordinates({
latitude: 37.7749,
longitude: -22.4194
});
}
}import { Point } from "@osdk/functions";
function createPoint(): Point {
return {
type: "Point",
coordinates: [-22.4194, 37.7749]
};
}
export default createPoint;from functions.api import function, GeoPoint
@function
def create_point() -> GeoPoint:
return GeoPoint(type="Point", coordinates=[-22.4194, 37.7749])GeoShape
下面的示例展示了如何创建并返回 Polygon。
import { Function, Polygon, GeoPoint } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public createPolygon(): Polygon {
const ring: GeoPoint[] = [
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.4 }),
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.5 }),
GeoPoint.fromCoordinates({ latitude: 37.7, longitude: -22.5 }),
GeoPoint.fromCoordinates({ latitude: 37.7, longitude: -22.4 }),
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.4 })
];
return Polygon.fromLinearRings([ring]);
}
}import { Geometry } from "@osdk/functions";
function createPolygon(): Geometry {
return {
type: "Polygon",
coordinates: [[
[-22.4, 37.8],
[-22.5, 37.8],
[-22.5, 37.7],
[-22.4, 37.7],
[-22.4, 37.8]
]]
};
}
export default createPolygon;from functions.api import function, Polygon
@function
def create_polygon() -> Polygon:
return Polygon(
type="Polygon",
coordinates=[[
[-22.4, 37.8],
[-22.5, 37.8],
[-22.5, 37.7],
[-22.4, 37.7],
[-22.4, 37.8]
]])Ontology 编辑函数 可以从 GeoJSON 字符串设置 geoshape 属性,但转换步骤因语言而异:
- TypeScript v1:
GeoShape.fromGeoJson()接受已解析的 GeoJSON 几何或几何集合,因此传入前需先将字符串解析。 - TypeScript v2:
Geometry就是一个普通的 GeoJSON 对象,因此无需转换函数,直接将解析后的值赋值即可。 - Python: 每个具体几何类(如
Polygon或LineString)都提供from_geo_json()方法,可直接接收 JSON 字符串。GeoShape类型不提供此方法,因此请使用与实际几何相符的类。
下面的示例从 JSON 字符串设置 Region 对象的 geoshape 属性。
import { OntologyEditFunction, Edits, GeoShape } from "@foundry/functions-api";
import { Region } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Region)
@OntologyEditFunction()
public updateBoundary(region: Region, boundary: string): void {
region.boundary = GeoShape.fromGeoJson(JSON.parse(boundary));
}
}import { Region } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Geometry } from "@osdk/functions";
type RegionEdit = Edits.Object<Region>;
function updateBoundary(
client: Client,
region: Osdk.Instance<Region>,
boundary: string
): RegionEdit[] {
const batch = createEditBatch<RegionEdit>(client);
batch.update(region, { boundary: JSON.parse(boundary) as Geometry });
return batch.getEdits();
}
export default updateBoundary;from functions.api import function, OntologyEdit, Polygon
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Region
@function(edits=[Region])
def update_boundary(region: Region, boundary: str) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
editable_region = ontology_edits.objects.Region.edit(region)
editable_region.boundary = Polygon.from_geo_json(boundary)
return ontology_edits.get_edits()延伸阅读 · 相关页面
按主题横向跳转,不必顺着目录一篇篇读。
常见问题速答 · FAQ
关于「函数类型参考手册」,读者最常问的几个问题。