Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,24 @@ jobs:
- name: Check formatting
run: |
uv run --python ${{ matrix.python-version }} black --check .
uv run --python ${{ matrix.python-version }} isort --check-only .
uv run --python ${{ matrix.python-version }} isort --check-only .

test-osx:
name: macOS Python 3.12
runs-on: macos-latest

steps:
- name: Checkout repository
uses: actions/checkout@v5

- name: Set up uv
uses: astral-sh/setup-uv@v6

- name: Install Python 3.12
run: uv python install 3.12

- name: Install the project
run: uv sync --locked --all-extras --dev

- name: Run tests
run: uv run --python 3.12 pytest
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ build:
python: "3.12"
commands:
- pip install .[docs]
- python -m pdoc --docformat google --output-directory $READTHEDOCS_OUTPUT/html tinypg
- python -m pdoc --docformat google --output-directory $READTHEDOCS_OUTPUT/html --logo https://iili.io/Klv1Zcx.md.png tinypg
116 changes: 114 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

[![Klv1Zcx.md.png](https://iili.io/Klv1Zcx.md.png)](https://freeimage.host/i/Klv1Zcx)
![logo](https://iili.io/Klv1Zcx.md.png)

# TinyPG

Expand All @@ -9,7 +9,7 @@ A Python package for creating ephemeral PostgreSQL databases, inspired by [ephem

TinyPG provides a clean Python API for creating temporary PostgreSQL databases for development and testing. It's designed to be self-contained and work without requiring system-wide PostgreSQL installation.

**Currently only tested on linux, but should work on OSX and Windows hopefully**
**Currently only tested on linux & osx. Does not work on Windows yet.**

## Features

Expand Down Expand Up @@ -50,6 +50,25 @@ with tinypg.database() as db_uri:
# Use database...
# Database automatically cleaned up

# Install the built-in pgcrypto extension and use it immediately
with tinypg.database(extensions=["pgcrypto"]) as db_uri:
import psycopg2
conn = psycopg2.connect(db_uri)
with conn.cursor() as cur:
cur.execute("SELECT encode(digest('hello', 'sha256'), 'hex')")
print(cur.fetchone()[0]) # -> SHA-256 hash
conn.close()

# Discover which extensions ship with the bundled PostgreSQL binaries
from tinypg import get_available_extension, list_available_extensions

available = list_available_extensions()
pgcrypto_manifest = get_available_extension("pgcrypto")

assert "pgcrypto" in available
assert pgcrypto_manifest is not None
assert pgcrypto_manifest.default_version is not None

# Advanced usage
db = tinypg.EphemeralDB(port=5433, cleanup_timeout=300)
uri = db.start()
Expand All @@ -65,6 +84,99 @@ finally:
- Python 3.8+
- PostgreSQL source compilation tools (if binaries need to be built)

## Bundled PostgreSQL extensions

TinyPG downloads the same portable PostgreSQL builds that ship with the
`pg-embed` project and exposes metadata about every extension included with the
distribution. Use :func:`tinypg.list_available_extensions` or
:func:`tinypg.get_available_extension` to inspect this catalog at runtime. The
default PostgreSQL 15 bundle currently includes the following extensions:

| Extension | Default version | Available versions |
| --- | --- | --- |
| `adminpack` | 2.1 | 1.0, 1.0--1.1, 1.1--2.0, 2.0--2.1 |
| `amcheck` | 1.3 | 1.0, 1.0--1.1, 1.1--1.2, 1.2--1.3 |
| `autoinc` | 1.0 | 1.0 |
| `bloom` | 1.0 | 1.0 |
| `bool_plperl` | 1.0 | 1.0 |
| `bool_plperlu` | 1.0 | 1.0 |
| `btree_gin` | 1.3 | 1.0, 1.0--1.1, 1.1--1.2, 1.2--1.3 |
| `btree_gist` | 1.7 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7 |
| `citext` | 1.6 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6 |
| `cube` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5 |
| `dblink` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `dict_int` | 1.0 | 1.0 |
| `dict_xsyn` | 1.0 | 1.0 |
| `earthdistance` | 1.1 | 1.0--1.1, 1.1 |
| `file_fdw` | 1.0 | 1.0 |
| `fuzzystrmatch` | 1.1 | 1.0--1.1, 1.1 |
| `hstore` | 1.8 | 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8 |
| `hstore_plperl` | 1.0 | 1.0 |
| `hstore_plperlu` | 1.0 | 1.0 |
| `hstore_plpython3u` | 1.0 | 1.0 |
| `insert_username` | 1.0 | 1.0 |
| `intagg` | 1.1 | 1.0--1.1, 1.1 |
| `intarray` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5 |
| `isn` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `jsonb_plperl` | 1.0 | 1.0 |
| `jsonb_plperlu` | 1.0 | 1.0 |
| `jsonb_plpython3u` | 1.0 | 1.0 |
| `lo` | 1.1 | 1.0--1.1, 1.1 |
| `ltree` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `ltree_plpython3u` | 1.0 | 1.0 |
| `moddatetime` | 1.0 | 1.0 |
| `old_snapshot` | 1.0 | 1.0 |
| `pageinspect` | 1.11 | 1.0--1.1, 1.1--1.2, 1.10--1.11, 1.2--1.3, 1.3--1.4, 1.4--1.5, 1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8, 1.8--1.9, 1.9--1.10 |
| `pg_buffercache` | 1.3 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3 |
| `pg_freespacemap` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_prewarm` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_stat_statements` | 1.10 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8, 1.8--1.9, 1.9--1.10 |
| `pg_surgery` | 1.0 | 1.0 |
| `pg_trgm` | 1.6 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3, 1.3--1.4, 1.4--1.5, 1.5--1.6 |
| `pg_visibility` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_walinspect` | 1.0 | 1.0 |
| `pgcrypto` | 1.3 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3 |
| `pgrowlocks` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `pgstattuple` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5 |
| `plperl` | 1.0 | 1.0 |
| `plperlu` | 1.0 | 1.0 |
| `plpgsql` | 1.0 | 1.0 |
| `plpython3u` | 1.0 | 1.0 |
| `pltcl` | 1.0 | 1.0 |
| `pltclu` | 1.0 | 1.0 |
| `postgres_fdw` | 1.1 | 1.0, 1.0--1.1 |
| `refint` | 1.0 | 1.0 |
| `seg` | 1.4 | 1.0--1.1, 1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4 |
| `sslinfo` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `tablefunc` | 1.0 | 1.0 |
| `tcn` | 1.0 | 1.0 |
| `tsm_system_rows` | 1.0 | 1.0 |
| `tsm_system_time` | 1.0 | 1.0 |
| `unaccent` | 1.1 | 1.0--1.1, 1.1 |
| `uuid-ossp` | 1.1 | 1.0--1.1, 1.1 |
| `xml2` | 1.1 | 1.0--1.1, 1.1 |

Third-party extensions such as `pgvector`, `pg_tle`, or `pgmq` are not packaged
with the official binaries yet. Adding additional
extension in the future could be possible so these ecosystems can be supported once the
project provides a portable installation workflow for them.

### Can I use other postgres extensions?

Not yet no. It's possible but it isn't supported yet.

At the moment the portable PostgreSQL builds bundled with TinyPG do not expose
the `pg_config` utility that PGXN requires, so the helper exits with a clear
error explaining that third-party compilation is not yet possible. This script
still serves as a reference point for the command sequence and will succeed once
the toolchain includes `pg_config` in a future release.

Building extensions requires a standard C compiler toolchain, development
headers, and network access to fetch dependency archives. These prerequisites
are available on most Linux distributions. This process is currently unsupported
as the trimmed down postgres distribution tinypg uses does not have pg_config
or postgres dev headers avaialble.

## Documentation / API Reference

TinyPG's documentation is available there:
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "tinypg"
version = "0.1.0"
version = "0.2.0"
description = "Ephemeral PostgreSQL databases for Python development and testing"
readme = "README.md"
license = {text = "MIT"}
Expand All @@ -15,6 +15,7 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS :: MacOS X",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand Down
105 changes: 104 additions & 1 deletion src/tinypg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,99 @@
db.stop()
```

## Extensions

TinyPG downloads the same portable PostgreSQL builds that ship with the
`pg-embed` project and exposes metadata about every extension included with the
distribution. Use :func:`tinypg.list_available_extensions` or
:func:`tinypg.get_available_extension` to inspect this catalog at runtime. The
default PostgreSQL 15 bundle currently includes the following extensions:

| Extension | Default version | Available versions |
| --- | --- | --- |
| `adminpack` | 2.1 | 1.0, 1.0--1.1, 1.1--2.0, 2.0--2.1 |
| `amcheck` | 1.3 | 1.0, 1.0--1.1, 1.1--1.2, 1.2--1.3 |
| `autoinc` | 1.0 | 1.0 |
| `bloom` | 1.0 | 1.0 |
| `bool_plperl` | 1.0 | 1.0 |
| `bool_plperlu` | 1.0 | 1.0 |
| `btree_gin` | 1.3 | 1.0, 1.0--1.1, 1.1--1.2, 1.2--1.3 |
| `btree_gist` | 1.7 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7 |
| `citext` | 1.6 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6 |
| `cube` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5 |
| `dblink` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `dict_int` | 1.0 | 1.0 |
| `dict_xsyn` | 1.0 | 1.0 |
| `earthdistance` | 1.1 | 1.0--1.1, 1.1 |
| `file_fdw` | 1.0 | 1.0 |
| `fuzzystrmatch` | 1.1 | 1.0--1.1, 1.1 |
| `hstore` | 1.8 | 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8 |
| `hstore_plperl` | 1.0 | 1.0 |
| `hstore_plperlu` | 1.0 | 1.0 |
| `hstore_plpython3u` | 1.0 | 1.0 |
| `insert_username` | 1.0 | 1.0 |
| `intagg` | 1.1 | 1.0--1.1, 1.1 |
| `intarray` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3, 1.3--1.4, 1.4--1.5 |
| `isn` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `jsonb_plperl` | 1.0 | 1.0 |
| `jsonb_plperlu` | 1.0 | 1.0 |
| `jsonb_plpython3u` | 1.0 | 1.0 |
| `lo` | 1.1 | 1.0--1.1, 1.1 |
| `ltree` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `ltree_plpython3u` | 1.0 | 1.0 |
| `moddatetime` | 1.0 | 1.0 |
| `old_snapshot` | 1.0 | 1.0 |
| `pageinspect` | 1.11 | 1.0--1.1, 1.1--1.2, 1.10--1.11, 1.2--1.3, 1.3--1.4, 1.4--1.5, 1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8, 1.8--1.9, 1.9--1.10 |
| `pg_buffercache` | 1.3 | 1.0--1.1, 1.1--1.2, 1.2, 1.2--1.3 |
| `pg_freespacemap` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_prewarm` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_stat_statements` | 1.10 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5, 1.5--1.6, 1.6--1.7, 1.7--1.8, 1.8--1.9, 1.9--1.10 |
| `pg_surgery` | 1.0 | 1.0 |
| `pg_trgm` | 1.6 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3, 1.3--1.4, 1.4--1.5, 1.5--1.6 |
| `pg_visibility` | 1.2 | 1.0--1.1, 1.1, 1.1--1.2 |
| `pg_walinspect` | 1.0 | 1.0 |
| `pgcrypto` | 1.3 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3 |
| `pgrowlocks` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `pgstattuple` | 1.5 | 1.0--1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4, 1.4, 1.4--1.5 |
| `plperl` | 1.0 | 1.0 |
| `plperlu` | 1.0 | 1.0 |
| `plpgsql` | 1.0 | 1.0 |
| `plpython3u` | 1.0 | 1.0 |
| `pltcl` | 1.0 | 1.0 |
| `pltclu` | 1.0 | 1.0 |
| `postgres_fdw` | 1.1 | 1.0, 1.0--1.1 |
| `refint` | 1.0 | 1.0 |
| `seg` | 1.4 | 1.0--1.1, 1.1, 1.1--1.2, 1.2--1.3, 1.3--1.4 |
| `sslinfo` | 1.2 | 1.0--1.1, 1.1--1.2, 1.2 |
| `tablefunc` | 1.0 | 1.0 |
| `tcn` | 1.0 | 1.0 |
| `tsm_system_rows` | 1.0 | 1.0 |
| `tsm_system_time` | 1.0 | 1.0 |
| `unaccent` | 1.1 | 1.0--1.1, 1.1 |
| `uuid-ossp` | 1.1 | 1.0--1.1, 1.1 |
| `xml2` | 1.1 | 1.0--1.1, 1.1 |

Third-party extensions such as `pgvector`, `pg_tle`, or `pgmq` are not packaged
with the official binaries yet. Adding additional
extension in the future could be possible so these ecosystems can be supported once the
project provides a portable installation workflow for them.

### Can I use other postgres extensions?

Not yet no. It's possible but it isn't supported yet.

At the moment the portable PostgreSQL builds bundled with TinyPG do not expose
the `pg_config` utility that PGXN requires, so the helper exits with a clear
error explaining that third-party compilation is not yet possible. This script
still serves as a reference point for the command sequence and will succeed once
the toolchain includes `pg_config` in a future release.

Building extensions requires a standard C compiler toolchain, development
headers, and network access to fetch dependency archives. These prerequisites
are available on most Linux distributions. This process is currently unsupported
as the trimmed down postgres distribution tinypg uses does not have pg_config
or postgres dev headers avaialble.

## Requirements

- Python 3.8+
Expand All @@ -76,12 +169,22 @@
DownloadError,
TinyPGError,
)
from .extensions import (
ExtensionManifest,
ExtensionSpec,
get_available_extension,
list_available_extensions,
)

__version__ = "0.1.0"
__version__ = "0.2.0"

__all__ = [
"EphemeralDB",
"AsyncEphemeralDB",
"ExtensionSpec",
"ExtensionManifest",
"get_available_extension",
"list_available_extensions",
"database",
"async_database",
"database_pool",
Expand Down
Loading