User bio
404 bio not found
Member since Sep 12, 2023
Replies:

Is this the kind of behavior you want?

Set pyType = ##class(%IPM.Utils.PydanticModelAdaptor).ExamplePydanticModel() // a convenience method to return a pydantic type object, with 3 fields defined: id, name, and email
Set object = ##class(%IPM.Utils.PydanticModelAdaptor).%New(pyType)
Set object.id = "1234", object.name = "John Doe", object.email = "john.doe@intersystems.com"
Zwrite object.id, object.name, object.email
// output
// 1234
// "John Doe"
// "john.doe@intersystems.com"

The above is achievable using the following. You can also implement %JSONExport, %Validate, etc.

Class %IPM.Utils.PydanticModelAdaptor Extends %RegisteredObject
{

/// Probably worthwhile to change the `PyModel` to something less likely to conflict with Pydantic field names
/// E.g. PyModel can be the type (aka class) object defined as 
/// class UserModel(BaseModel):
///     id: int
///     name: str = Field(..., min_length=3)
///     email: Optional[str] = None
Property PyModel As %SYS.Python;

/// E.g. 
/// PyFieldArray("id") = 1234
/// PyFieldArray("name") = "John Doe"
/// PyFieldEmail("email") = "john.doe@example.com" or unset
Property PyFieldArray As %String [ MultiDimensional ];

Method %OnNew(pyType As %SYS.Python) As %Status [ Private, ServerOnly = 1 ]
{
    Set ..PyModel = pyType
    Quit $$$OK
}

Method %DispatchGetProperty(Property As %String) [ ServerOnly = 1 ]
{
    Set userFields = ..PyModel."model_fields"
    Set fieldInfo = userFields.get(Property)
    If '$IsObject(fieldInfo) {
        $$$ThrowStatus($$$ERROR($$$GeneralError, "Unknown field name: "_Property))
    }
    Set fieldType = fieldInfo.annotation
    If $Data(..PyFieldArray(Property), output) # 2 {
        // TODO check the `fieldType`, raise error if not matching or violates min_length, max_length, etc.
        Return output
    }

    $$$ThrowStatus($$$ERROR($$$GeneralError, "Field not set: "_Property))
}

Method %DispatchSetProperty(Property As %String, Val) [ ServerOnly = 1 ]
{
    Set userFields = ..PyModel."model_fields"
    Set fieldInfo = userFields.get(Property)
    If '$IsObject(fieldInfo) {
        $$$ThrowStatus($$$ERROR($$$GeneralError, "Unknown field name: "_Property))
    }
    Set fieldType = fieldInfo.annotation
    // TODO check the `fieldType`, raise error if not matching or violates min_length, max_length, etc.

    Set ..PyFieldArray(Property) = Val
}

ClassMethod ExamplePydanticModel() [ Language = python ]
{
    from pydantic import BaseModel, Field
    from typing import Optional

    class UserModel(BaseModel):
        id: int
        name: str = Field(..., min_length=3)
        email: Optional[str] = None

    return UserModel
}

}
Certifications & Credly badges:
Shuheng has no Certifications & Credly badges yet.
Global Masters badges:
Shuheng has no Global Masters badges yet.
Followers:
Shuheng has no followers yet.
Following:
Shuheng has not followed anybody yet.