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.
Files changed (119) hide show
  1. geneweb_py-0.1.0/CHANGELOG.md +73 -0
  2. geneweb_py-0.1.0/LICENSE +21 -0
  3. geneweb_py-0.1.0/MANIFEST.in +54 -0
  4. geneweb_py-0.1.0/PKG-INFO +541 -0
  5. geneweb_py-0.1.0/README.md +483 -0
  6. geneweb_py-0.1.0/doc/ARCHITECTURE_MULTIPASS.md +219 -0
  7. geneweb_py-0.1.0/doc/MIGRATION_STRUCTURE_SRC.md +147 -0
  8. geneweb_py-0.1.0/doc/PERFORMANCE.md +299 -0
  9. geneweb_py-0.1.0/doc/PYPI_PUBLICATION_GUIDE.md +362 -0
  10. geneweb_py-0.1.0/doc/PYPI_TESTING_STRATEGY.md +783 -0
  11. geneweb_py-0.1.0/doc/exports_design.md +243 -0
  12. geneweb_py-0.1.0/doc/exports_plan.md +261 -0
  13. geneweb_py-0.1.0/doc/exports_plan_step2.md +155 -0
  14. geneweb_py-0.1.0/doc/exports_plan_step3.md +259 -0
  15. geneweb_py-0.1.0/doc/features/data_cleaning.md +530 -0
  16. geneweb_py-0.1.0/doc/features/obsidian.md +303 -0
  17. geneweb_py-0.1.0/doc/geneweb/gw_format_documentation.md +404 -0
  18. geneweb_py-0.1.0/doc/organizations_candidates_design.md +486 -0
  19. geneweb_py-0.1.0/doc/organizations_candidates_plan.md +641 -0
  20. geneweb_py-0.1.0/doc/parser_fidelity_audit.md +566 -0
  21. geneweb_py-0.1.0/doc/parser_finalisation_design.md +391 -0
  22. geneweb_py-0.1.0/doc/roadmap.md +28 -0
  23. geneweb_py-0.1.0/doc/shared_experiences_design.md +411 -0
  24. geneweb_py-0.1.0/doc/status.md +252 -0
  25. geneweb_py-0.1.0/examples/api_usage.py +204 -0
  26. geneweb_py-0.1.0/examples/basic_usage.py +165 -0
  27. geneweb_py-0.1.0/examples/conversion_usage.py +256 -0
  28. geneweb_py-0.1.0/examples/data_manipulation.py +194 -0
  29. geneweb_py-0.1.0/examples/parser_improvements_demo.py +117 -0
  30. geneweb_py-0.1.0/examples/parser_usage.py +158 -0
  31. geneweb_py-0.1.0/examples/performance_demo.py +270 -0
  32. geneweb_py-0.1.0/pyproject.toml +213 -0
  33. geneweb_py-0.1.0/setup.cfg +4 -0
  34. geneweb_py-0.1.0/src/geneweb_py/__init__.py +23 -0
  35. geneweb_py-0.1.0/src/geneweb_py/analytics/__init__.py +5 -0
  36. geneweb_py-0.1.0/src/geneweb_py/analytics/network.py +261 -0
  37. geneweb_py-0.1.0/src/geneweb_py/api/__init__.py +11 -0
  38. geneweb_py-0.1.0/src/geneweb_py/api/dependencies.py +75 -0
  39. geneweb_py-0.1.0/src/geneweb_py/api/family_payload.py +64 -0
  40. geneweb_py-0.1.0/src/geneweb_py/api/limits.py +87 -0
  41. geneweb_py-0.1.0/src/geneweb_py/api/main.py +222 -0
  42. geneweb_py-0.1.0/src/geneweb_py/api/middleware/__init__.py +3 -0
  43. geneweb_py-0.1.0/src/geneweb_py/api/middleware/error_handler.py +153 -0
  44. geneweb_py-0.1.0/src/geneweb_py/api/middleware/logging.py +100 -0
  45. geneweb_py-0.1.0/src/geneweb_py/api/models/__init__.py +3 -0
  46. geneweb_py-0.1.0/src/geneweb_py/api/models/event.py +192 -0
  47. geneweb_py-0.1.0/src/geneweb_py/api/models/family.py +178 -0
  48. geneweb_py-0.1.0/src/geneweb_py/api/models/organization.py +154 -0
  49. geneweb_py-0.1.0/src/geneweb_py/api/models/person.py +311 -0
  50. geneweb_py-0.1.0/src/geneweb_py/api/models/responses.py +122 -0
  51. geneweb_py-0.1.0/src/geneweb_py/api/person_payload.py +67 -0
  52. geneweb_py-0.1.0/src/geneweb_py/api/rate_limit.py +22 -0
  53. geneweb_py-0.1.0/src/geneweb_py/api/router_helpers.py +32 -0
  54. geneweb_py-0.1.0/src/geneweb_py/api/routers/__init__.py +8 -0
  55. geneweb_py-0.1.0/src/geneweb_py/api/routers/events.py +503 -0
  56. geneweb_py-0.1.0/src/geneweb_py/api/routers/families.py +374 -0
  57. geneweb_py-0.1.0/src/geneweb_py/api/routers/genealogy.py +515 -0
  58. geneweb_py-0.1.0/src/geneweb_py/api/routers/organizations.py +150 -0
  59. geneweb_py-0.1.0/src/geneweb_py/api/routers/persons.py +431 -0
  60. geneweb_py-0.1.0/src/geneweb_py/api/routers/sessions.py +133 -0
  61. geneweb_py-0.1.0/src/geneweb_py/api/serialization.py +344 -0
  62. geneweb_py-0.1.0/src/geneweb_py/api/services/__init__.py +3 -0
  63. geneweb_py-0.1.0/src/geneweb_py/api/services/export_bundle.py +30 -0
  64. geneweb_py-0.1.0/src/geneweb_py/api/services/genealogy_service.py +1552 -0
  65. geneweb_py-0.1.0/src/geneweb_py/api/services/organization_candidates.py +445 -0
  66. geneweb_py-0.1.0/src/geneweb_py/api/services/organization_exports.py +223 -0
  67. geneweb_py-0.1.0/src/geneweb_py/api/services/organization_tables.py +253 -0
  68. geneweb_py-0.1.0/src/geneweb_py/api/session_store.py +132 -0
  69. geneweb_py-0.1.0/src/geneweb_py/api/static/app.js +2393 -0
  70. geneweb_py-0.1.0/src/geneweb_py/api/static/index.html +273 -0
  71. geneweb_py-0.1.0/src/geneweb_py/api/static/style.css +860 -0
  72. geneweb_py-0.1.0/src/geneweb_py/api/static/toldot-logo.png +0 -0
  73. geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/bootstrap.bundle.min.js +7 -0
  74. geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/bootstrap.min.css +6 -0
  75. geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/tabulator.min.css +2 -0
  76. geneweb_py-0.1.0/src/geneweb_py/api/static/vendor/tabulator.min.js +3 -0
  77. geneweb_py-0.1.0/src/geneweb_py/cli/__init__.py +9 -0
  78. geneweb_py-0.1.0/src/geneweb_py/cli/commands.py +196 -0
  79. geneweb_py-0.1.0/src/geneweb_py/cli/entry.py +15 -0
  80. geneweb_py-0.1.0/src/geneweb_py/core/__init__.py +9 -0
  81. geneweb_py-0.1.0/src/geneweb_py/core/date.py +620 -0
  82. geneweb_py-0.1.0/src/geneweb_py/core/event.py +265 -0
  83. geneweb_py-0.1.0/src/geneweb_py/core/event_to_organization.py +1099 -0
  84. geneweb_py-0.1.0/src/geneweb_py/core/exceptions.py +648 -0
  85. geneweb_py-0.1.0/src/geneweb_py/core/family.py +399 -0
  86. geneweb_py-0.1.0/src/geneweb_py/core/genealogy.py +697 -0
  87. geneweb_py-0.1.0/src/geneweb_py/core/models.py +42 -0
  88. geneweb_py-0.1.0/src/geneweb_py/core/note_leads.py +191 -0
  89. geneweb_py-0.1.0/src/geneweb_py/core/organization.py +209 -0
  90. geneweb_py-0.1.0/src/geneweb_py/core/parser/__init__.py +39 -0
  91. geneweb_py-0.1.0/src/geneweb_py/core/parser/gw_parser.py +3780 -0
  92. geneweb_py-0.1.0/src/geneweb_py/core/parser/lexical.py +825 -0
  93. geneweb_py-0.1.0/src/geneweb_py/core/parser/multipass_parser.py +65 -0
  94. geneweb_py-0.1.0/src/geneweb_py/core/parser/place_tokens.py +173 -0
  95. geneweb_py-0.1.0/src/geneweb_py/core/parser/reconcile.py +359 -0
  96. geneweb_py-0.1.0/src/geneweb_py/core/parser/streaming.py +326 -0
  97. geneweb_py-0.1.0/src/geneweb_py/core/parser/syntax.py +1668 -0
  98. geneweb_py-0.1.0/src/geneweb_py/core/parser/wikitext.py +144 -0
  99. geneweb_py-0.1.0/src/geneweb_py/core/parser/words.py +167 -0
  100. geneweb_py-0.1.0/src/geneweb_py/core/person.py +365 -0
  101. geneweb_py-0.1.0/src/geneweb_py/core/place.py +69 -0
  102. geneweb_py-0.1.0/src/geneweb_py/core/shared_experiences.py +548 -0
  103. geneweb_py-0.1.0/src/geneweb_py/core/validation.py +449 -0
  104. geneweb_py-0.1.0/src/geneweb_py/formats/__init__.py +39 -0
  105. geneweb_py-0.1.0/src/geneweb_py/formats/base.py +156 -0
  106. geneweb_py-0.1.0/src/geneweb_py/formats/gedcom.py +1234 -0
  107. geneweb_py-0.1.0/src/geneweb_py/formats/json.py +429 -0
  108. geneweb_py-0.1.0/src/geneweb_py/formats/leads_table.py +158 -0
  109. geneweb_py-0.1.0/src/geneweb_py/formats/org_sidecar.py +103 -0
  110. geneweb_py-0.1.0/src/geneweb_py/formats/table_writers.py +229 -0
  111. geneweb_py-0.1.0/src/geneweb_py/formats/tables.py +389 -0
  112. geneweb_py-0.1.0/src/geneweb_py/formats/xml.py +808 -0
  113. geneweb_py-0.1.0/src/geneweb_py/py.typed +0 -0
  114. geneweb_py-0.1.0/src/geneweb_py.egg-info/PKG-INFO +541 -0
  115. geneweb_py-0.1.0/src/geneweb_py.egg-info/SOURCES.txt +117 -0
  116. geneweb_py-0.1.0/src/geneweb_py.egg-info/dependency_links.txt +1 -0
  117. geneweb_py-0.1.0/src/geneweb_py.egg-info/entry_points.txt +2 -0
  118. geneweb_py-0.1.0/src/geneweb_py.egg-info/requires.txt +39 -0
  119. 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
@@ -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
+ [![Python](https://img.shields.io/pypi/pyversions/geneweb-py?logo=python&label=Python&color=blue)](https://github.com/Relais4x100a2/geneweb-py/blob/main/pyproject.toml)
62
+ [![PyPI version](https://img.shields.io/badge/pypi-v0.1.0-blue.svg)](https://pypi.org/project/geneweb-py/)
63
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
64
+ [![CI](https://github.com/Relais4x100a2/prosopo-gw/actions/workflows/ci.yml/badge.svg)](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)