Terms
Context Definition
It is possible to configure a default context for a model.
No Context Validation
The model properties are in no way influenced by the defined context in this implementation. Any changes of context only change the context properties value itself and the "@context" key for dumps.
from pydantic_jsonld.compact import BaseModel, Context, Value
context = {"@vocab": "http://www.example.org/"}
class ArticleModel(BaseModel):
context: Context = context
headline: Value[str]
author: Value[str]
keywords: list[Value[str]]
model = ArticleModel(
headline="News of Today",
author="Alice",
keywords=["news", "recent"],
)
assert model.context == context
from pydantic_jsonld.compact import BaseModel, Value
context = "https://www.external.org"
class WeatherReportModel(BaseModel):
context: Context = context
location: Value[str]
temperature: Value[float]
conditions: list[Value[str]]
model = WeatherReportModel(
location="London",
temperature=10.5,
conditions=["rainy", "wet"],
)
assert model.context == context
from pydantic_jsonld.compact import BaseModel, Context, Value
context: list[str | dict[str, str]] = [
"https://www.external.org",
{
"title": "http://example.org/title",
"artist": "http://example.org/artist",
},
]
class MusicTrackModel(BaseModel):
context: Context = context
title: Value[str]
artist: Value[str]
genres: list[Value[str]]
model = MusicTrackModel(
title="My Song",
artist="Bob",
genres=["rock", "pop"],
)
assert model.context == context
Context Alias
The context property is automatically assigned the alias @context
unless explicitly specified by the user.
Context Limitations
As the context is not parsed or resolved in any way, there is currently no way to use the same model for data with vastly different context mappings. And there likely never will be.
Tip
In such cases you may either use the expanded models or compact your data beforehand with a uniform context.
Field with Terms
Terms for properties can be defined via a custom Field implementation.
from pydantic_jsonld.compact import BaseModel, Context, Field, Value
class SpaceMissionModel(BaseModel):
context: Context = Field(
default_factory=lambda: {"ex": "http://www.example.org/"}
)
mission_name: Value[str] = Field(..., term="ex")
launch_vehicle: Value[str] = Field(..., term="ex")
destination: Value[str] = Field(..., term="ex")
crew_capacity: Value[int] = Field(..., term="ex")
data = {
"@context": {"ex": "http://www.example.org/"},
"ex:missionName": "Aurora VII",
"ex:launchVehicle": "Titan Horizon Heavy",
"ex:destination": "Europa",
"ex:crewCapacity": 6,
}
model = SpaceMissionModel.model_validate(data)
assert model.mission_name.value == "Aurora VII"
assert model.launch_vehicle.value == "Titan Horizon Heavy"
assert model.destination.value == "Europa"
assert model.crew_capacity.value == 6
dumped = model.model_dump(by_alias=True, exclude_none=True)
assert dumped == data
from pydantic_jsonld.compact import BaseModel, Context, Field, Value
class FantasyCreatureModel(BaseModel):
context: Context = Field(
default_factory=lambda: {"ex": "http://www.example.org/"}
)
creature_name: Value[str] = Field(..., term="ex")
habitat: Value[str] = Field(..., term="ex")
magical_ability: Value[str] = Field(..., term="ex")
wing_span_meters: Value[float] = Field(..., term="ex")
data = {
"@context": {"ex": "http://www.example.org/"},
"ex:creatureName": "Silverthorn Wyvern",
"ex:habitat": "Crystal Caverns",
"ex:magicalAbility": "Lightning Breath",
"ex:wingSpanMeters": 14.7,
}
model = FantasyCreatureModel.model_validate(data)
assert model.creature_name.value == "Silverthorn Wyvern"
assert model.habitat.value == "Crystal Caverns"
assert model.magical_ability.value == "Lightning Breath"
assert model.wing_span_meters.value == 14.7
dumped = model.model_dump(by_alias=True, exclude_none=True)
assert dumped == data
from pydantic_jsonld.compact import BaseModel, Context, Field, Value
class CoffeeBlendModel(BaseModel):
context: Context = Field(
default_factory=lambda: {"ex": "http://www.example.org/"}
)
blend_name: Value[str] = Field(..., term="ex")
roast_level: Value[str] = Field(..., term="ex")
origin_country: Value[str] = Field(..., term="ex")
tasting_notes: Value[str] = Field(..., term="ex")
data = {
"@context": {"ex": "http://www.example.org/"},
"ex:blendName": "Volcanic Sunrise",
"ex:roastLevel": "Medium Dark",
"ex:originCountry": "Ethiopia",
"ex:tastingNotes": "Dark chocolate, orange peel, and jasmine",
}
model = CoffeeBlendModel.model_validate(data)
assert model.blend_name.value == "Volcanic Sunrise"
assert model.roast_level.value == "Medium Dark"
assert model.origin_country.value == "Ethiopia"
assert model.tasting_notes.value == "Dark chocolate, orange peel, and jasmine"
dumped = model.model_dump(by_alias=True, exclude_none=True)
assert dumped == data
Limitations
For a valid JSON-LD, the terms set for the individual properties obviously mandate that the context also needs to define those terms. This implementation does not parse or validate the context in any way, so it is unable to detect any inconsistencies.