Skip to content

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.