ResourceId
The resource-id package provides a ResourceId class implementing base62-encoded identifiers, suitable for URLs, URIs, and perhaps something else.
ResourceId is written to work with Pydantic. In particular, it can be used with FastAPI as a path parameter.
Requirements
Resource-id requires Python >= 3.10. As of version 1.4.0, resource-id requires pydantic 2.
Installation
pip install resource-id
Usage
There is one class, ResourceId.
from resource_id import ResourceId
Create a ResourceId:
id = ResourceId(43)
id1 = ResourceId('deadbeef')
id2 = ResourceId(UUID(int=101))
A ResourceId can be created from a str (a base62 string, or a UUID in dashed or dashless-hex form), an int, a uuid.UUID, or another ResourceId. The value must be non-negative and fit in a UUID (< 2**128).
Create a URL path using a ResourceId:
path = f"/api/foo/{ResourceId('deadbeef')}"
Define a FastAPI request handler with a ResourceId:
@app.get('/api/foo/{foo_id}')
async def get_foo(foo_id: ResourceId):
...
Here, FastAPI will validate the value of the path variable foo_id with Pydantic. If validation fails, FastAPI returns 422 Unprocessable Entity.
Litestar
FastAPI builds its OpenAPI schema from Pydantic, so ResourceId works there out of the box. Litestar uses its own schema system and has no public API for custom path-parameter types (litestar#4205), so resource-id ships the integration as an optional extra:
pip install resource-id[litestar]
Importing resource_id.litestar registers ResourceId as the resourceid
path-parameter type; add ResourceIdSchemaPlugin to your app so ResourceId
fields render correctly in the OpenAPI document:
import resource_id.litestar # registers the {...:resourceid} path-param type
from resource_id.litestar import ResourceIdPathParameter, ResourceIdSchemaPlugin
from litestar import Litestar, get
@get("/api/foo/{foo_id:resourceid}")
async def get_foo(foo_id: ResourceIdPathParameter) -> str:
...
app = Litestar([get_foo], plugins=[ResourceIdSchemaPlugin()])
The path parameter is parsed into a ResourceId (an invalid value yields a 400),
and the plugin renders ResourceId fields as {"type": "string", "format": "resource-id"} instead of the empty schema litestar would otherwise emit.
Convert a ResourceId to a UUID:
res_id = ResourceId(43)
id = res_id.uuid
More
I have some projects that use PostgreSQL and asyncpg. It is quite simple to add conversion between PostgreSQL UUID datatype and ResourceId.
def get_uuid(value: ResourceId) -> str:
assert isinstance(value, ResourceId)
return str(value.uuid)
def get_resource_id(value: str) -> ResourceId:
assert isinstance(value, str)
return ResourceId(UUID(value))
async def init_connection(conn: asyncpg.Connection):
await conn.set_type_codec(
"uuid", encoder=get_uuid, decoder=get_resource_id, schema="pg_catalog"
)
Testing
This project uses uv for development. To set up and run tests:
uv sync --all-extras --dev
uv run pytest tests
Package Verification
As of version 1.4.0, releases use trusted publishing. As of version 1.5.0, commits are now signed using gitsign.
Metadata
Release files for resource-id 1.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| resource_id-1.6.0.tar.gz | 90.0 kB | With provenance | Details for resource_id-1.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| resource_id-1.6.0-py3-none-any.whl | Python 3 | none | any | Details for resource_id-1.6.0-py3-none-any.whl |
Total release size: 98.1 kB
Release files / resource_id-1.6.0.tar.gz
| Download URL | resource_id-1.6.0.tar.gz |
|---|---|
| Size | 90.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf72da25580730602488d0d1153a045790878aebeeba92e9244d8ba5b259c712
|
|
BLAKE2b-256 checksum How to use checksums |
fd2be37a0454975236b04c9eaa55689d8036220ccaa0370fa64024a49e2b5052
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.
Transparency logRelease files / resource_id-1.6.0-py3-none-any.whl
| Download URL | resource_id-1.6.0-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78ecded34b7be8373abe6d81e716287d4ffe3f962f209d5ab93337f2869e2786
|
|
BLAKE2b-256 checksum How to use checksums |
86901b0072f631b3a4b4ca5b23da137f1ce3f01ebf226be457d7a6e2d193aed8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.
Transparency logSecurity for resource-id 1.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for resource_id-1.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 14, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.