API reference


The two main building blocks of the hrefs library are

  • Href, the class representing hyperlinks

  • Referrable, the protocol/ABC of types that can be targets of hyperlinks

class hrefs.Href(key, url)

Hypertext reference to another model

The class is generic and can be annotated by a type implementing the Referrable protocol. If Book is assumed to be a type implementing Referrable, then Href[Book] represents a hyperlink to a book. This mechanism primarily exists for the benefit of pydantic, and allows the validation to know what kind of reference it is working with (see Getting started).

property key

The key of the referred object

property url

The URL of the referred object

classmethod validate(value, field: pydantic.fields.ModelField)

Parse value into hyperlink

This method mainly exists for integration to pydantic. A user rarely needs to call it directly.



The parsed object. It can be either:

  • Another Href instance

  • An instance of the referred model

  • A value of the key type (interpreted as key identifying the referred object)

  • A url string (interpreted as URL to the referred object)


A Href object referring the model identified by the value argument.

  • TypeError – If the Href model isn’t properly annotated, or if value doesn’t conform to any of the recognized types

  • Exception – In addition passes any exceptions happening during conversions

class hrefs.Referrable(*args, **kwds)

Protocol that needs to be implemented by a target of Href

The class can either be used as a protocol (see PEP 544), or abstract base class.

  • When used as protocol in type annotations, Referrable is parametrized by key and URL types, respectively. For example Referrable[int, str] annotates a referrable type having int as key and str as URL. Referrable[UUID, AnyHttpUrl] annotates a referrable type having UUID key and AnyHttpUrl as URL type.

  • When used as abstract base class, the subclass needs to implement at least get_key() to convert between model and key, and key_to_url() and url_to_key() to specify the conversions between the key and URL representations. The return types of the functions should be annotated to make them available for parsing and serialization at runtime. Here is an example:

    class Book(Referrable):
        id: int
        def get_key(self) -> int:
            return self.id
        def key_to_url(key: int) -> str:
            return f"/books/{key}"
        def url_to_key(url: str) -> int:
            return url.split("/")[-1]
classmethod __modify_href_schema__(schema: MutableMapping[str, Any], field: pydantic.fields.ModelField)

Modify schema of Href to this type

The default implementation reads the return type annotation of key_to_url(), and uses its schema as Href schema.

  • schema – the schema being modified

  • field – the pydantic ModelField object of the Href

abstract get_key() hrefs.href.KeyType

Return the key of the model

abstract classmethod key_to_url(key: hrefs.href.KeyType) hrefs.href.UrlType

Convert key to url

classmethod parse_as_key(value: Any) Optional[hrefs.href.KeyType]

Attempt to parse value as key

The default implementation reads the return type annotation of url_to_key(), and tries to convert value, swallowing TypeError and ValueError.


value parameter converted to key type, or None if unable to parse

classmethod parse_as_url(value: Any) Optional[hrefs.href.UrlType]

Attempt to parse value as URL

The default implementation reads the return type annotation of key_to_url(), and tries to convert value, swallowing TypeError and ValueError.


value parameter converted to URL type, or None if unable to parse

abstract classmethod url_to_key(url: hrefs.href.UrlType) hrefs.href.KeyType

Convert url to key

Pydantic models

Any pydantic model that is a target of hyperlinks should implement BaseReferrableModel. It inherits both pydantic.BaseModel and hrefs.Referrable.

class hrefs.BaseReferrableModel

Referrable model with pydantic integration

A subclass of both pydantic.BaseModel and hrefs.Referrable. It should be used as the base class of any pydantic model that will be used as target of hrefs.Href.

BaseReferrableModel provides implementation on get_key() and parse_as_key() based on its field annotations. By default the model key is the id field (if it exists), but that can be changed by using PrimaryKey to annotate other field(s).

When using referrable models with FastAPI or Starlette in particular, hrefs.starlette.ReferrableModel is more natural base.

get_key() Any

Return the model key


The model key based on the field annotations. If the key is composite, return a tuple containing the parts.

classmethod has_simple_key() bool

Query if the model has a simple key


True if the model has simple (single part) key, False otherwise

classmethod key_to_path_params(key: Any) Dict[str, Any]

Convert model key to path parameters

This is a helper that can be used to convert a model key into a dictionary containing the key parts. Hyperlinks are unwrapped (see Hyperlinks as keys). It can be used to generate URLs in several HTTP frameworks.


key – model key


A dictionary mapping key names to key parts

classmethod parse_as_key(value: Any) Optional[Any]

Parse value as the key type

The type of the model key based on the field annotations. Either a single type, or (in case of composite key), a tuple of the parts.

classmethod path_params_to_key(path_params: Mapping[str, Any]) Any

Convert path parameters to model key

This helper can be used to convert path parameter mapping to model key. It is the inverse of key_to_path_params().


path_params – A mapping from key names to key parts


Model key parsed from path_params

static try_parse_as(model: Type[pydantic.main.BaseModel], value: Any) Optional[Any]

Parse value as model but swallow validation error

  • model – the model parsed to

  • value – the value to parse


value parsed as model, or None on validation error

classmethod update_forward_refs(**localns: Any) None

Try to update ForwardRefs on fields based on this Model, globalns and localns.

class hrefs.PrimaryKey(type_: Optional[Type] = None, name: Optional[str] = None)

Annotation declaring a field in BaseReferrableModel as key

PrimaryKey can be used the following way:

from typing import Annotation

class MyModel(BaseReferrableModel):
    my_id: Annotated[int, PrimaryKey]

    # ...the rest of the definitions...

See Configuring model key for more details.

  • type – The underlying key type if the annotated primary key is itself a hyperlink. See Hyperlinks as keys.

  • name – The name of the key. It may be distinct from the actual field name, and will appear in path parameters etc.

Starlette integration

The main motivation for writing the library was to make it easy to use hyperlinks in FastAPI and Starlette applications. See Getting started for a full working example how to use these classes.

class hrefs.starlette.ReferrableModel

Referrable model with Starlette integration

This class implements the hrefs.BaseReferrableModel with the following features:

  • Its key type is inferred from type annotations as in the base class

  • Its URL type is always pydantic.AnyHttpUrl

  • It uses a context (app or request) to automatically generate and resolve URLs based on routes defined in the application.

The preferrable way to provide ReferrableModel its context is by adding HrefMiddleware to the middleware stack of the application. href_context() can alternatively be used when using the middleware is not possible (for example in websocket handlers or when using hyperlinks outside of request handlers).

Here is a minimal example using route called "my_view" to convert to/from URLs:

class MyModel(ReferrableModel):
    id: int

    class Config:
        details_view = "my_view"

For a more complete example of using hrefs library with Starlette, please refer to Getting started.

class hrefs.starlette.HrefMiddleware(app: Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[None]]], Awaitable[None]], dispatch: Optional[Callable[[starlette.requests.Request, Callable[[starlette.requests.Request], Awaitable[starlette.responses.Response]]], Awaitable[starlette.responses.Response]]] = None)

Middleware for resolving hrefs

This middleware needs to be added to the middleware stack of the Starlette app using the ReferrableModel.

hrefs.starlette.href_context(request_or_app: Union[starlette.requests.HTTPConnection, starlette.applications.Starlette], *, base_url: Optional[Union[str, starlette.datastructures.URL]] = None)

Context manager that sets hyperlink context

Makes request_or_app responsible for converting between keys and URLs in hypperlinks to ReferrableModel. The context can either be:

  • A Starlette HTTPConnection – that is HTTP request or websocket

  • A Starlette application. Note that base_url needs to be provided when using application to convert the URL path to absolute URL.

href_context() is used as a context manager that automatically clears the context when exiting. The contexts stack so you can even use nested contexts if you’re feeling adventurous.

This is an example how to make a websocket handler work with hyperlinks in FastAPI:

from fastapi import FastAPI, WebSocket
from hrefs.starlette import ReferrableModel, href_context

app = FastAPI(...)

class Book(ReferrableModel):
    id: int

    # ...et cetera...

async def my_awesome_websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    with href_context(websocket):
        # here you can create and parse Href[Book] instances
        # the base URL will be inferred from the connection

If you want to use an application as hyperlink context, you’ll need to provide base URL manually:

with href_context(app, base_url="http://example.com"):
    # here you can create and parse Href[Book] instances
    # URLs will be like: http://example.com/book/api/books/1


For normal use where hyperlinks are parsed or generated inside request handlers of a Starlette/FastAPI app, it is recommended to use HrefMiddleware to automatically set the context.


request_or_app: The request or app to be used as hyperlink context base_url: The base URL (needed when using application as context)