wxyc-catalog
WXYC library catalog access and operations. This package defines the CatalogSource protocol — a read-only interface to the WXYC library catalog — with implementations for tubafrenzy (MySQL) and Backend-Service (PostgreSQL). It also provides CLI tools that produce pipeline inputs for downstream services: library.db (SQLite with FTS5), library_artists.txt, and library_labels.csv.
CatalogSource Protocol
CatalogSource is a @runtime_checkable Protocol that abstracts over the two catalog databases. Both implementations return identical data structures despite different underlying schemas.
class CatalogSource(Protocol):
def fetch_library_rows(self) -> list[dict[str, Any]]:
"""Library releases. Keys: id, title, artist, call_letters,
artist_call_number, release_call_number, release_call_letters, genre,
format, alternate_artist_name, label, cross_reference_names."""
def fetch_alternate_names(self) -> set[str]:
"""Alternate artist names (e.g. 'Body Count' filed under Ice-T)."""
def fetch_cross_referenced_artists(self) -> set[str]:
"""Artist names from both sides of the artist cross-reference table."""
def fetch_release_cross_ref_artists(self) -> set[str]:
"""Artist names from library-level cross-references."""
def fetch_library_labels(self) -> set[tuple[str, str, str]]:
"""(artist, title, label) triples from flowsheet plays."""
def close(self) -> None:
"""Release the database connection."""
release_call_letters is the per-release volume letter that tells the items of a multi-volume set apart (volume A vs G of a set shelved at one call number). It is distinct from call_letters, the artist code (e.g. V/A). Both sources emit it as None or one upper-case value (normalize_volume_letters): tubafrenzy's '' and Backend's empty values become None, and 'b' becomes 'B', matching Backend-Service's case-insensitive slot key. Backend-Service stores the column as wxyc_schema.library.code_volume_letters.
Implementations
| Source | Database | Connection |
|---|---|---|
TubafrenzySource |
MySQL 4.1+ (Kattare) | pymysql |
BackendServiceSource |
PostgreSQL (Backend-Service) | psycopg |
Use the factory function to create a source by name:
from wxyc_catalog import create_catalog_source
source = create_catalog_source("tubafrenzy", "mysql://user:pass@host/db")
# or
source = create_catalog_source("backend-service", "postgresql://user:pass@host/db")
MySQL 4.1 Compatibility
Kattare runs MySQL 4.1.22 with old-format password hashes. No modern Python MySQL driver supports this auth protocol. The daily library sync workflow (discogs-etl/scripts/sync-library.sh) uses the MariaDB mysql CLI client instead, which handles old auth natively. The connect_mysql() function in this package uses pymysql, which works with MySQL 5.x+ servers.
Installation
pip install wxyc-catalog
For MySQL support (tubafrenzy):
pip install "wxyc-catalog[mysql]"
CLI Tools
wxyc-export-to-sqlite
Exports the library catalog to a SQLite database with an FTS5 full-text search index on title, artist, and alternate_artist_name. The library table's last column, release_call_letters (nullable TEXT), holds the volume letter; it is a shelf-locator component and is deliberately not in the FTS index. New columns are appended so existing columns keep their ordinal positions.
wxyc-export-to-sqlite \
--catalog-source tubafrenzy \
--catalog-db-url mysql://user:pass@host/db \
--output library.db
wxyc-enrich-library-artists
Generates library_artists.txt containing all unique artist names, enriched with alternate names, cross-references, and contextual splitting of multi-artist entries (names with commas, slashes, ampersands) via wxyc_etl.
wxyc-enrich-library-artists \
--library-db library.db \
--catalog-source backend-service \
--catalog-db-url postgresql://user:pass@host/db \
--output library_artists.txt
wxyc-extract-library-labels
Extracts (artist, title, label) triples from flowsheet plays to CSV.
wxyc-extract-library-labels \
--catalog-source tubafrenzy \
--catalog-db-url mysql://user:pass@host/db \
--output library_labels.csv
Programmatic Usage
from wxyc_catalog import create_catalog_source, export_rows_to_sqlite
from pathlib import Path
source = create_catalog_source("backend-service", "postgresql://user:pass@host/db")
rows = source.fetch_library_rows()
source.close()
export_rows_to_sqlite(rows, Path("library.db"))
Downstream Consumers
| Repo | Usage |
|---|---|
| discogs-etl | CI tests import CatalogSource for integration/E2E tests. Pipeline scripts use enrich_library_artists and extract_library_labels. The production library.db is not built by this package: discogs-etl's daily scripts/sync-library.sh builds it from Backend-Service's HTTP catalog export with its own writer (lib/library_db.py), so a column added to export_rows_to_sqlite reaches production only once that builder carries it too. |
Dependencies
psycopg[binary]>=3.1— PostgreSQL driverwxyc-etl>=0.1.0— text normalization (split_artist_name_contextual,is_compilation_artist)pymysql>=1.0— MySQL driver (optional,[mysql]extra)
Development
pip install -e ".[dev]"
pytest
ruff check
ruff format --check
Metadata
Release files for wxyc-catalog 0.2.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 | |
|---|---|---|---|---|
| wxyc_catalog-0.2.0.tar.gz | 25.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wxyc_catalog-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.7 kB
Release files / wxyc_catalog-0.2.0.tar.gz
| Download URL | wxyc_catalog-0.2.0.tar.gz |
|---|---|
| Size | 25.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5f5724b85a9e75661cc65a8e1a9fd3231e0ff168eeede97356fb1d715e44dde
|
|
BLAKE2b-256 checksum How to use checksums |
51bc41c6be2c62ac52a18e94a72d54344c8fff397b2cf4da347e96dfcc5ad8d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wxyc_catalog-0.2.0-py3-none-any.whl
| Download URL | wxyc_catalog-0.2.0-py3-none-any.whl |
|---|---|
| Size | 25.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0f4e98cc847665af71f37f9e0f9322870e0d08d091b1cae0c07e537dbd1eab8a
|
|
BLAKE2b-256 checksum How to use checksums |
9aef1b64625de4287d542f6406bc235f53d2a44d51ecdbe5c98e832e2f1693a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for wxyc-catalog 0.2.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.