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
26 changes: 25 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Continuous integration for psycodict.
#
# Four jobs, cheapest first, so an obvious mistake fails in under a minute:
# Five jobs, cheapest first, so an obvious mistake fails in under a minute:
#
# lint static checks, no interpreter matrix, no database
# unit the database-free tests on every supported Python
# database the full suite against real PostgreSQL service containers
# package sdist/wheel build, twine metadata check, install smoke tests
# docs the Sphinx build with warnings as errors, no database
#
# The downstream regression suites (LMFDB and seminars) live in a separate
# workflow, downstream.yml, because they are an order of magnitude slower.
Expand Down Expand Up @@ -200,3 +201,26 @@ jobs:
with:
name: dist
path: dist/

docs:
name: Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: pip

# The package itself is installed so that autodoc can import it; no
# database is needed (importing psycodict does not connect).
- name: Install package and documentation dependencies
run: |
python -m pip install '.[pgbinary]' -r docs/requirements.txt

# -W turns warnings into errors: a broken cross-reference or a
# malformed docstring fails here rather than silently degrading the
# site. Read the Docs builds with fail_on_warning to match.
- name: Build documentation
run: python -m sphinx -W --keep-going -b html docs docs/_build/html
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,12 @@ secrets.ini
# Local database configuration (may contain a password): copy
# config.ini.example to config.ini and edit. Should not be committed.
config.ini
# Guides copied into docs/ at build time by docs/conf.py
docs/README.md
docs/QueryLanguage.md
docs/Searching.md
docs/DataManagement.md
docs/MetadataFormats.md
docs/Versioning.md
docs/CONTRIBUTING.md
docs/SECURITY.md
27 changes: 27 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Read the Docs build configuration for the psycodict documentation.
#
# One manual step activates this: import the repository at
# https://readthedocs.org/dashboard/import/ (the psycodict GitHub App
# integration handles builds on push and pull-request previews from then
# on). Once 1.0 is tagged, activate the tag under Versions so that
# /stable/ serves the release while /latest/ tracks master.
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.12"

sphinx:
configuration: docs/conf.py
# The same contract as the docs job in ci.yml: a broken cross-reference
# or malformed docstring fails the build rather than degrading the site.
fail_on_warning: true

python:
install:
# The package itself, so that autodoc can import it.
- method: pip
path: .
extra_requirements: [pgbinary]
- requirements: docs/requirements.txt
1 change: 1 addition & 0 deletions DataManagement.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Data management

## Introduction

Expand Down
1 change: 1 addition & 0 deletions QueryLanguage.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# The query language

## Introduction

Expand Down
2 changes: 1 addition & 1 deletion Searching.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ database and a table variable such as `nf = db.nf_fields`.

- [Stability](#stability)
- [`search`](#search)
- [Parameters](#search-parameters)
- [Parameters](#parameters)
- [Return type: iterator vs. list](#return-type-iterator-vs-list)
- [Projections](#projections)
- [Sorting](#sorting)
Expand Down
5 changes: 5 additions & 0 deletions docs/api/base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.base

```{eval-rst}
.. automodule:: psycodict.base
```
5 changes: 5 additions & 0 deletions docs/api/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.config

```{eval-rst}
.. automodule:: psycodict.config
```
5 changes: 5 additions & 0 deletions docs/api/database.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.database

```{eval-rst}
.. automodule:: psycodict.database
```
5 changes: 5 additions & 0 deletions docs/api/dbdiff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.dbdiff

```{eval-rst}
.. automodule:: psycodict.dbdiff
```
5 changes: 5 additions & 0 deletions docs/api/encoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.encoding

```{eval-rst}
.. automodule:: psycodict.encoding
```
44 changes: 44 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# API reference

Generated from the docstrings. The map of the library:

- {mod}`psycodict.database` — {class}`~psycodict.database.PostgresDatabase`,
the connection object; each table in the database is an attribute of it.
- {mod}`psycodict.searchtable` —
{class}`~psycodict.searchtable.PostgresSearchTable`, the read API
(`search`, `lucky`, `lookup`, `count`, `random`, …) driven by the query
dictionaries of [the query language](../QueryLanguage.md).
- {mod}`psycodict.table` — {class}`~psycodict.table.PostgresTable`, the
write and schema half (row writes, bulk file import/export, reloads,
indexes, columns); base class of the search table.
- {mod}`psycodict.statstable` —
{class}`~psycodict.statstable.PostgresStatsTable`, precomputed counts and
statistics, available as `table.stats`.
- {mod}`psycodict.encoding` — value conversion between Python and
PostgreSQL, including the file formats used by the bulk operations.
- {mod}`psycodict.config` — configuration discovery and parsing
(`config.ini`, command-line arguments, `$PSYCODICT_CONFIG`).
- {mod}`psycodict.utils` — {class}`~psycodict.utils.DelayCommit` and other
helpers shared across the library.
- {mod}`psycodict.notifications` — LISTEN/NOTIFY support: schema-change
announcements and a small publish/subscribe primitive.
- {mod}`psycodict.dbdiff` — comparing the contents of two databases.
- {mod}`psycodict.slowlog` — parsing and reporting on the slow-query log.
- {mod}`psycodict.base` — {class}`~psycodict.base.PostgresBase`, the shared
execution and logging plumbing underneath everything else.

```{toctree}
:maxdepth: 1

database
searchtable
table
statstable
encoding
config
utils
notifications
dbdiff
slowlog
base
```
5 changes: 5 additions & 0 deletions docs/api/notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.notifications

```{eval-rst}
.. automodule:: psycodict.notifications
```
5 changes: 5 additions & 0 deletions docs/api/searchtable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.searchtable

```{eval-rst}
.. automodule:: psycodict.searchtable
```
5 changes: 5 additions & 0 deletions docs/api/slowlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.slowlog

```{eval-rst}
.. automodule:: psycodict.slowlog
```
5 changes: 5 additions & 0 deletions docs/api/statstable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.statstable

```{eval-rst}
.. automodule:: psycodict.statstable
```
5 changes: 5 additions & 0 deletions docs/api/table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.table

```{eval-rst}
.. automodule:: psycodict.table
```
5 changes: 5 additions & 0 deletions docs/api/utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# psycodict.utils

```{eval-rst}
.. automodule:: psycodict.utils
```
69 changes: 69 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Configuration for the psycodict documentation build (Sphinx).
#
# Build locally with
#
# pip install '.[pgbinary]' -r docs/requirements.txt
# python -m sphinx -W --keep-going -b html docs docs/_build/html
#
# The same build runs in CI (the docs job of ci.yml) and on Read the Docs
# (.readthedocs.yaml), with warnings treated as errors in both.
import shutil
from importlib.metadata import version as _dist_version
from pathlib import Path

_DOCS = Path(__file__).resolve().parent
_ROOT = _DOCS.parent

# The canonical copies of the narrative guides live at the repository root,
# where GitHub renders them; they are copied here at build time so that the
# site includes them and their relative links to one another keep working.
# The copies are ignored by git (see .gitignore).
_GUIDES = [
"README.md",
"QueryLanguage.md",
"Searching.md",
"DataManagement.md",
"MetadataFormats.md",
"Versioning.md",
"CONTRIBUTING.md",
"SECURITY.md",
]
for _name in _GUIDES:
shutil.copyfile(_ROOT / _name, _DOCS / _name)

project = "psycodict"
author = "David Roe and Edgar Costa"
copyright = "2019–2026, David Roe and Edgar Costa"
release = _dist_version("psycodict")
version = release

extensions = [
"myst_parser",
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
]

# Generate GitHub-style anchors for headings so that intra-page links in the
# Markdown guides ([`search`](#search) and friends) keep working on the site.
myst_heading_anchors = 4

# The API reference is generated from the docstrings, which follow the Sage
# documentation conventions (INPUT:/OUTPUT: bullet blocks, EXAMPLES:: with
# literal transcripts); those are plain reST, so autodoc renders them as-is.
autodoc_member_order = "bysource"
autodoc_default_options = {
"members": True,
"undoc-members": True,
"show-inheritance": True,
}

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"psycopg": ("https://www.psycopg.org/psycopg3/docs", None),
}

exclude_patterns = ["_build"]

html_theme = "furo"
html_title = f"psycodict {release}"
37 changes: 37 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# psycodict

psycodict is a dictionary-based Python interface to PostgreSQL databases:
queries are Python dictionaries, results come back as Python values, and the
metadata that makes this ergonomic — column types, sort orders, statistics —
is managed for you. It was extracted from the
[LMFDB](https://www.lmfdb.org) and powers several mathematical databases.

The guides below describe the system top-down; the API reference is
generated from the docstrings.

```{toctree}
:maxdepth: 2
:caption: Guides

Getting started <README>
QueryLanguage
Searching
DataManagement
MetadataFormats
Versioning
```

```{toctree}
:maxdepth: 2
:caption: Reference

api/index
```

```{toctree}
:maxdepth: 1
:caption: Project

Contributing <CONTRIBUTING>
Security policy <SECURITY>
```
7 changes: 7 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Documentation build dependencies. Used by the docs job in
# .github/workflows/ci.yml and by Read the Docs (.readthedocs.yaml);
# the package itself (with a psycopg extra) must also be installed so
# that autodoc can import it.
sphinx>=7
myst-parser>=3
furo>=2024.1.29
3 changes: 2 additions & 1 deletion psycodict/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ class NotificationListener:
- ``config`` -- a :class:`~psycodict.config.Configuration`; the
``postgresql`` options are used to open the dedicated connection
- ``channels`` -- a channel name, or an iterable of them (default:
``("psycodict_schema",)``); each is validated and ``LISTEN``ed on
``("psycodict_schema",)``); each is validated and subscribed with
``LISTEN``
- ``**connect_kwargs`` -- extra keyword arguments passed on to
``psycopg.connect`` (e.g. keepalive settings), overriding the
configuration where they overlap
Expand Down
Loading