Skip to main content

Compile a Python model

To generate a portable schema from a Pydantic model in softschema, use the compile_model function. This function transforms your Python class into a canonical JSON Schema YAML file, embedding a unique contract_id and a content hash for version tracking.

The following example demonstrates how to define a model and compile it to a specific file path. The returned CompileResult provides access to the generated YAML content and the calculated SHA-256 hash.

from pathlib import Path
from pydantic import BaseModel
from softschema.compile import compile_model

class UserProfile(BaseModel):
username: str
bio: str | None = None
age: int

# Compile the model to a YAML file
output_path = Path("user_profile.schema.yaml")
result = compile_model(
UserProfile,
out_path=output_path,
contract_id="identity:UserProfile/v1"
)

# Inspect the result
print(f"Schema written to: {result.out_path}")
print(f"Content Hash: {result.schema_sha256}")
print(f"YAML Preview:\n{result.schema_yaml[:100]}...")

Detecting Schema Drift

You can verify if a model definition has changed relative to a previously compiled file without overwriting the existing file. By setting check_only=True, compile_model performs a comparison between the current model and the file on disk.

If the model and the file differ, the drift attribute of the CompileResult will be True, and drift_diff will contain a description of the mismatch. This is useful for CI/CD pipelines to ensure that committed schemas are always in sync with the source code.

from pathlib import Path
from pydantic import BaseModel
from softschema.compile import compile_model

class UserProfile(BaseModel):
username: str
bio: str | None = None
# If this field is added or removed, drift will be detected
age: int
is_active: bool = True

# Check for drift without writing to the file
output_path = Path("user_profile.schema.yaml")
result = compile_model(
UserProfile,
out_path=output_path,
contract_id="identity:UserProfile/v1",
check_only=True
)

if result.drift:
print(f"Drift detected: {result.drift_diff}")
else:
print("Schema is up to date.")