A tiny VGI (Vector Gateway Interface) worker
that gives DuckDB one SQL function — easter_date(year) — returning the date of
Western (Gregorian) Easter Sunday. It has no external data and almost no code,
which makes it a clean, copyable example of a VGI scalar-function worker.
In DuckDB:
-- VGI isn't bundled with DuckDB yet, so load it from the community channel
-- (INSTALL is a one-time download; LOAD is once per session).
INSTALL vgi FROM community;
LOAD vgi;
ATTACH 'easter' (TYPE 'vgi', LOCATION 'uvx vgi-easter');
SELECT easter.easter_date(2025); -- 2025-04-20
SELECT year, easter.easter_date(year) AS easter
FROM range(2020, 2025) t(year);DuckDB launches the worker for you, and easter_date then behaves like a native
function (a null year yields a null date). The uvx vgi-easter location fetches
the worker on demand; to keep it around, pip install vgi-easter.
A VGI worker publishes catalogs, schemas, and functions that DuckDB can ATTACH
and query as if they were built in. Values cross the boundary as Apache Arrow,
so they stay columnar end to end.
This worker publishes a single function:
easter (catalog)
└── main (schema)
└── easter_date(year BIGINT) → DATE
The whole implementation is ~160 lines in
easter_worker.py: the date calculation
(_easter_sunday, the Anonymous Gregorian Computus — pure standard library),
a ScalarFunction that maps an Arrow array of years to dates, and a few lines
wiring it into a catalog.
Once installed, the package gives you one command per VGI transport:
| Command | Transport | Use it when |
|---|---|---|
vgi-easter |
stdio | DuckDB spawns the worker as a subprocess (the quickstart) |
vgi-easter-http |
HTTP | you want a long-running server to attach to |
To run over HTTP, start the server and attach to its URL:
VGI_SIGNING_KEY=dev vgi-easter-http --host 0.0.0.0 --port 8000LOAD vgi; -- after a one-time INSTALL vgi FROM community
ATTACH 'easter' (TYPE 'vgi', LOCATION 'http://localhost:8000');Working from a checkout instead? Both modules carry
PEP 723 metadata, so uv run easter_worker.py (stdio) and uv run serve.py (HTTP) run without installing
anything.
| Variable | Purpose |
|---|---|
VGI_SIGNING_KEY |
Signing key for HTTP state tokens (required by the HTTP server). |
VGI_HTTP_HOST / VGI_HTTP_PORT |
HTTP bind address (default: all interfaces / 8000). |
VGI_EASTER_GIT_COMMIT |
Reported as the catalog's implementation_version. |
VGI_WORKER_DEBUG |
Set to 1 for debug logging. |
Requires Python 3.13+ and uv; the only
dependency is vgi-python.
uv run --frozen pytest tests/ -qThe tests/ suite covers the Easter calculation (including the March 22 /
April 25 extremes) and the Arrow compute path. A separate
sqllogictest suite in test/sql/
drives the worker through the real DuckDB vgi extension. CI runs both on
Linux, macOS, and Windows — see ci/README.md.
vgi-easter is built with hatchling and published to PyPI by CI when a GitHub
Release is created (it runs the test suites, then uv build && uv publish). To
cut a release, bump version in pyproject.toml and publish a GitHub Release.
- DuckDB attaches and queries the worker — install the
VGI extension with
INSTALL vgi FROM community; LOAD vgi;. - vgi-python is the VGI worker SDK this is built on.
- Haybarn provides the
DuckDB-compatible
unittestrunner that drives the cross-platform CI.
MIT — see LICENSE. Copyright 2026 Query Farm LLC — https://query.farm
