A minimal VGI (Vector Gateway Interface) worker exposing a SQL easter_date(year) scalar function to DuckDB
Project description
vgi-easter
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.
Quick start
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.
How it works
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.
Running it
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 8000
LOAD 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.
Configuration
| 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. |
Development
Requires Python 3.13+ and uv; the only
dependency is vgi-python.
uv run --frozen pytest tests/ -q
The 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.
Releasing
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.
Built with
- 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.
License
MIT — see LICENSE. Copyright 2026 Query Farm LLC — https://query.farm
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vgi_easter-0.1.4.tar.gz.
File metadata
- Download URL: vgi_easter-0.1.4.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff28137f26a108898fa4332230d8ced9218e1dc03d4cb721b6fa8ea950517c16
|
|
| MD5 |
92d5ce2b276a49eaa9cbae8675acc859
|
|
| BLAKE2b-256 |
b93384f3cbd3e71ab5c061eb1d91d30d7dc9bd91c54352a4f204f96a61b8c64d
|
File details
Details for the file vgi_easter-0.1.4-py3-none-any.whl.
File metadata
- Download URL: vgi_easter-0.1.4-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b79bdbc6c2cc79dc4293ff0f878a734ee398275dc2a0017d334dd5bc702a7f04
|
|
| MD5 |
b143ed3e9a1449b31a322d0f6b17cbaa
|
|
| BLAKE2b-256 |
1121479a07d453c210c93f7fbd16d1e3ec49f9e25e4af539c43b56c561433d2e
|