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.")