Compare changes

Choose any two refs to compare.

Changed files
+221
src
atpasser
model
tools
tools/fetchLexicon.py
+7
src/atpasser/model/converter.py
···
UnknownModel, RecordModel, QueryModel,
ProcedureModel, SubscriptionModel
)
+
from .types.binary import BytesModel, CidLinkModel
+
from .blob import BlobModel
class LexiconConverter:
"""
···
"integer": IntegerModel,
"string": StringModel,
+
# Binary types
+
"bytes": BytesModel,
+
"cid-link": CidLinkModel,
+
"blob": BlobModel,
+
# Complex types
"array": ArrayModel,
"object": ObjectModel,
+214
src/atpasser/model/types/complex.py
···
+
from typing import Any
+
from pydantic import field_validator
+
from ..base import DataModel
+
+
class ArrayModel(DataModel):
+
"""
+
Model for AT Protocol array type.
+
+
Represents an array of elements with support for item schema definition,
+
minimum/maximum length constraints as specified in Lexicon.
+
"""
+
+
items: Any
+
"""Schema definition for array elements"""
+
+
minLength: int | None = None
+
"""Minimum number of elements"""
+
+
maxLength: int | None = None
+
"""Maximum number of elements"""
+
+
value: list[Any]
+
"""Array values"""
+
+
def __init__(self, **data: Any) -> None:
+
"""
+
Initialize array model with validation.
+
+
Args:
+
**data: Input data containing array values
+
+
Raises:
+
ValueError: If array violates constraints
+
"""
+
super().__init__(**data)
+
+
@field_validator("value", mode="before")
+
def validate_array(cls, v: Any) -> list[Any]:
+
"""
+
Validate array structure and elements.
+
+
Args:
+
v: Value to validate
+
+
Returns:
+
Validated array
+
+
Raises:
+
ValueError: If array violates constraints
+
"""
+
if not isinstance(v, list):
+
raise ValueError("Value must be an array")
+
+
# Validate length constraints
+
if cls.minLength is not None and len(v) < cls.minLength:
+
raise ValueError(f"Array must have at least {cls.minLength} items")
+
+
if cls.maxLength is not None and len(v) > cls.maxLength:
+
raise ValueError(f"Array must have at most {cls.maxLength} items")
+
+
return v
+
+
class ObjectModel(DataModel):
+
"""
+
Model for AT Protocol object type.
+
+
Represents a generic object schema with properties definitions,
+
required fields and nullable fields as specified in Lexicon.
+
"""
+
+
properties: dict[str, Any]
+
"""Map of property names to their schema definitions"""
+
+
required: list[str] | None = None
+
"""List of required property names"""
+
+
nullable: list[str] | None = None
+
"""List of properties that can be null"""
+
+
value: dict[str, Any]
+
"""Object property values"""
+
+
def __init__(self, **data: Any) -> None:
+
"""
+
Initialize object model with validation.
+
+
Args:
+
**data: Input data containing object properties
+
+
Raises:
+
ValueError: If object violates constraints
+
"""
+
super().__init__(**data)
+
+
@field_validator("value", mode="before")
+
def validate_object(cls, v: Any) -> dict[str, Any]:
+
"""
+
Validate object structure and properties.
+
+
Args:
+
v: Value to validate
+
+
Returns:
+
Validated object
+
+
Raises:
+
ValueError: If object violates constraints
+
"""
+
if not isinstance(v, dict):
+
raise ValueError("Value must be an object")
+
+
# Validate required fields
+
if cls.required:
+
for field in cls.required:
+
if field not in v:
+
raise ValueError(f"Missing required field: {field}")
+
+
# Validate nullable fields
+
if cls.nullable:
+
for field, value in v.items():
+
if field not in cls.nullable and value is None:
+
raise ValueError(f"Field {field} cannot be null")
+
+
return v
+
+
class ParamsModel(DataModel):
+
"""
+
Model for AT Protocol params type.
+
+
Specialized for HTTP query parameters with support for boolean,
+
integer, string and unknown types as specified in Lexicon.
+
"""
+
+
required: list[str] | None = None
+
"""List of required parameter names"""
+
+
properties: dict[str, Any]
+
"""Map of parameter names to their schema definitions"""
+
+
value: dict[str, Any]
+
"""Parameter values
+
+
Supported types:
+
- boolean
+
- integer
+
- string
+
- array (of boolean/integer/string/unknown)
+
- unknown (object)
+
"""
+
+
def __init__(self, **data: Any) -> None:
+
"""
+
Initialize params model with validation.
+
+
Args:
+
**data: Input data containing parameter values
+
+
Raises:
+
ValueError: If parameters violate constraints
+
"""
+
super().__init__(**data)
+
+
@field_validator("value", mode="before")
+
def validate_params(cls, v: Any) -> dict[str, Any]:
+
"""
+
Validate parameters structure and values.
+
+
Args:
+
v: Value to validate
+
+
Returns:
+
Validated parameters
+
+
Raises:
+
ValueError: If parameters violate constraints
+
"""
+
if not isinstance(v, dict):
+
raise ValueError("Value must be a dictionary of parameters")
+
+
# Validate required parameters
+
if cls.required:
+
for param in cls.required:
+
if param not in v:
+
raise ValueError(f"Missing required parameter: {param}")
+
+
# Validate parameter types
+
for param, value in v.items():
+
if param in cls.properties:
+
prop_type = cls.properties[param].get("type")
+
if prop_type == "boolean" and not isinstance(value, bool):
+
raise ValueError(f"Parameter {param} must be boolean")
+
elif prop_type == "integer" and not isinstance(value, int):
+
raise ValueError(f"Parameter {param} must be integer")
+
elif prop_type == "string" and not isinstance(value, str):
+
raise ValueError(f"Parameter {param} must be string")
+
elif prop_type == "array":
+
if not isinstance(value, list):
+
raise ValueError(f"Parameter {param} must be array")
+
# Validate array items if schema is specified
+
if "items" in cls.properties[param]:
+
item_type = cls.properties[param]["items"].get("type")
+
for item in value:
+
if item_type == "boolean" and not isinstance(item, bool):
+
raise ValueError(f"Array item in {param} must be boolean")
+
elif item_type == "integer" and not isinstance(item, int):
+
raise ValueError(f"Array item in {param} must be integer")
+
elif item_type == "string" and not isinstance(item, str):
+
raise ValueError(f"Array item in {param} must be string")
+
elif item_type == "unknown" and not isinstance(item, dict):
+
raise ValueError(f"Array item in {param} must be object")
+
elif prop_type == "unknown" and not isinstance(value, dict):
+
raise ValueError(f"Parameter {param} must be object")
+
+
return v