Acquisition, normalization, versioning, and persistence for Riftbound data.
Project description
riftbound-database
riftbound-database est la librairie d'acquisition, de normalisation,
d'historisation et de persistance des données Riftbound.
Le projet suit cette direction de dépendances :
riftbound-core
↑ utilisé par
riftbound-database
↓ utilise
baobab-database
Le modèle métier canonique appartient à riftbound-core. Ce dépôt ne doit pas
redéfinir les cartes, sets, domaines, types, tags, coûts ou textes de carte.
L'accès aux moteurs, sessions et transactions SQLAlchemy sera encapsulé derrière
un adaptateur local de baobab-database.
Prérequis
- Python 3.12 ou 3.13 ;
- PostgreSQL pour l'intégration, SQLite étant réservé aux tests rapides.
Installation de développement
python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
La dépendance riftbound-core est résolue depuis PyPI (>=0.1.1,<0.2).
Configuration
| Variable | Obligatoire | Valeur par défaut | Rôle |
|---|---|---|---|
RIFTBOUND_DATABASE_URL |
Non au bootstrap | aucune | URL de connexion ; obligatoire pour les futures opérations de base |
RIFTBOUND_STORAGE_PATH |
Non | storage |
Racine du stockage local |
RIFTBOUND_LOG_LEVEL |
Non | INFO |
Niveau de logs Python |
RIFTBOUND_ENVIRONMENT |
Non | development |
Nom de l'environnement d'exécution |
Les secrets éventuellement présents dans RIFTBOUND_DATABASE_URL ne doivent
jamais être écrits dans les logs. Les fichiers .env sont ignorés par Git.
Provider de base de données
Les moteurs, sessions et transactions passent exclusivement par
riftbound_database.database.BaobabProvider. PostgreSQL utilise
baobab-database 2.0.0 avec le driver psycopg; SQLite est limité aux tests
sur fichier temporaire.
L'adaptation complète et les options SSL supportées sont documentées dans
docs/database-provider.md.
Modèles et migrations
Les modèles SQLAlchemy vivent sous riftbound_database.database.models. Les
mappers domaine ↔ persistance sont sous database/mappers. Alembic est configuré
via alembic.ini et exécutable avec :
python -m alembic upgrade head
Pour les tests locaux sans PostgreSQL, définir RIFTBOUND_MIGRATION_SQLITE_PATH
ou laisser Alembic utiliser la base SQLite par défaut sous .my_cache/.
Repositories
Les écritures applicatives passent par RiftboundUnitOfWork, qui expose les
repositories sans créer de session locale. Les retours sont limités aux objets
riftbound-core ou aux read models sous database/read_models/.
from riftbound_database.database.baobab_provider import BaobabProvider
from riftbound_database.database.unit_of_work import RiftboundUnitOfWork
provider = BaobabProvider.for_sqlite("test.db")
unit_of_work = RiftboundUnitOfWork(provider)
with unit_of_work.transaction() as repositories:
card = repositories.cards.find_by_stable_id("card-001")
Ingestion
Les imports passent par BaseImporter, qui orchestre fetch, stockage raw,
checksum, batch et persistance via les repositories. SetImporter importe
des fichiers JSON locaux de façon idempotente avec normalisation, checksum
canonique et stockage sous normalized_data/sets/. CardNormalizer produit
des DTO canoniques compatibles avec riftbound-core, calcule un checksum
stable et signale les champs ambigus via le statut needs_review. Les
importers cartes (LocalFileCardImporter, OfficialApiCardImporter,
CardGalleryImporter) normalisent, versionnent et persistent les cartes via
les repositories. Les documents normatifs passent par RulesImporter,
ErrataImporter et BanlistImporter avec normalisation, checksums stables,
historisation (rules_versions, snapshots banlist) et statuts
matched / ambiguous / needs_review. Un FakeImporter est disponible
pour les tests.
Assets
Les images de cartes sont téléchargées par CardAssetDownloader, validées
(MIME, taille minimale, signature binaire) puis stockées sous
{RIFTBOUND_STORAGE_PATH}/card_assets/{set_code}/{card_id}/ avec un
metadata.json par carte. La persistance relationnelle passe par
AssetRepository ; un checksum inchangé évite les écritures inutiles.
from riftbound_database.assets import AssetDownloadRequest, AssetVariant, CardAssetDownloader
from riftbound_database.config.settings import Settings
from riftbound_database.database.baobab_provider import BaobabProvider
from riftbound_database.database.unit_of_work import RiftboundUnitOfWork
settings = Settings()
downloader = CardAssetDownloader()
provider = BaobabProvider.for_sqlite("test.db")
unit_of_work = RiftboundUnitOfWork(provider)
request = AssetDownloadRequest(
set_code="OGN",
card_id="card-unit-001",
variant=AssetVariant.ORIGINAL,
source_url="https://example.test/card.png",
)
with unit_of_work.transaction() as repositories:
result = downloader.download(request, settings, repositories.assets)
Synchronisation
Les jobs sous riftbound_database.sync orchestrent les importers via un
SyncManifest JSON (ADR-0002) : chemins locaux + liste assets[] avec URLs
source explicites. FullSyncJob exécute dans l'ordre
sets → cartes → assets → règles → errata → banlists, avec dry_run et
SyncReport final.
from riftbound_database.sync import FullSyncJob, SyncContext, SyncManifestLoader
manifest = SyncManifestLoader.load(Path("sync.json"))
context = SyncContext(settings=settings, unit_of_work=unit_of_work, manifest=manifest)
report = FullSyncJob().run(context)
CLI
La CLI Typer est exposée via le script riftbound-database (ou
python -m riftbound_database.cli.main). Options globales :
--database-url, --sqlite-path, --storage-path, --log-level.
riftbound-database --sqlite-path ./local.db db upgrade
riftbound-database --sqlite-path ./local.db import sets --path ./sets.json
riftbound-database --sqlite-path ./local.db import cards --source local-file --path ./cards.json
riftbound-database --sqlite-path ./local.db import rules --path ./rules.json
riftbound-database --sqlite-path ./local.db import errata --path ./errata.json
riftbound-database --sqlite-path ./local.db import banlist --path ./banlist.json
riftbound-database --sqlite-path ./local.db assets download --manifest ./sync.json
riftbound-database --sqlite-path ./local.db sync full --manifest ./sync.json
riftbound-database checksums verify
riftbound-database export normalized --format json
Les imports supportent --dry-run et --limit. Les commandes retournent un
code de sortie non nul en cas d'échec ; les secrets de connexion ne sont jamais
loggés.
Qualité
python -m pytest
python -m coverage run -m pytest
python -m coverage report
python -m ruff check .
python -m mypy src tests
python -m bandit -r src
Tests rapides vs intégration
# unitaires (CI par défaut)
python -m pytest -m "not integration and not postgresql"
# migrations SQLite
python -m pytest tests/integration/riftbound_database/database/migrations/
# PostgreSQL (service local requis)
set RIFTBOUND_TEST_POSTGRESQL_URL=postgresql+psycopg://user:pass@localhost:5432/riftbound_test
python -m pytest -m postgresql
Couverture minimale configurée : 85 % (pyproject.toml).
CI GitHub Actions
Le workflow .github/workflows/ci.yml exécute sur chaque push/PR vers main :
- quality : ruff, mypy, bandit ;
- unit : pytest + coverage (Python 3.12 et 3.13) ;
- integration : migrations SQLite + test PostgreSQL via service container.
Les dépendances (riftbound-core, baobab-database) sont installées depuis PyPI ;
aucun secret GitHub n'est requis pour la CI si tous les packages restent publics.
Documentation projet
Le cahier des charges et le découpage fonctionnel sont disponibles dans
docs/. Le développement suit l'ordre séquentiel des
backlogs BL-001 à BL-014.
Project details
Release history Release notifications | RSS feed
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 riftbound_database-0.1.1.tar.gz.
File metadata
- Download URL: riftbound_database-0.1.1.tar.gz
- Upload date:
- Size: 160.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c62db2ebcec660164594f6617cb941d9edf0da38076af282cafc99db8024d6a2
|
|
| MD5 |
bcbabc743a7881b7e450df6351275312
|
|
| BLAKE2b-256 |
39536a58f0cbaff5265154759858edba936774b8c5cf397c5b55e1bdeee18b8c
|
Provenance
The following attestation bundles were made for riftbound_database-0.1.1.tar.gz:
Publisher:
release.yml on baobabgit/riftbound-database
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
riftbound_database-0.1.1.tar.gz -
Subject digest:
c62db2ebcec660164594f6617cb941d9edf0da38076af282cafc99db8024d6a2 - Sigstore transparency entry: 1820122874
- Sigstore integration time:
-
Permalink:
baobabgit/riftbound-database@07fa46ff4a90197b8e76c6af1059fb139d5448c5 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/baobabgit
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@07fa46ff4a90197b8e76c6af1059fb139d5448c5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file riftbound_database-0.1.1-py3-none-any.whl.
File metadata
- Download URL: riftbound_database-0.1.1-py3-none-any.whl
- Upload date:
- Size: 138.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34199830672dfd15209e26289d20dc7a1287d132165c03312dca378c86a629d3
|
|
| MD5 |
1f033ec6cc8f519b93e87fea946c22ef
|
|
| BLAKE2b-256 |
4e7c177007d2aa099a1ec4cb809ce320325db5eef962aaa9eac805e5f0020553
|
Provenance
The following attestation bundles were made for riftbound_database-0.1.1-py3-none-any.whl:
Publisher:
release.yml on baobabgit/riftbound-database
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
riftbound_database-0.1.1-py3-none-any.whl -
Subject digest:
34199830672dfd15209e26289d20dc7a1287d132165c03312dca378c86a629d3 - Sigstore transparency entry: 1820122942
- Sigstore integration time:
-
Permalink:
baobabgit/riftbound-database@07fa46ff4a90197b8e76c6af1059fb139d5448c5 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/baobabgit
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@07fa46ff4a90197b8e76c6af1059fb139d5448c5 -
Trigger Event:
push
-
Statement type: