geneweb-py 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geneweb_py-0.1.0/CHANGELOG.md +73 -0
- geneweb_py-0.1.0/LICENSE +21 -0
- geneweb_py-0.1.0/MANIFEST.in +54 -0
- geneweb_py-0.1.0/PKG-INFO +541 -0
- geneweb_py-0.1.0/README.md +483 -0
- geneweb_py-0.1.0/doc/ARCHITECTURE_MULTIPASS.md +219 -0
- geneweb_py-0.1.0/doc/MIGRATION_STRUCTURE_SRC.md +147 -0
- geneweb_py-0.1.0/doc/PERFORMANCE.md +299 -0
- geneweb_py-0.1.0/doc/PYPI_PUBLICATION_GUIDE.md +362 -0
- geneweb_py-0.1.0/doc/PYPI_TESTING_STRATEGY.md +783 -0
- geneweb_py-0.1.0/doc/exports_design.md +243 -0
- geneweb_py-0.1.0/doc/exports_plan.md +261 -0
- geneweb_py-0.1.0/doc/exports_plan_step2.md +155 -0
- geneweb_py-0.1.0/doc/exports_plan_step3.md +259 -0
- geneweb_py-0.1.0/doc/features/data_cleaning.md +530 -0
- geneweb_py-0.1.0/doc/features/obsidian.md +303 -0
- geneweb_py-0.1.0/doc/geneweb/gw_format_documentation.md +404 -0
- geneweb_py-0.1.0/doc/organizations_candidates_design.md +486 -0
- geneweb_py-0.1.0/doc/organizations_candidates_plan.md +641 -0
- geneweb_py-0.1.0/doc/parser_fidelity_audit.md +566 -0
- geneweb_py-0.1.0/doc/parser_finalisation_design.md +391 -0
- geneweb_py-0.1.0/doc/roadmap.md +28 -0
- geneweb_py-0.1.0/doc/shared_experiences_design.md +411 -0
- geneweb_py-0.1.0/doc/status.md +252 -0
- geneweb_py-0.1.0/examples/api_usage.py +204 -0
- geneweb_py-0.1.0/examples/basic_usage.py +165 -0
- geneweb_py-0.1.0/examples/conversion_usage.py +256 -0
- geneweb_py-0.1.0/examples/data_manipulation.py +194 -0
- geneweb_py-0.1.0/examples/parser_improvements_demo.py +117 -0
- geneweb_py-0.1.0/examples/parser_usage.py +158 -0
- geneweb_py-0.1.0/examples/performance_demo.py +270 -0
- geneweb_py-0.1.0/pyproject.toml +213 -0
- geneweb_py-0.1.0/setup.cfg +4 -0
- geneweb_py-0.1.0/src/geneweb_py/__init__.py +23 -0
- geneweb_py-0.1.0/src/geneweb_py/analytics/__init__.py +5 -0
- geneweb_py-0.1.0/src/geneweb_py/analytics/network.py +261 -0
- geneweb_py-0.1.0/src/geneweb_py/api/__init__.py +11 -0
- geneweb_py-0.1.0/src/geneweb_py/api/dependencies.py +75 -0
- geneweb_py-0.1.0/src/geneweb_py/api/family_payload.py +64 -0
- geneweb_py-0.1.0/src/geneweb_py/api/limits.py +87 -0
- geneweb_py-0.1.0/src/geneweb_py/api/main.py +222 -0
- geneweb_py-0.1.0/src/geneweb_py/api/middleware/__init__.py +3 -0
- geneweb_py-0.1.0/src/geneweb_py/api/middleware/error_handler.py +153 -0
- geneweb_py-0.1.0/src/geneweb_py/api/middleware/logging.py +100 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/__init__.py +3 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/event.py +192 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/family.py +178 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/organization.py +154 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/person.py +311 -0
- geneweb_py-0.1.0/src/geneweb_py/api/models/responses.py +122 -0
- geneweb_py-0.1.0/src/geneweb_py/api/person_payload.py +67 -0
- geneweb_py-0.1.0/src/geneweb_py/api/rate_limit.py +22 -0
- geneweb_py-0.1.0/src/geneweb_py/api/router_helpers.py +32 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/__init__.py +8 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/events.py +503 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/families.py +374 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/genealogy.py +515 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/organizations.py +150 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/persons.py +431 -0
- geneweb_py-0.1.0/src/geneweb_py/api/routers/sessions.py +133 -0
- geneweb_py-0.1.0/src/geneweb_py/api/serialization.py +344 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/__init__.py +3 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/export_bundle.py +30 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/genealogy_service.py +1552 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/organization_candidates.py +445 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/organization_exports.py +223 -0
- geneweb_py-0.1.0/src/geneweb_py/api/services/organization_tables.py +253 -0
- geneweb_py-0.1.0/src/geneweb_py/api/session_store.py +132 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/app.js +2393 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/index.html +273 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/style.css +860 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/toldot-logo.png +0 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/bootstrap.bundle.min.js +7 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/bootstrap.min.css +6 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/tabulator.min.css +2 -0
- geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/tabulator.min.js +3 -0
- geneweb_py-0.1.0/src/geneweb_py/cli/__init__.py +9 -0
- geneweb_py-0.1.0/src/geneweb_py/cli/commands.py +196 -0
- geneweb_py-0.1.0/src/geneweb_py/cli/entry.py +15 -0
- geneweb_py-0.1.0/src/geneweb_py/core/__init__.py +9 -0
- geneweb_py-0.1.0/src/geneweb_py/core/date.py +620 -0
- geneweb_py-0.1.0/src/geneweb_py/core/event.py +265 -0
- geneweb_py-0.1.0/src/geneweb_py/core/event_to_organization.py +1099 -0
- geneweb_py-0.1.0/src/geneweb_py/core/exceptions.py +648 -0
- geneweb_py-0.1.0/src/geneweb_py/core/family.py +399 -0
- geneweb_py-0.1.0/src/geneweb_py/core/genealogy.py +697 -0
- geneweb_py-0.1.0/src/geneweb_py/core/models.py +42 -0
- geneweb_py-0.1.0/src/geneweb_py/core/note_leads.py +191 -0
- geneweb_py-0.1.0/src/geneweb_py/core/organization.py +209 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/__init__.py +39 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/gw_parser.py +3780 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/lexical.py +825 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/multipass_parser.py +65 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/place_tokens.py +173 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/reconcile.py +359 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/streaming.py +326 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/syntax.py +1668 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/wikitext.py +144 -0
- geneweb_py-0.1.0/src/geneweb_py/core/parser/words.py +167 -0
- geneweb_py-0.1.0/src/geneweb_py/core/person.py +365 -0
- geneweb_py-0.1.0/src/geneweb_py/core/place.py +69 -0
- geneweb_py-0.1.0/src/geneweb_py/core/shared_experiences.py +548 -0
- geneweb_py-0.1.0/src/geneweb_py/core/validation.py +449 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/__init__.py +39 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/base.py +156 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/gedcom.py +1234 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/json.py +429 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/leads_table.py +158 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/org_sidecar.py +103 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/table_writers.py +229 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/tables.py +389 -0
- geneweb_py-0.1.0/src/geneweb_py/formats/xml.py +808 -0
- geneweb_py-0.1.0/src/geneweb_py/py.typed +0 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/PKG-INFO +541 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/SOURCES.txt +117 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/dependency_links.txt +1 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/entry_points.txt +2 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/requires.txt +39 -0
- geneweb_py-0.1.0/src/geneweb_py.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Toutes les modifications notables de ce projet seront documentées dans ce fichier.
|
|
4
|
+
|
|
5
|
+
Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/),
|
|
6
|
+
et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **API** : Statistiques avancées dans `get_stats` (longévité, top lieux, histogramme enfants/famille).
|
|
12
|
+
- **API** : Filtres recherche personnes par plage d'année (naissance/décès) et par lieu.
|
|
13
|
+
- **API** : Endpoint `POST /genealogy/validate` branché sur `Genealogy.validate_consistency` avec option `strict`.
|
|
14
|
+
- **Core** : Méthode `Date.sort_year()` pour les filtres temporels.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Core** : `Genealogy.validate_consistency(strict=True)` remplace les erreurs stockées à chaque passe (pas de cumul entre appels).
|
|
18
|
+
- **API** : Filtres année naissance/décès par chevauchement avec les segments OR/BETWEEN (`Date.filter_years_for_range`).
|
|
19
|
+
- **API** : Recherche lieu personnes avec NFKC + `casefold` ; exposition des query params année/lieu sur `GET /persons/`.
|
|
20
|
+
- **API** : Message HTTP de `POST /genealogy/validate` reflète `is_valid` ; doc OpenAPI du mode `strict` précisée.
|
|
21
|
+
- **Structure** : Migration vers structure `src/` (meilleure pratique PyPA)
|
|
22
|
+
- Package déplacé de `geneweb_py/` vers `src/geneweb_py/`
|
|
23
|
+
- Mise à jour de `pyproject.toml` pour pointer vers `src/`
|
|
24
|
+
- Mise à jour de tous les scripts et tests
|
|
25
|
+
- Suppression des dossiers vides (`utils/`, `tests/`, `examples/` dans le package)
|
|
26
|
+
- **Email** : Mise à jour vers `guillaume.cayeux@relais4x100a2.fr`
|
|
27
|
+
|
|
28
|
+
### Documentation
|
|
29
|
+
- **README / pyproject** : Badge Python dérivé de `requires-python` sur `main`, section « Standards » explicite (Ruff remplace Black/Flake8), URL `Changelog` dans les métadonnées PyPA, extra `parsing` / Lark clarifié comme optionnel.
|
|
30
|
+
- 🧹 **Nettoyage documentation** : Suppression de 24 fichiers Markdown non conformes à la racine
|
|
31
|
+
- 📊 **Métriques de tests / couverture** : source unique **[doc/status.md](doc/status.md)** ; tendance CI sur [Codecov](https://codecov.io/gh/Relais4x100a2/geneweb-py) ; README et index sans pourcentages dupliqués divergents
|
|
32
|
+
- 📝 **Conformité structure** : Seuls README.md, CHANGELOG.md, DOCUMENTATION.md à la racine
|
|
33
|
+
- 🏗️ **Organisation** : Documentation conforme aux règles Cursor du projet
|
|
34
|
+
- Consolidation complète de la documentation
|
|
35
|
+
- Suppression des fichiers de résumés de sessions obsolètes
|
|
36
|
+
- Restructuration de la section documentation dans README
|
|
37
|
+
- Mise à jour du statut du projet et de l'architecture
|
|
38
|
+
|
|
39
|
+
## [0.1.0] - 2025-10-09
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
- ✨ **Parser avancé** : Support des apostrophes, caractères spéciaux, numéros d'occurrence
|
|
43
|
+
- ✨ **Nouveaux blocs** : Support `notes-db`, `page-ext`, `wizard-note`
|
|
44
|
+
- ✨ **Optimisations** : Mode streaming automatique pour fichiers >10MB (~80% réduction mémoire)
|
|
45
|
+
- ✨ **Validation gracieuse** : Mode strict/gracieux avec collecte d'erreurs
|
|
46
|
+
- ✨ **Messages enrichis** : Erreurs contextuelles avec ligne, token, suggestions
|
|
47
|
+
- ✨ **Tests PyPI** : 43 tests (packaging, compatibilité, sécurité)
|
|
48
|
+
- ✨ **CI/CD** : GitHub Actions pour tests et publication automatisée
|
|
49
|
+
- ✨ **Scripts** : Validation PyPI bash et Python
|
|
50
|
+
- 📚 **Documentation** : 7 guides complets (performance, publication, tests)
|
|
51
|
+
|
|
52
|
+
### Performance
|
|
53
|
+
- ⚡ **Streaming** : ~80% réduction mémoire sur gros fichiers
|
|
54
|
+
- ⚡ **CPU** : ~15-20% plus rapide sur petits fichiers
|
|
55
|
+
- ⚡ **Cache LRU** : Patterns regex mis en cache
|
|
56
|
+
- ⚡ **__slots__** : ~40% réduction mémoire par token
|
|
57
|
+
|
|
58
|
+
### Tests & Qualité
|
|
59
|
+
- ✅ **Suite de tests étendue** : à la v0.1.0, couverture et volumétrie conformes aux objectifs du projet (détail historique : tag de release, rapport d’époque)
|
|
60
|
+
- ✅ **Multi-versions** : Python 3.8-3.12
|
|
61
|
+
- ✅ **Multi-OS** : Linux, macOS, Windows
|
|
62
|
+
- ✅ **Structure consolidée** : 18 fichiers de tests unitaires
|
|
63
|
+
|
|
64
|
+
### API & Formats
|
|
65
|
+
- 🔌 **API REST** : FastAPI avec endpoints CRUD complets
|
|
66
|
+
- 🔄 **Conversions** : GEDCOM, JSON, XML (import/export)
|
|
67
|
+
|
|
68
|
+
### Architecture
|
|
69
|
+
- 📦 Structure modulaire complète (core, api, formats, utils)
|
|
70
|
+
- 🏗️ Modèles de données avec dataclasses et validation
|
|
71
|
+
- 🛡️ Gestion d'erreurs avec exceptions spécifiques
|
|
72
|
+
- 🎨 Type hints et docstrings françaises
|
|
73
|
+
- 🔧 Configuration via pyproject.toml
|
geneweb_py-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Guillaume Cayeux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# MANIFEST.in
|
|
2
|
+
# Contrôle des fichiers inclus dans la distribution source
|
|
3
|
+
|
|
4
|
+
# Inclure les fichiers de documentation
|
|
5
|
+
include README.md
|
|
6
|
+
include LICENSE
|
|
7
|
+
include CHANGELOG.md
|
|
8
|
+
include pyproject.toml
|
|
9
|
+
|
|
10
|
+
# Inclure la documentation
|
|
11
|
+
recursive-include doc *.md
|
|
12
|
+
recursive-include doc/geneweb *.md
|
|
13
|
+
|
|
14
|
+
# Inclure les exemples
|
|
15
|
+
recursive-include examples *.py
|
|
16
|
+
recursive-include examples/output *.ged *.json *.xml
|
|
17
|
+
|
|
18
|
+
# Exclure les fichiers de développement
|
|
19
|
+
exclude .gitignore
|
|
20
|
+
exclude .coveragerc
|
|
21
|
+
exclude scripts/validate_pypi.sh
|
|
22
|
+
exclude scripts/check_pypi_readiness.py
|
|
23
|
+
|
|
24
|
+
# Exclure les dossiers de test et développement
|
|
25
|
+
recursive-exclude tests *
|
|
26
|
+
recursive-exclude htmlcov *
|
|
27
|
+
recursive-exclude .github *
|
|
28
|
+
recursive-exclude __pycache__ *
|
|
29
|
+
recursive-exclude *.egg-info *
|
|
30
|
+
|
|
31
|
+
# Exclure les fichiers temporaires
|
|
32
|
+
global-exclude *.pyc
|
|
33
|
+
global-exclude *.pyo
|
|
34
|
+
global-exclude *.pyd
|
|
35
|
+
global-exclude .DS_Store
|
|
36
|
+
global-exclude *.so
|
|
37
|
+
global-exclude *.dylib
|
|
38
|
+
|
|
39
|
+
# Exclure les fichiers de cache
|
|
40
|
+
global-exclude *~
|
|
41
|
+
global-exclude *.swp
|
|
42
|
+
global-exclude *.swo
|
|
43
|
+
|
|
44
|
+
# Exclure les rapports
|
|
45
|
+
exclude coverage.json
|
|
46
|
+
exclude COVERAGE_REPORT.md
|
|
47
|
+
exclude IMPLEMENTATION_SUMMARY.md
|
|
48
|
+
exclude OPTIMIZATIONS_SUMMARY.md
|
|
49
|
+
exclude PHASE1_FINAL_SUMMARY.md
|
|
50
|
+
exclude PHASE1_REPORT.md
|
|
51
|
+
exclude PROGRESS_LOG.md
|
|
52
|
+
exclude SESSION_FINAL_SUMMARY.md
|
|
53
|
+
exclude TESTING_ROADMAP.md
|
|
54
|
+
|
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geneweb-py
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Librairie Python complète pour parser, manipuler et convertir les fichiers généalogiques au format GeneWeb (.gw)
|
|
5
|
+
Author-email: Guillaume Cayeux <guillaume.cayeux@relais4x100a2.fr>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Relais4x100a2/prosopo-gw
|
|
8
|
+
Project-URL: Repository, https://github.com/Relais4x100a2/prosopo-gw
|
|
9
|
+
Project-URL: Documentation, https://github.com/Relais4x100a2/prosopo-gw/tree/main/core/doc
|
|
10
|
+
Project-URL: Changelog, https://github.com/Relais4x100a2/prosopo-gw/blob/main/core/CHANGELOG.md
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/Relais4x100a2/prosopo-gw/issues
|
|
12
|
+
Keywords: genealogy,geneweb,parser,gedcom,family-tree
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: Sociology :: Genealogy
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: typing_extensions>=4.0.0
|
|
26
|
+
Requires-Dist: chardet>=5.0.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: hypothesis>=6.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: httpx>=0.24.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pip-audit>=2.6.0; extra == "dev"
|
|
35
|
+
Requires-Dist: click>=8.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: rich>=13.0.0; extra == "dev"
|
|
37
|
+
Provides-Extra: docs
|
|
38
|
+
Requires-Dist: sphinx>=5.0.0; extra == "docs"
|
|
39
|
+
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
|
|
40
|
+
Provides-Extra: cli
|
|
41
|
+
Requires-Dist: click>=8.0.0; extra == "cli"
|
|
42
|
+
Requires-Dist: rich>=13.0.0; extra == "cli"
|
|
43
|
+
Provides-Extra: validation
|
|
44
|
+
Requires-Dist: pydantic>=2.0.0; extra == "validation"
|
|
45
|
+
Provides-Extra: analytics
|
|
46
|
+
Requires-Dist: networkx>=3.0; extra == "analytics"
|
|
47
|
+
Requires-Dist: pyvis>=0.3; extra == "analytics"
|
|
48
|
+
Provides-Extra: api
|
|
49
|
+
Requires-Dist: fastapi>=0.100.0; extra == "api"
|
|
50
|
+
Requires-Dist: uvicorn[standard]>=0.20.0; extra == "api"
|
|
51
|
+
Requires-Dist: pydantic>=2.0.0; extra == "api"
|
|
52
|
+
Requires-Dist: python-multipart>=0.0.5; extra == "api"
|
|
53
|
+
Requires-Dist: slowapi>=0.1.9; extra == "api"
|
|
54
|
+
Requires-Dist: httpx>=0.24.0; extra == "api"
|
|
55
|
+
Provides-Extra: parsing
|
|
56
|
+
Requires-Dist: lark>=1.0.0; extra == "parsing"
|
|
57
|
+
Dynamic: license-file
|
|
58
|
+
|
|
59
|
+
# geneweb-py
|
|
60
|
+
|
|
61
|
+
[](https://github.com/Relais4x100a2/geneweb-py/blob/main/pyproject.toml)
|
|
62
|
+
[](https://pypi.org/project/geneweb-py/)
|
|
63
|
+
[](LICENSE)
|
|
64
|
+
[](https://github.com/Relais4x100a2/prosopo-gw/actions/workflows/ci.yml)
|
|
65
|
+
|
|
66
|
+
Librairie Python complète pour parser, manipuler et convertir les fichiers généalogiques au format GeneWeb (.gw).
|
|
67
|
+
|
|
68
|
+
## 🚀 Fonctionnalités
|
|
69
|
+
|
|
70
|
+
- **Parser complet** : Lecture et parsing des fichiers .gw avec support gwplus ✅
|
|
71
|
+
- **Parser avancé** : Support des apostrophes, caractères spéciaux, numéros d'occurrence ✅
|
|
72
|
+
- **Nouveaux blocs** : Support complet des blocs `notes-db`, `page-ext`, `wizard-note` ✅
|
|
73
|
+
- **Modèles de données** : Représentation structurée des personnes, familles et événements ✅
|
|
74
|
+
- **API REST moderne** : FastAPI avec endpoints complets pour CRUD ✅
|
|
75
|
+
- **Validation** : Vérification de cohérence des données généalogiques ✅
|
|
76
|
+
- **Messages d'erreur enrichis** : Erreurs contextuelles avec numéro de ligne, tokens, et suggestions ✅
|
|
77
|
+
- **Validation gracieuse** : Mode strict/gracieux pour collecter toutes les erreurs ou s'arrêter à la première ✅
|
|
78
|
+
- **Conversion** : Export/import vers GEDCOM, JSON, XML et autres formats ✅
|
|
79
|
+
- **CLI** : commande `geneweb-py` (parse / export) avec l’extra `[cli]` ✅
|
|
80
|
+
- **Performance** : Optimisations avancées (streaming, cache LRU, __slots__) ✅
|
|
81
|
+
- Mode streaming automatique pour gros fichiers (>10MB)
|
|
82
|
+
- Réduction mémoire de ~80% sur fichiers volumineux
|
|
83
|
+
- Optimisations CPU : ~15-20% plus rapide sur petits fichiers
|
|
84
|
+
- Parser **multi-passes** (`use_multipass=True`) pour renforcer la résolution des références croisées sur des bases complexes
|
|
85
|
+
|
|
86
|
+
### Quand utiliser le streaming vs le mode multi-passes ?
|
|
87
|
+
|
|
88
|
+
| Besoin | Réglage recommandé |
|
|
89
|
+
|--------|-------------------|
|
|
90
|
+
| Fichier très volumineux, limiter la **mémoire** (lexique + tokens en flux) | Laisser le seuil par défaut ou forcer `stream_mode=True` sur `GeneWebParser` ; le streaming s’active automatiquement au-delà du seuil (10 Mo par défaut). |
|
|
91
|
+
| Fichier chargé en mémoire (taille modeste à grande) avec **beaucoup de références croisées** (familles, témoins, blocs dispersés) | `GeneWebParser(use_multipass=True)` : une passe supplémentaire met à jour les liens personnes ↔ familles après fusion de toutes les personnes. |
|
|
92
|
+
| Très gros fichier **et** références difficiles | `stream_mode=True` **et** `use_multipass=True` : le pipeline streaming produit les mêmes nœuds syntaxiques, puis la phase multi-passes reconstruit les modèles avec la passe de références renforcée. |
|
|
93
|
+
|
|
94
|
+
Le streaming agit sur la **lecture et la tokenisation** ; le multi-passes agit sur la **construction du graphe généalogique**. Ils ne s’excluent pas.
|
|
95
|
+
|
|
96
|
+
## 📦 Installation
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pip install geneweb-py
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**→ [Démarrage rapide après `pip install`](QUICK_START_PYPI.md)** : parsing, export GEDCOM/JSON, lancement de l’API en quelques minutes.
|
|
103
|
+
|
|
104
|
+
### Ligne de commande (`geneweb-py`)
|
|
105
|
+
|
|
106
|
+
Avec l’extra **`cli`** (Click + Rich) :
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pip install "geneweb-py[cli]"
|
|
110
|
+
geneweb-py --help
|
|
111
|
+
geneweb-py parse ma_base.gw
|
|
112
|
+
geneweb-py export ma_base.gw --format gedcom -o sortie.ged
|
|
113
|
+
geneweb-py export ma_base.gw --format json -o sortie.json
|
|
114
|
+
geneweb-py export ma_base.gw --format xml -o sortie.xml
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Les erreurs de parsing ou d’export sont affichées sur la sortie d’erreur avec des panneaux Rich.
|
|
118
|
+
|
|
119
|
+
Pour le développement :
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install geneweb-py[dev]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Extras disponibles (voir `[project.optional-dependencies]` dans `pyproject.toml`) : `dev`, `docs`, `cli`, `validation`, `api`. L’extra optionnel **`parsing`** installe [Lark](https://github.com/lark-parser/lark) pour d’éventuels travaux sur une grammaire déclarative ; **le parser GeneWeb actuel n’en dépend pas** — réservé à un usage expérimental ou futur (non requis pour parser des fichiers `.gw`).
|
|
126
|
+
|
|
127
|
+
## 🎯 Utilisation rapide
|
|
128
|
+
|
|
129
|
+
### Parser un fichier .gw
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from geneweb_py import GeneWebParser
|
|
133
|
+
|
|
134
|
+
# Créer le parser
|
|
135
|
+
parser = GeneWebParser()
|
|
136
|
+
|
|
137
|
+
# Parser un fichier
|
|
138
|
+
genealogy = parser.parse_file("ma_famille.gw")
|
|
139
|
+
|
|
140
|
+
# Afficher des statistiques
|
|
141
|
+
print(f"Nombre de personnes : {len(genealogy.persons)}")
|
|
142
|
+
print(f"Nombre de familles : {len(genealogy.families)}")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### API REST avec FastAPI
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
# Démarrer l'API
|
|
149
|
+
from geneweb_py.api import app
|
|
150
|
+
import uvicorn
|
|
151
|
+
|
|
152
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
153
|
+
|
|
154
|
+
# L'API sera disponible sur http://localhost:8000/docs
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**CORS (déploiement)** : définir `GENEWEB_API_ENV=prod` (ou lancer `python run_api.py --env prod`, qui positionne cette variable avant le chargement de l’app) et lister les origines autorisées dans `ALLOWED_ORIGINS` (URLs séparées par des virgules, ex. `https://app.example.com,https://admin.example.com`). En production, tant que ni `ALLOWED_ORIGINS` ni `CORS_ORIGINS` ne sont définies, aucune origine cross-origin n’est autorisée par défaut. La variable `CORS_ORIGINS` reste prise en charge pour compatibilité, mais `ALLOWED_ORIGINS` est prioritaire.
|
|
158
|
+
|
|
159
|
+
### Rechercher une personne
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# Rechercher par nom
|
|
163
|
+
person = genealogy.find_person("CORNO", "Joseph")
|
|
164
|
+
|
|
165
|
+
if person:
|
|
166
|
+
print(f"Nom : {person.full_name}")
|
|
167
|
+
print(f"Naissance : {person.birth_date}")
|
|
168
|
+
print(f"Décès : {person.death_date}")
|
|
169
|
+
|
|
170
|
+
# Obtenir les familles
|
|
171
|
+
families = person.get_families()
|
|
172
|
+
for family in families:
|
|
173
|
+
print(f"Époux(se) : {family.spouse(person)}")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Utiliser l'API REST
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
# Via l'API REST
|
|
180
|
+
import requests
|
|
181
|
+
|
|
182
|
+
# Lister les personnes
|
|
183
|
+
response = requests.get("http://localhost:8000/api/v1/persons")
|
|
184
|
+
print(f"Personnes : {response.json()}")
|
|
185
|
+
|
|
186
|
+
# Obtenir une personne
|
|
187
|
+
person = requests.get("http://localhost:8000/api/v1/persons/1")
|
|
188
|
+
print(f"Personne : {person.json()}")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Nouvelles fonctionnalités du parser
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
# Démontrer les améliorations récentes
|
|
195
|
+
python examples/parser_improvements_demo.py
|
|
196
|
+
|
|
197
|
+
# Exemple de parsing avec apostrophes et caractères spéciaux
|
|
198
|
+
content = """
|
|
199
|
+
fam d'Arc Jean-Marie .1 #occu Ingénieur_(ENSIA),_Aumônier_de_l'enseignement + O'Brien Marie-Claire .2
|
|
200
|
+
wit m: LEROY Bernard .1 #occu Dominicain,_Aumônier_de_l'enseignement_technique_à_Rouen
|
|
201
|
+
beg
|
|
202
|
+
- h Pierre_Bernard .1 #occu Ingénieur,_éditeur
|
|
203
|
+
- f Marie_Claire .2 #occu Conseillère_en_économie_sociale_et_familiale
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
notes-db
|
|
207
|
+
Notes générales sur cette famille
|
|
208
|
+
end notes-db
|
|
209
|
+
|
|
210
|
+
page-ext d'Arc Jean-Marie .1
|
|
211
|
+
<h1>Page de Jean-Marie d'Arc</h1>
|
|
212
|
+
end page-ext
|
|
213
|
+
|
|
214
|
+
wizard-note O'Brien Marie-Claire .2
|
|
215
|
+
Note générée par le wizard pour Marie-Claire
|
|
216
|
+
end wizard-note
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
parser = GeneWebParser()
|
|
220
|
+
genealogy = parser.parse_string(content)
|
|
221
|
+
|
|
222
|
+
# Toutes les personnes sont correctement parsées avec leurs occupations
|
|
223
|
+
for person in genealogy.persons.values():
|
|
224
|
+
print(f"{person.first_name} {person.last_name} - {person.occupation}")
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Validation gracieuse et gestion d'erreurs
|
|
228
|
+
|
|
229
|
+
Le parser supporte deux modes de gestion d'erreurs :
|
|
230
|
+
|
|
231
|
+
#### Mode strict (par défaut) - S'arrête à la première erreur
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
from geneweb_py import GeneWebParser
|
|
235
|
+
|
|
236
|
+
parser = GeneWebParser(strict=True) # Mode par défaut
|
|
237
|
+
try:
|
|
238
|
+
genealogy = parser.parse_file("fichier_avec_erreur.gw")
|
|
239
|
+
except GeneWebParseError as e:
|
|
240
|
+
print(f"Erreur de parsing : {e}")
|
|
241
|
+
# Message enrichi avec ligne, token attendu, contexte
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### Mode gracieux - Collecte toutes les erreurs
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
from geneweb_py import GeneWebParser
|
|
248
|
+
|
|
249
|
+
# Mode gracieux : continue le parsing malgré les erreurs
|
|
250
|
+
parser = GeneWebParser(strict=False, validate=True)
|
|
251
|
+
genealogy = parser.parse_file("fichier_avec_erreurs.gw")
|
|
252
|
+
|
|
253
|
+
# Vérifier si la généalogie est valide
|
|
254
|
+
if not genealogy.is_valid:
|
|
255
|
+
print(f"Erreurs détectées : {len(genealogy.validation_errors)}")
|
|
256
|
+
|
|
257
|
+
# Obtenir un résumé
|
|
258
|
+
print(genealogy.get_validation_summary())
|
|
259
|
+
|
|
260
|
+
# Afficher toutes les erreurs
|
|
261
|
+
for error in genealogy.validation_errors:
|
|
262
|
+
print(f"- {error}") # Messages enrichis avec contexte
|
|
263
|
+
|
|
264
|
+
# Rapport détaillé des erreurs
|
|
265
|
+
if parser.error_collector.has_errors():
|
|
266
|
+
print(parser.error_collector.get_detailed_report())
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Messages d'erreur enrichis
|
|
270
|
+
|
|
271
|
+
Les erreurs incluent automatiquement :
|
|
272
|
+
- Numéro de ligne
|
|
273
|
+
- Token trouvé vs token attendu
|
|
274
|
+
- Contexte (quelle personne, famille, etc.)
|
|
275
|
+
- Sévérité (WARNING, ERROR, CRITICAL)
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
# Exemple de message d'erreur enrichi :
|
|
279
|
+
# Ligne 42: Token inattendu
|
|
280
|
+
# Token trouvé: 'invalid'
|
|
281
|
+
# Attendu: fam, nom, ou date
|
|
282
|
+
# Contexte: Parsing d'une personne
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Validation des données
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from geneweb_py.core.validation import (
|
|
289
|
+
validate_person_basic,
|
|
290
|
+
validate_family_basic,
|
|
291
|
+
validate_genealogy_consistency
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
# Valider une personne
|
|
295
|
+
result = validate_person_basic(person)
|
|
296
|
+
if not result.is_valid():
|
|
297
|
+
print(f"Erreurs : {result.get_error_messages()}")
|
|
298
|
+
print(f"Avertissements : {result.get_warning_messages()}")
|
|
299
|
+
|
|
300
|
+
# Valider toute la généalogie
|
|
301
|
+
result = validate_genealogy_consistency(genealogy)
|
|
302
|
+
print(result.get_summary()) # Résumé des erreurs et avertissements
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Conversion de formats
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
from geneweb_py.formats import GEDCOMExporter, JSONExporter, XMLExporter
|
|
309
|
+
|
|
310
|
+
# Export vers GEDCOM
|
|
311
|
+
gedcom_exporter = GEDCOMExporter()
|
|
312
|
+
gedcom_exporter.export(genealogy, "ma_famille.ged")
|
|
313
|
+
|
|
314
|
+
# Export vers JSON
|
|
315
|
+
json_exporter = JSONExporter()
|
|
316
|
+
json_exporter.export(genealogy, "ma_famille.json")
|
|
317
|
+
|
|
318
|
+
# Export vers XML
|
|
319
|
+
xml_exporter = XMLExporter()
|
|
320
|
+
xml_exporter.export(genealogy, "ma_famille.xml")
|
|
321
|
+
|
|
322
|
+
# Import depuis JSON
|
|
323
|
+
from geneweb_py.formats import JSONImporter
|
|
324
|
+
json_importer = JSONImporter()
|
|
325
|
+
imported_genealogy = json_importer.import_from_file("ma_famille.json")
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## ⚡ Optimisations de performance
|
|
329
|
+
|
|
330
|
+
geneweb-py inclut des optimisations avancées pour gérer efficacement les fichiers volumineux :
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
from geneweb_py.core.parser.gw_parser import GeneWebParser
|
|
334
|
+
|
|
335
|
+
# Mode automatique : détecte la taille et choisit le meilleur mode
|
|
336
|
+
parser = GeneWebParser()
|
|
337
|
+
genealogy = parser.parse_file("gros_fichier.gw") # Streaming si >10MB
|
|
338
|
+
|
|
339
|
+
# Estimer l'utilisation mémoire avant parsing
|
|
340
|
+
estimate = parser.get_memory_estimate("gros_fichier.gw")
|
|
341
|
+
print(f"Mémoire estimée : {estimate['estimated_streaming_memory_mb']} MB")
|
|
342
|
+
print(f"Économie : {estimate['memory_saving_percent']}%")
|
|
343
|
+
|
|
344
|
+
# Mode streaming forcé pour économiser la mémoire
|
|
345
|
+
parser = GeneWebParser(stream_mode=True)
|
|
346
|
+
|
|
347
|
+
# Désactiver la validation pour plus de vitesse
|
|
348
|
+
parser = GeneWebParser(validate=False)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Gains mesurés** :
|
|
352
|
+
- Fichiers >10MB : ~80% de réduction mémoire avec le streaming
|
|
353
|
+
- Petits fichiers : ~15-20% plus rapide grâce aux optimisations CPU
|
|
354
|
+
- Exemple : fichier 50MB passe de ~375MB RAM à ~75MB RAM
|
|
355
|
+
|
|
356
|
+
**Voir aussi** :
|
|
357
|
+
- [Guide complet des performances](doc/PERFORMANCE.md)
|
|
358
|
+
- [Exemple de démonstration](examples/performance_demo.py)
|
|
359
|
+
- [Benchmarks](tests/performance/benchmark_parser.py)
|
|
360
|
+
|
|
361
|
+
## 📚 Documentation
|
|
362
|
+
|
|
363
|
+
**→ [Guide complet de la documentation](DOCUMENTATION.md)** - Index central et parcours recommandés
|
|
364
|
+
|
|
365
|
+
### Essentiel
|
|
366
|
+
- **[README.md](README.md)** - 👈 Vous êtes ici - Guide d'utilisation
|
|
367
|
+
- **[CHANGELOG.md](CHANGELOG.md)** - Historique des versions
|
|
368
|
+
- **[doc/status.md](doc/status.md)** - État du projet et métriques
|
|
369
|
+
- **[doc/roadmap.md](doc/roadmap.md)** - Vision à long terme
|
|
370
|
+
|
|
371
|
+
### Guides spécialisés
|
|
372
|
+
- **[doc/PERFORMANCE.md](doc/PERFORMANCE.md)** ⚡ - Optimisations et benchmarks
|
|
373
|
+
- **[QUICK_START_PYPI.md](QUICK_START_PYPI.md)** 📦 - Démarrage rapide (install PyPI)
|
|
374
|
+
- **[doc/geneweb/gw_format_documentation.md](doc/geneweb/gw_format_documentation.md)** - Format .gw
|
|
375
|
+
|
|
376
|
+
### Ressources
|
|
377
|
+
- **[examples/](examples/)** - Scripts de démonstration
|
|
378
|
+
- **[tests/](tests/)** - Suite de tests (volume à jour dans [doc/status.md](doc/status.md))
|
|
379
|
+
- **[Documentation API](http://localhost:8000/docs)** - Swagger UI (API REST)
|
|
380
|
+
- **[GeneWeb Community](https://web.archive.org/web/20250802144922/https://geneweb.tuxfamily.org/wiki/GeneWeb)** - Documentation communautaire
|
|
381
|
+
|
|
382
|
+
## 🧪 Tests
|
|
383
|
+
|
|
384
|
+
geneweb-py dispose d'une suite de tests **consolidée et organisée**. Les comptages exacts et l’instantané de couverture documenté sont tenus à jour dans **[doc/status.md](doc/status.md)** ; la tendance sur `main` est visible sur **[Codecov](https://codecov.io/gh/Relais4x100a2/geneweb-py)** (CI). En local : `python3 -m pytest tests/ --cov=src/geneweb_py` (extras `dev`, `api`, `validation`).
|
|
385
|
+
|
|
386
|
+
### 📁 Structure des Tests
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
tests/
|
|
390
|
+
├── unit/ # Tests unitaires par module (18 fichiers)
|
|
391
|
+
│ ├── test_date.py # Tests pour core.date
|
|
392
|
+
│ ├── test_event.py # Tests pour core.event
|
|
393
|
+
│ ├── test_person.py # Tests pour core.person
|
|
394
|
+
│ ├── test_family.py # Tests pour core.family
|
|
395
|
+
│ ├── test_exceptions.py # Tests pour core.exceptions
|
|
396
|
+
│ ├── test_validation.py # Tests pour core.validation
|
|
397
|
+
│ ├── test_parser*.py # Tests pour core.parser
|
|
398
|
+
│ └── test_formats*.py # Tests pour formats.*
|
|
399
|
+
├── integration/ # Tests d'intégration
|
|
400
|
+
├── compatibility/ # Tests de compatibilité Python
|
|
401
|
+
├── packaging/ # Tests de packaging PyPI
|
|
402
|
+
└── security/ # Tests de sécurité
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### 🚀 Exécution des Tests
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
# Exécuter tous les tests
|
|
409
|
+
pytest
|
|
410
|
+
|
|
411
|
+
# Tests unitaires seulement (recommandé pour le développement)
|
|
412
|
+
pytest tests/unit/
|
|
413
|
+
|
|
414
|
+
# Tests avec couverture
|
|
415
|
+
pytest --cov=geneweb_py --cov-report=html
|
|
416
|
+
|
|
417
|
+
# Tests sans les tests lents
|
|
418
|
+
pytest -m "not slow"
|
|
419
|
+
|
|
420
|
+
# Tests d'intégration seulement
|
|
421
|
+
pytest tests/integration/
|
|
422
|
+
|
|
423
|
+
# Tests de packaging (PyPI)
|
|
424
|
+
pytest tests/packaging/
|
|
425
|
+
|
|
426
|
+
# Tests de compatibilité multi-versions
|
|
427
|
+
pytest tests/compatibility/
|
|
428
|
+
|
|
429
|
+
# Tests de sécurité
|
|
430
|
+
pytest tests/security/
|
|
431
|
+
|
|
432
|
+
# Voir les tests skippés et leurs raisons
|
|
433
|
+
pytest -rs
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### 📊 Métriques de Qualité
|
|
437
|
+
|
|
438
|
+
- **Tests et couverture** : voir **[doc/status.md](doc/status.md)** (instantané versionné) et le badge **Codecov** en tête de ce README.
|
|
439
|
+
- **Modules critiques** : parser, validation et exceptions sont en majorité très couverts ; le détail par fichier est dans le rapport `htmlcov/` après `pytest --cov`.
|
|
440
|
+
- **Temps d'exécution** : de l’ordre de quelques secondes pour la suite complète sur machine récente
|
|
441
|
+
|
|
442
|
+
### 🔧 Configuration des Tests
|
|
443
|
+
|
|
444
|
+
Les tests sont configurés dans `pyproject.toml` avec :
|
|
445
|
+
- **Couverture minimale** : 80%
|
|
446
|
+
- **Marqueurs** : `slow`, `integration`, `unit`, `coverage`, `parser`, `validation`, `formats`
|
|
447
|
+
- **Filtres d'avertissements** : Déprecations ignorées
|
|
448
|
+
- **Traceback court** : Pour des rapports concis
|
|
449
|
+
|
|
450
|
+
### 📝 Documentation des Tests
|
|
451
|
+
|
|
452
|
+
- **[Structure des tests](tests/README.md)** : Organisation et bonnes pratiques
|
|
453
|
+
- **[Tests skippés](tests/SKIPPED_TESTS.md)** : Documentation des tests temporairement désactivés
|
|
454
|
+
- **Couverture** : Rapport HTML généré dans `htmlcov/`
|
|
455
|
+
|
|
456
|
+
## 🚀 Développement et Publication
|
|
457
|
+
|
|
458
|
+
### Installation en mode développement
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
git clone https://github.com/Relais4x100a2/geneweb-py.git
|
|
462
|
+
cd geneweb-py
|
|
463
|
+
pip install -e .[dev]
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Validation avant publication PyPI
|
|
467
|
+
|
|
468
|
+
geneweb-py inclut des scripts de validation pour garantir la qualité avant publication :
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# Validation complète (bash)
|
|
472
|
+
./scripts/validate_pypi.sh
|
|
473
|
+
|
|
474
|
+
# Vérification avancée (Python)
|
|
475
|
+
python scripts/check_pypi_readiness.py
|
|
476
|
+
|
|
477
|
+
# Construction du package
|
|
478
|
+
python -m build
|
|
479
|
+
|
|
480
|
+
# Vérification avec twine
|
|
481
|
+
twine check dist/*
|
|
482
|
+
|
|
483
|
+
# Tests de packaging
|
|
484
|
+
pytest tests/packaging/ -v
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Publication sur PyPI
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
# 1. Publication sur TestPyPI (pour tester)
|
|
491
|
+
twine upload --repository testpypi dist/*
|
|
492
|
+
|
|
493
|
+
# 2. Test d'installation depuis TestPyPI
|
|
494
|
+
pip install --index-url https://test.pypi.org/simple/ geneweb-py
|
|
495
|
+
|
|
496
|
+
# 3. Publication sur PyPI (production)
|
|
497
|
+
twine upload dist/*
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Note** : La publication est automatisée via GitHub Actions. Voir `.github/workflows/test-pypi.yml`
|
|
501
|
+
|
|
502
|
+
### Compatibilité
|
|
503
|
+
|
|
504
|
+
geneweb-py est testé et compatible avec :
|
|
505
|
+
- **Python** : 3.8, 3.9, 3.10, 3.11, 3.12 (voir `requires-python` dans `pyproject.toml`)
|
|
506
|
+
- **OS** : Linux, macOS, Windows
|
|
507
|
+
- **Architectures** : x86_64, arm64
|
|
508
|
+
|
|
509
|
+
## 🤝 Contribution
|
|
510
|
+
|
|
511
|
+
Les contributions sont les bienvenues ! Consultez le [Statut du projet](doc/status.md) et la [Roadmap](doc/roadmap.md) pour comprendre la direction actuelle et proposer des améliorations.
|
|
512
|
+
|
|
513
|
+
### Processus de contribution
|
|
514
|
+
|
|
515
|
+
1. Fork le projet
|
|
516
|
+
2. Créer une branche (`git checkout -b feature/AmazingFeature`)
|
|
517
|
+
3. Commit les changements (`git commit -m 'Add AmazingFeature'`)
|
|
518
|
+
4. Push vers la branche (`git push origin feature/AmazingFeature`)
|
|
519
|
+
5. Ouvrir une Pull Request
|
|
520
|
+
|
|
521
|
+
### Standards de qualité
|
|
522
|
+
|
|
523
|
+
Le projet n’utilise **ni Black ni Flake8** : le formatage, le lint et le tri des imports sont assurés par **Ruff** (`ruff format`, `ruff check`, configuration dans `[tool.ruff]` de `pyproject.toml`), en remplacement de l’écosystème Black + Flake8 + isort.
|
|
524
|
+
|
|
525
|
+
- Tests unitaires obligatoires (couverture ≥ 90% sur les modules critiques)
|
|
526
|
+
- Annotations de type sur toutes les fonctions publiques
|
|
527
|
+
- Docstrings en français (style Google)
|
|
528
|
+
- **Ruff** pour le formatage et le lint — aligné sur `pyproject.toml` ; commandes locales : `ruff format .` puis `ruff check .`
|
|
529
|
+
- Vérification des types avec **mypy** (mode strict)
|
|
530
|
+
- **Sécurité des dépendances** : le workflow [.github/workflows/security.yml](.github/workflows/security.yml) exécute **pip-audit** sur les extras `api`, `validation` et `parsing` (cœur + optionnels « runtime » documentés) à chaque PR et chaque semaine ; pour un contrôle local, installer l’extra `dev` puis lancer `pip-audit` selon vos besoins
|
|
531
|
+
|
|
532
|
+
## 📄 Licence
|
|
533
|
+
|
|
534
|
+
Ce projet est sous licence MIT. Voir [LICENSE](LICENSE) pour plus de détails.
|
|
535
|
+
|
|
536
|
+
## 🔗 Liens utiles
|
|
537
|
+
|
|
538
|
+
- [GeneWeb GitHub repo](http://geneweb.org/)
|
|
539
|
+
- [Format .gw](doc/geneweb/gw_format_documentation.md)
|
|
540
|
+
- [Geneweb documentation by the community](https://web.archive.org/web/20250802144922/https://geneweb.tuxfamily.org/wiki/GeneWeb)
|
|
541
|
+
- [Issues](https://github.com/Relais4x100a2/geneweb-py/issues)
|