Generated Types
This page documents what type definitions in TypeSpec are generated as in emitted libraries
Models
Flattening
NOTE: Flattening is NOT a recommended pattern, and you shouldn’t use it unless told by SDK architects.
model Properties { name: string;}
model Foo { @flattenProperty prop: Properties;}{ "kind": "model", "name": "Foo", "properties": [ { "kind": "property", "name": "prop", "serializedName": "prop", "flatten": true, "optional": false, "type": { "kind": "model", "name": "Properties", "properties": [ { "kind": "property", "name": "name", "serializedName": "name", "flatten": false, "optional": false, "type": { "kind": "string", "encode": "string" } } ] } } ]}Python will do dynamic flattening, exposing the non-flattening syntax, and dynamically accepting the flattened access.
class Properties(_model_base.Model): name: str = rest_field() """Required."""
class Foo(_model_base.Model): properties: "_models.Properties" = rest_field() """Required."""
__flattened_items = ["properties"]
print(f.properties.name) # Non-flattened access is preferred experienceprint(f.name) # Flattened access is dynamically supported, but not documentedCSharp will generate the model with properties being flattened. During serialization/deserialization, the model will be serialized/deserialized as a non-flattened model.
public partial class Foo{ public Foo(string name) { Argument.AssertNotNull(name, nameof(name));
Name = name; }
public string Name { get; set; }}
public partial class Foo : IUtf8JsonSerializable, IJsonModel<Foo>{ void IJsonModel<Foo>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { var format = options.Format == "W" ? ((IPersistableModel<Foo>)this).GetFormatFromOptions(options) : options.Format; if (format != "J") { throw new FormatException($"The model {nameof(Foo)} does not support writing '{format}' format."); }
writer.WriteStartObject(); writer.WritePropertyName("properties"u8); writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); writer.WriteEndObject(); writer.WriteEndObject(); }
internal static Foo DeserializeFoo(JsonElement element, ModelReaderWriterOptions options = null) { options ??= ModelSerializationExtensions.WireOptions;
if (element.ValueKind == JsonValueKind.Null) { return null; } string name = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("properties"u8)) { if (property.Value.ValueKind == JsonValueKind.Null) { property.ThrowNonNullablePropertyIsNull(); continue; } foreach (var property0 in property.Value.EnumerateObject()) { if (property0.NameEquals("name"u8)) { name = property0.Value.GetString(); } } } } return new Foo(name); }}// Please note that this feature is not supported right now, and the model will be generated un-flattened.// Please comment and follow work status on: https://github.com/Azure/autorest.typescript/issues/2164In Java, @flattenProperty have no effect on generated libraries.
@Fluentpublic final class Properties { public Properties(); public String getName(); public Properties setName(String name);}Models with additional properties
Additional properties of any type
Recommend usage:
model Animal { name: string; kind: string; ...Record<unknown>;}Other usages:
model Animal extends Record<unknown> { name: string; kind: string;}model Animal is Record<unknown> { name: string; kind: string;}{ "kind": "model", "name": "Animal", "properties": [ { "kind": "property", "name": "name", "serializedName": "name", "optional": false, "type": { "kind": "string", "encode": "string" } }, { "kind": "property", "name": "kind", "serializedName": "kind", "optional": false, "type": { "kind": "string", "encode": "string" } } ], "additionalProperties": { "kind": "any" }}Python models are designed to support adding any additional properties.
from .. import _model_basefrom .._model_base import rest_field
class Animal(_model_base.Model):
name: str = rest_field() kind: str = rest_field()
animal = Animal(name="Tom", kind="Cat")animal["friend"] = "Jerry"animal["age"] = 5public partial class Animal : IJsonModel<Animal> { public Animal(string name, string kind);
public string Name { get; } public string Kind { get; }
public IDictionary<string, BinaryData> AdditionalProperties { get; }}// RLC inputexport interface Animal extends Record<string, unknown> { name: string; kind: string;}
// RLC outputexport interface AnimalOutput extends Record<string, any> { name: string; kind: string;}
// Modular for both legacy and non legacyexport interface Animal extends Record<string, any> { name: string; kind: string;}@Fluentpublic final class Animal implements JsonSerializable<Animal> { public Animal(String name, String kind); public String getName(); public String getKind(); public Map<String, Object> getAdditionalProperties(); public Animal setAdditionalProperties(Map<String, Object> additionalProperties);}Additional properties of specific type
model AnimalProperty { category: string; value: unknown;}
model Animal { name: string; kind: string; ...Record<AnimalProperty>;}{ "kind": "model", "name": "Animal", "properties": [ { "kind": "property", "name": "name", "serializedName": "name", "optional": false, "type": { "kind": "string", "encode": "string" } }, { "kind": "property", "name": "kind", "serializedName": "kind", "optional": false, "type": { "kind": "string", "encode": "string" } } ], "additionalProperties": { "kind": "model", "name": "AnimalProperty", "properties": [ { "kind": "property", "name": "category", "serializedName": "category", "optional": false, "type": { "kind": "string", "encode": "string" } }, { "kind": "property", "name": "value", "serializedName": "value", "optional": false, "type": { "kind": "any" } } ], "additionalProperties": undefined }}Python models are designed to support adding any additional properties.
from typing import Anyfrom .. import _model_basefrom .._model_base import rest_field
class Animal(_model_base.Model):
name: str = rest_field() kind: str = rest_field()
class AnimalProperty(_model_base.Model):
category: str = rest_field() value: Any = rest_field()
animal = Animal(name="Tom", kind="Cat")animal["friend"] = AnimalProperty(category="relationship", value="Jerry")animal["age"] = AnimalProperty(category="attribute", value=5)Due to currently there is no way to know whether a Json could be correctly mapped into the specified type in .Net, we currently generate any non-primitive value type in additional properties property as BinaryData.
For typespec:
model Animal { name: string; kind: string; ...Record<AnimalProperty>;}The C# generated code is the same as if the type is unknown:
public partial class Animal : IJsonModel<Animal>{ public Animal(string name, string kind);
public string Name { get; } public string Kind { get; }
public IDictionary<string, BinaryData> AdditionalProperties { get; }}For typespec with additional properties of primitive types:
model Animal { name: string; kind: string; ...Record<string>;}The C# generated code still has the specified type in AdditionalProperties property:
public partial class Animal : IJsonModel<Animal>{ public Animal(string name, string kind);
public string Name { get; } public string Kind { get; }
public IDictionary<string, string> AdditionalProperties { get; }}// RLC inputexport interface AnimalProperty { category: string; value: unknown;}export interface Animal extends Record<string, unknown> { name: string; kind: string;}
// RLC outputexport interface AnimalProperty { category: string; value: any;}export interface Animal extends Record<string, any> { name: string; kind: string;}
// Modular for legacy clientsexport interface AnimalProperty { category: string; value: any;}export interface Animal extends Record<string, any> { name: string; kind: string;}
// Modular for non-legacy clientsexport interface AnimalProperty { category: string; value: any;}export interface Animal { name: string; kind: string; additionalProperties: Record<string, AnimalProperty>;}@Fluentpublic final class Animal implements JsonSerializable<Animal> { public Animal(String name, String kind); public String getName(); public String getKind(); public Map<String, AnimalProperty> getAdditionalProperties(); public Animal setAdditionalProperties(Map<String, AnimalProperty> additionalProperties);}Additional properties of union type
model Animal { name: string; kind: string; ...Record<string | int32>;}model Animal { name: string; kind: string; ...Record<string>; ...Record<int32>;}{ "kind": "model", "name": "Animal", "properties": [ { "kind": "property", "name": "name", "serializedName": "name", "optional": false, "type": { "kind": "string", "encode": "string" } }, { "kind": "property", "name": "kind", "serializedName": "kind", "optional": false, "type": { "kind": "string", "encode": "string" } } ], "additionalProperties": { "kind": "union", "name": "AnimalAdditionalProperty", "generatedName": true, "values": [ { "kind": "string", "encode": "string" }, { "kind": "int32" } ] }}Python models are designed to support adding any additional properties.
from .. import _model_basefrom .._model_base import rest_field
class Animal(_model_base.Model):
name: str = rest_field() kind: str = rest_field()
animal = Animal(name="Tom", kind="Cat")animal["friend"] = "Jerry"animal["age"] = 5public partial class Animal : IJsonModel<Animal>{ public Animal(string name, string kind);
public string Name { get; } public string Kind { get; }
public IDictionary<string, BinaryData> AdditionalProperties { get; }}// RLC input and outputexport interface Animal extends Record<string, string | number> { name: string; kind: string;}
// Modular for legacy and non-legacy clientsexport interface Animal extends Record<string, string | number> { name: string; kind: string;}@Fluentpublic final class Animal implements JsonSerializable<Animal> { public Animal(String name, String kind); public String getName(); public String getKind(); public Map<String, BinaryData> getAdditionalProperties(); public Animal setAdditionalProperties(Map<String, BinaryData> additionalProperties);}Additional properties of nullable type
model Animal { name: string; kind: string; ...Record<string | null>;}{ "kind": "model", "name": "Animal", "properties": [ { "kind": "property", "name": "name", "serializedName": "name", "optional": false, "type": { "kind": "string", "encode": "string" } }, { "kind": "property", "name": "kind", "serializedName": "kind", "optional": false, "type": { "kind": "string", "encode": "string" } } ], "additionalProperties": { "kind": "nullable", "valueType": { "kind": "string", "encode": "string" } }}Python models are designed to support adding any additional properties.
from .. import _model_basefrom .._model_base import rest_field
class Animal(_model_base.Model):
name: str = rest_field() kind: str = rest_field()
animal = Animal(name="Tom", kind="Cat")animal["friend"] = "Jerry"animal["alert"] = Nonepublic partial class Animal : IJsonModel<Animal>{ public Animal(string name, string kind);
public string Name { get; } public string Kind { get; }
public IDictionary<string, string> AdditionalProperties { get; }}// RLC input and outputexport interface Animal extends Record<string, string | null> { name: string; kind: string;}
// Modular for legacy and non-legacy clientsexport interface Animal extends Record<string, string | null> { name: string; kind: string;}@Fluentpublic final class Animal implements JsonSerializable<Animal> { public Animal(String name, String kind); public String getName(); public String getKind(); public Map<String, String> getAdditionalProperties(); public Animal setAdditionalProperties(Map<String, String> additionalProperties);}Nullable
TypeSpec uses | null to represent nullable types. Nullability is handled differently in languages, but emitter authors will find information
about nullability by inspecting the type of a property.
model Foo { basicNullableProperty: string | null; modelNullableProperty: Bar | null; unionNullableProperty: Bar | Baz | null; enumNullableProperty: LR | null;}
model Bar { prop: string;}
model Baz { prop: int32;}
enum LR { left, right,}A nullable type has kind nullable and property valueType. The kind of the type tells you the property is nullable, while the valueType tells you the underlying type you want to generate.
{ "kind": "model", "name": "Foo", "properties": [ { "kind": "property", "name": "basicNullableProperty", "serializedName": "basicNullableProperty", "optional": false, "type": { "kind": "nullable", "valueType": { "kind": "string", "encode": "string" } } }, { "kind": "property", "name": "modelNullableProperty", "serializedName": "modelNullableProperty", "optional": false, "type": { "kind": "nullable", "valueType": { "kind": "model", "name": "Bar", "properties": [ { "kind": "property", "name": "prop", "serializedName": "prop", "optional": false, "type": { "kind": "string", "encode": "string" } } ] } } }, { "kind": "property", "name": "unionNullableProperty", "serializedName": "unionNullableProperty", "optional": false, "type": { "kind": "nullable", "valueType": { "kind": "union", "values": [ { "kind": "model", "name": "Bar", "properties": [ { "kind": "property", "name": "prop", "serializedName": "prop", "optional": false, "type": { "kind": "string", "encode": "string" } } ] }, { "kind": "model", "name": "Baz", "properties": [ { "kind": "property", "name": "prop", "serializedName": "prop", "optional": false, "type": { "kind": "int32", "encode": "int32" } } ] } ] } } }, { "kind": "property", "name": "enumNullableProperty", "serializedName": "enumNullableProperty", "optional": false, "type": { "kind": "nullable", "valueType": { "kind": "enum", "name": "LR", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": false } } } ]}Python treat nullable as optional. If you actually want to send the value null to the service without the property being ignored, you can send in corehttp.serialization.NULL. Python does not restrict you from setting any property to this value.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class Bar(_model_base.Model): prop: Optional[str] = rest_field()
class Baz(_model_base.Model): prop: Optional[str] = rest_field()
class LR(str, Enum, metaclass=CaseInsensitiveEnumMeta): LEFT = "left" RIGHT = "right"
class Foo(_model_base.Model): basicNullableProperty: Optional[str] = rest_field() modelNullableProperty: Optional["_models.Bar"] = rest_field() unionNullableProperty: Optional[Union["_models.Bar", "_models.Baz"]] = rest_field() enumNullableProperty: Optional["LR"] = rest_field()TODO
TODO
TODO
Unions
Union of literals with same type
All emitters will generate their version of a closed enum.
union LR { left: "left", right: "right",}{ "kind": "enum", "name": "LR", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": true}Python never generates closed enum by design. We will always permit users to pass in additional values.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class LR(str, Enum, metaclass=CaseInsensitiveEnumMeta): LEFT = "left" RIGHT = "right"public enum LR{ Left, Right}Serialization/deserialization will respect the value defined, in this case it is “left” for LR.Left and “right” for LR.Right respectively.
export type LR = "left" | "right";public enum LR { LEFT("left"), RIGHT("right");}Inline union of literals with same type
This is union defined inline at point of usage.
model Widget { horizontal: "left" | "right";}{ "kind": "enum", "name": "WidgetHorizontals", "generatedName": true, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": true}Python generates this as a union of literals, not as enum. We also don’t generate a closed set of literals.
from typing import Literal, Union
model Widget: horizontal: Union[Literal["left"] | Literal["right"] | str]public partial class Widget{ public WidgetHorizontal Horizontal;}public enum WidgetHorizontal{ Left, Right}export interface Widget { horizontal: "left" | "right";}public enum WidgetHorizontal { LEFT("left"), RIGHT("right");}Union of basic type and literals of that type
Each language will generate their version of an open enum.
union Colors { string, red: "red", blue: "blue",}{ "kind": "enum", "name": "Colors", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "red", "value": "red" }, { "kind": "enumvalue", "name": "blue", "value": "blue" } ], "isFixed": false, "isUnionAsEnum": true}Python generates open enum again here.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class Colors(str, Enum, metaclass=CaseInsensitiveEnumMeta): RED = "red" BLUE = "blue"public readonly partial struct Colors : IEquatable<Colors>{ private const string RedValue = "red"; private const string BlueValue = "blue"; public static Colors Red { get; } = new Colors(RedValue); public static Colors Blue { get; } = new Colors(BlueValue);}export type Colors = string | "red" | "blue";public final class Colors extends ExpandableStringEnum<Colors> { public static final Colors RED = fromString("red"); public static final Colors BLUE = fromString("blue");}Inline union of basic type and literals of that type
This is union defined inline at point of usage which include the base type as an option.
model Widget { color: "red" | "blue" | string;}{ "kind": "enum", "name": "WidgetColors", "generatedName": true, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "red", "value": "red" }, { "kind": "enumvalue", "name": "blue", "value": "blue" } ], "isFixed": false, "isUnionAsEnum": true}Python generates a union of literals again.
from typing import Literal, Union
model Widget: color: Union[Literal["red"] | Literal["blue"] | str]public partial class Widget{ public WidgetColor Color;}public readonly partial struct WidgetColor : IEquatable<WidgetColor>{ private const string RedValue = "red"; private const string BlueValue = "blue"; public static WidgetColor Red { get; } = new WidgetColor(RedValue); public static WidgetColor Blue { get; } = new WidgetColor(BlueValue);}export interface Widget { color: "red" | "blue" | string;}public final class WidgetColor extends ExpandableStringEnum<Colors> { public static final Color RED = fromString("red"); public static final Color BLUE = fromString("blue");}Union of other union/enum, basic type and literals of that type
import "@azure-tools/typespec-azure-resource-manager";
union ProvisioningState { string, "InProgress", Azure.ResourceManager.ResourceProvisioningState,}For union of other union or enum. TCGC will do the flatten according to the flag.
With flatten-union-as-enum flagged true:
{ "kind": "enum", "name": "ProvisioningState", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "InProgress", "value": "InProgress" }, { "kind": "enumvalue", "name": "Succeeded", "value": "Succeeded" }, { "kind": "enumvalue", "name": "Failed", "value": "Failed" }, { "kind": "enumvalue", "name": "Canceled", "value": "Canceled" } ], "isFixed": false, "isUnionAsEnum": true}With flatten-union-as-enum flagged false:
{ "kind": "union", "name": "ProvisioningState", "generatedName": false, "values": [ { "kind": "string" }, { "kind": "constant", "value": "InProgress", "valueType": { "kind": "string" } }, { "kind": "enum", "name": "ResourceProvisioningState", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "Succeeded", "value": "Succeeded" }, { "kind": "enumvalue", "name": "Failed", "value": "Failed" }, { "kind": "enumvalue", "name": "Canceled", "value": "Canceled" } ], "isFixed": true, "isUnionAsEnum": false } ]}Python generates a single open enum.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class ProvisioningState(str, Enum, metaclass=CaseInsensitiveEnumMeta): INPROGRESS = "InProgress" SUCCEEDED = "Succeeded" FAILED = "Failed" CANCELED = "Canceled"public readonly partial struct ProvisioningState : IEquatable<ProvisioningState>{ private const string SucceededValue = "Succeeded"; private const string FailedValue = "Failed"; private const string CanceledValue = "Canceled"; private const string InProgressValue = "InProgress";
public static ProvisioningState Succeeded { get; } = new ProvisioningState(SucceededValue); public static ProvisioningState Failed { get; } = new ProvisioningState(FailedValue); public static ProvisioningState Canceled { get; } = new ProvisioningState(CanceledValue); public static ProvisioningState InProgress { get; } = new ProvisioningState(InProgressValue);}export type ResourceProvisioningState = "Succeeded" | "Failed" | "Canceled";// NOTE: extensible enum design may change in JSexport type ProvisioningState = string | "InProgress" | ResourceProvisioningState;public final class ProvisioningState extends ExpandableStringEnum<ProvisioningState> { public static final ProvisioningState INPROGRESS = fromString("InProgress"); public static final ProvisioningState SUCCEEDED = fromString("Succeeded"); public static final ProvisioningState FAILED = fromString("Failed"); public static final ProvisioningState CANCELED = fromString("Canceled");}Union of other unions of literals with same type
union LR { left: "left", right: "right",}
union UD { up: "up", down: "down",}
union Orientation { LR, UD,}For union of other union or enum. TCGC will do the flatten according to the flag.
With flatten-union-as-enum flagged true:
{ "kind": "enum", "name": "Orientation", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" }, { "kind": "enumvalue", "name": "up", "value": "up" }, { "kind": "enumvalue", "name": "down", "value": "down" } ], "isFixed": true, "isUnionAsEnum": true}With flatten-union-as-enum flagged false:
{ "kind": "union", "name": "Orientation", "generatedName": false, "values": [ { "kind": "enum", "name": "LR", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": true }, { "kind": "enum", "name": "UD", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "up", "value": "up" }, { "kind": "enumvalue", "name": "down", "value": "down" } ], "isFixed": true, "isUnionAsEnum": true } ]}from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class Orientation(str, Enum, metaclass=CaseInsensitiveEnumMeta): LEFT = "left" RIGHT = "right" UP = "up" DOWN = "down"public enum Orientation{ Left, Right, Up, Down}export type LR = "left" | "right";export type UD = "up" | "down";export type Orientation = LR | UD;public enum Orientation { LEFT("left"), RIGHT("right"), UP("up"), DOWN("down");}Inline union of other unions of literals with same type
union LR { left: "left", right: "right",}
union UD { up: "up", down: "down",}
model Widget { orientation: LR | UD;}For union of other union or enum. TCGC will do the flatten according to the flag.
With flatten-union-as-enum flagged true:
{ "kind": "enum", "name": "WidgetOrientations", "generatedName": true, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" }, { "kind": "enumvalue", "name": "up", "value": "up" }, { "kind": "enumvalue", "name": "down", "value": "down" } ], "isFixed": true, "isUnionAsEnum": true}With flatten-union-as-enum flagged false:
{ "kind": "union", "name": "WidgetOrientations", "generatedName": true, "values": [ { "kind": "enum", "name": "LR", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": true }, { "kind": "enum", "name": "UD", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "up", "value": "up" }, { "kind": "enumvalue", "name": "down", "value": "down" } ], "isFixed": true, "isUnionAsEnum": true } ]}Since this is inline, Python will generate this as a single union of all possible literal values.
from typing import Literal
type WidgetOrientation = "left" | "right" | "up" | "down" | str
model Widget: orientation: WidgetOrientationpublic partial class Widget{ public WidgetOrientation Orientation;}public enum WidgetOrientation{ Left, Right, Up, Down}export interface Widget { orientation: LR | UD;}
export type LR = "left" | "right";export type UD = "up" | "down";public enum WidgetOrientation { LEFT("left"), RIGHT("right"), UP("up"), DOWN("down");}Union with multiple types
These are unions where the values don’t share same type.
model Shirt { sizing: 32 | 34 | int32 | "small" | "medium" | string;}{ "kind": "union", "name": "ShirtSizings", "generatedName": true, "values": [ { "kind": "constant", "value": 32, "valueType": { "kind": "int32" } }, { "kind": "constant", "value": 34, "valueType": { "kind": "int32" } }, { "kind": "constant", "value": "small", "valueType": { "kind": "string" } }, { "kind": "constant", "value": "medium", "valueType": { "kind": "string" } }, { "kind": "string" } ]}Python will generate this as a union since these entries don’t share the same type
from typing import Literal
type ShirtSizing = Literal[32] | Literal[34] | int | Literal["small"] | Literal["medium"] | str
model Shirt: sizing: ShirtSizingpublic partial class Shirt{ public BinaryData Shirt;}export interface Shirt { sizing: 32 | 34 | number | "small" | "medium" | string;}public final class Shirt { private BinaryData sizing;}Enums
Standard
Standard enums will be generated as closed enums.
enum LR { left, right,}{ "kind": "enum", "name": "LR", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" } ], "isFixed": true, "isUnionAsEnum": false}Python never generates closed enums by design. We will always permit users to pass in additional values.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class LR(str, Enum, metaclass=CaseInsensitiveEnumMeta): LEFT = "left" RIGHT = "right"public enum LR{ Left, Right}export type LR = "left" | "right";public enum LR { LEFT("left"), RIGHT("right");}Versioning Enums
@versioned(Versions)@servicenamespace My.Service;
enum Versions { v1, v2,}{ "kind": "enum", "name": "Versions", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "v1", "value": "v1" }, { "kind": "enumvalue", "name": "v2", "value": "v2" } ], "isFixed": true, "isUnionAsEnum": false, "usage": 8}# Python does not generate the enum used for versioning// CSharp does not generate the enum used for versioning// JS does not generate the enum used for versioningpublic enum ServiceServiceVersion implements ServiceVersion { V1("v1"), V2("v2");}Spread
Spreading enums will return the resultant enum as a new single closed enum.
enum LR { left, right,}
enum UD { up, down,}
enum Orientation { ...LR, ...UD,}{ "kind": "enum", "name": "Orientation", "generatedName": false, "valueType": { "kind": "string" }, "values": [ { "kind": "enumvalue", "name": "left", "value": "left" }, { "kind": "enumvalue", "name": "right", "value": "right" }, { "kind": "enumvalue", "name": "up", "value": "up" }, { "kind": "enumvalue", "name": "down", "value": "down" } ], "isFixed": true, "isUnionAsEnum": false}Python generates one open enum, because Python never generates an enum as fully closed.
from enum import Enumfrom corehttp.utils import CaseInsensitiveEnumMeta
class Orientation(str, Enum, metaclass=CaseInsensitiveEnumMeta): LEFT = "left" RIGHT = "right" UP = "up" DOWN = "down"public enum Orientation{ Left, Right, Up, Down}export type Orientation = "left" | "right" | "up" | "down";public enum Orientation { LEFT("left"), RIGHT("right"), UP("up"), DOWN("down");}Scalars
Encoding
We will take the @encode decorator into account, determining how we serialize inputted scalars to send over the wire.
model Test { @encode(DateTimeKnownEncoding.rfc3339) prop: utcDateTime;}{ "kind": "property", "name": "prop", "type": { "kind": "utcDateTime", "encode": "rfc3339", "wireType": { "kind": "string" } }}serialized_prop = json.dumps(prop, cls=SdkJSONEncoder, format="rfc3339")TODOTODO;// Internal implementationjsonWriter.writeStringField("prop", this.value == null ? null : DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(this.value));When you specify an encoding type, say that you want to encode an integer as a string, that will also be represented in our generated SDKs.
model Test { @encode(string) prop: int64;}{ "kind": "property", "name": "prop", "type": { "kind": "int64", "encode": "string", "wireType": { "kind": "string" } }}serialized_prop = json.dumps(prop, cls=SdkJSONEncoder, format="string")TODOTODO;// Internal implementationjsonWriter.writeStringField("prop", Objects.toString(this.value, null));