Notes de version¶
0.1.0¶
La première version de ddi-l : une boîte à outils Python pour créer, lire,
mettre à jour et valider des documents XML
DDI Lifecycle 3.3,
avec une API CRUD simple posée sur une couche de modèles générée depuis les XSD.
Rédaction¶
- API CRUD simple :
ddi.new_study(),ddi.open_ddi()et la classeDocumentavecadd_question(),add_variable(),add_concept(),add_universe(),add_code_list(),add_item(),find(),remove(),save()etvalidate(). Chaque méthodeadd_*accepte unlabel=optionnel (etlabel_lang=), de sorte qu'un objet peut être libellé là où il est créé plutôt qu'en seconde passe. C'est la différence entre une sortie qui passe le lint sans rien signaler et une sortie qui se signale elle-même. add_item()/items()génériques : 30 types d'éléments DDI (QuestionItem, Variable, Category, Instrument, Concept, Universe, et d'autres) via un registre de types unique.- Représentations de variables :
Variable.set_numeric(),set_coded(),set_text()etset_datetime()déclarent le type de valeurs que porte une variable, avec des plages numériques optionnelles (low_inclusive/high_inclusive),missing_values,blank_is_missing_value, ou une référence vers une liste de codes. Ces setters s'enchaînent suradd_variable(). - Propriétés personnalisées :
set_property(),get_property(),propertiesetremove_property()sur tout élément DDI. - Versionnement :
increment_major_version(),increment_minor_version(),increment_subversion(), justifications de version et responsabilité de version. - Support multilingue : un paramètre
lang=sur toutes les méthodesadd_*, etInternationalStringpour les traductions supplémentaires.
Structure d'étude¶
- Séries multi-études :
doc.add_study()ajoute d'autres études au groupe.doc.study(identifier)renvoie unStudyCursordontadd_variable(),add_question()et les autres helpersadd_*ciblent cette étude précise : les études non primaires sont donc éditables via l'API de haut niveau.doc.study()sans argument cible l'étude primaire. - Groupes d'études :
doc.add_group()organise une étude dans un<g:Group>(une série d'études ou un lot de publication). Le document reste pleinement éditable, et les fichiers organisés en groupe s'ouvrent et font l'aller-retour. - Paquets au niveau instance :
doc.add_resource_package()etdoc.add_local_holding_package()attachent unResourcePackage(métadonnées réutilisables) ou unLocalHoldingPackage(une détention locale d'une étude déposée, référençant l'étude primaire par défaut) directement sur laDDIInstance;doc.resource_packages/doc.local_holding_packagesles relisent. - Archive :
doc.add_archive()attache un moduleArchive(métadonnées de cycle de vie d'archive) à l'étude primaire ;doc.archivesles relit. - Informations de traduction :
doc.add_translation_information(languages=..., description=...)définit laTranslationInformationde l'instance ;doc.translation_informationla relit. - Comparaisons :
doc.add_comparison()enregistre des cartes d'harmonisation entre éléments, d'une étude ou d'une version à l'autre :add_variable_map(),add_concept_map(),add_managed_item_map(),add_representation_map(), un constructeurcorrespondence(), et les argumentssource_scheme/target_scheme/correspondencesur les helpers de carte. - Profils DDI :
doc.add_ddi_profile()attache unDDIProfiledéclarant quels éléments DDI un système utilise, via des énoncés XPathadd_used()/add_not_used().
Description des données¶
- Relations de données :
doc.add_data_relationship()construit uneDataRelationshipdontadd_logical_record()déclare quelles variables composent un cas (le défaut rectangulaire). - NCubes :
doc.add_ncube()construit un cube multidimensionnel ;add_dimension(variable_ref)ajoute un axe,add_measure(variable_ref)ajoute une valeur mesurée etadd_attribute()ajoute une variable qualifiante.add_coordinate_region()etadd_dimension_value()décrivent une région du cube, etadd_attribute(..., attachment_region=)s'y attache. - Instances physiques :
PhysicalInstanceest un typeadd_itemde premier ordre au niveau de l'étude, décrivant un fichier de données concret avecset_data_file(),set_record_count()etset_citation_title(). - Dispositions d'enregistrement :
doc.add_record_layout()associe les variables à des positions dans un fichier de données viaadd_data_item(variable_ref, start_position=, width=), qui accepte aussistorage_format,delimiteretdecimal_positions. Passezlogical_record=pour lier la structure sous-jacente à un enregistrement logique modélisé.PhysicalStructure.link_logical_record(..., key_variable=)déclare une clé de segment. - Jeux de données en ligne :
doc.add_dataset()stocke les valeurs directement dans le document, sous formeItemSet(add_item_value()),RecordSet(set_variable_order()/add_record()) ouVariableSet(add_variable_item()).
Questionnaires¶
- Constructions de flux :
QuestionConstruct,Sequence,IfThenElse,StatementItem,ComputationItemetLoopsont des typesadd_item()de premier ordre, stockés dans unControlConstructSchemeconstruit, sérialisé et rejoue automatiquement, et reliés entre eux par.to_reference().
Validation et qualité¶
- Validation de schéma hors ligne : les XSD DDI 3.1, 3.2 et 3.3 sont
livres dans le paquet :
doc.validate()etddi validatefonctionnent sans accès réseau ni téléchargement séparé. - Lecture de DDI 3.1, 3.2 et 3.3 :
read_ddi(),ddi validate,ddi lint,ddi to-jsonetddi roundtripdétectent la version déclarée par le document. L'API de rédactionDocumentet les modèles types ciblent DDI 3.3 ; les documents 3.1 et 3.2 se manipulent en XML viaDDIDocument.root. - Moteur de lint :
ddi lintetDocument.lint()vérifient l'intégrité des références, les libellés manquants et la complétude des citations. La règle des libellés suit le schéma : elle n'exige un libellé que là où le modèle de contenu prévoit un emplacementr:Label(174 des 1247 éléments de DDI 3.3). La règle sur les langues de citation compare des plages de langue selon le RFC 4647 : unenrequis est satisfait paren,en-CAouen-Latn-CA, mais pas pareng. - Une sortie propre au lint par défaut : l'API
Documentlibellé les modules, schemes et conteneurs physiques qu'elle crée, et chaque méthodeadd_*acceptelabel=.set_scheme_label()libellé n'importe quel conteneur de scheme généré. Un document lu n'est jamais modifié. - Des valeurs par défaut adaptées à une bibliothèque publiée : la liste
blanche d'agences est optionnelle (
configure_lint(allowed_agencies=[...])ou--allowed-agency) ; une agence absente est toujours une erreur.ddi lintne renvoie un code non nul que pour les erreurs ; utilisez--fail-severity warningpour un contrôle strict. - Des libellés seulement là où le schéma les autorise : la prise en
charge des libellés est dérivée des XSD. Poser un libellé sur un type sans
emplacement
r:Labelémet un avertissement au lieu de produire un document invalide. - Vérification des références :
Document.save()signale en un seulDDIReferenceWarningles références vers des éléments absents de l'étude. - Des erreurs claires : un XML mal forme lève
DDIParseErroravec la ligne et la colonne de l'analyseur ; une référence introuvable lèveDDIReferenceError(unLookupError) ; un identifiant en double lèveDuplicateIdentifierError, et un nom vide ou non textuel est refusé des l'ajout. Les échecs de schéma lèventSchemaValidationError, unDDIValidationErrordont.issuesporte le détail des problèmes. - Des exemples qui passent nos propres contrôles : les fichiers livres
example_instance.xmletQuality_of_Life.xmlsont valides selon le schéma et exempts d'erreurs de lint ;example_instance.xmln'a aucun signalement, quelle que soit la sévérité. Methodologyutilise l'espace de noms de DDI :<Methodology>est écrit dansddi:datacollection:3_3, comme le déclare DDI 3.3.- Les types d'extension sont visiblement les nôtres : les quelques types
ProcessetMethodologyqu'aucune version de DDI Lifecycle ne définit sont sérialisés dansurn:ddi-l:extension:*: rien ne peut être confondu avec un espace de noms DDI officiel. - Fidélité de l'aller-retour : les éléments et attributs XML inconnus sont préservés à l'ouverture et à la re-sauvegarde.
- Le backend
lxmlest un choix de performance, pas un dialecte : les documents produits parddi-lsont sérialisés en octets identiques avec et sansddi-l[full]. Un fichier tiers dont les espaces de noms sont disposés autrement (racine préfixée et redéclarationsxmlns=par élément, comme dansQuality_of_Life.xml) peut différer par l'écriture des préfixes entre les backends ; son contenu est identique.
Performance¶
import ddi_lcharge les noms à la première utilisation : importer le paquet et lancer la commandeddiprennent quelques centièmes de seconde.read_ddi()construit son index de résolution à la demande.- Avec
ddi-l[full], la validation vérifie d'abord le document avec libxml2 et ne lance le validateur détaillé xmlschema qu'en cas d'échec : un document valide est valide en quelques millisecondes, et les anomalies signalées sont identiques sur les deux moteurs. iter_variables(),iter_questions()etiterparse_ddi()parcourent les gros documents en flux et fournissent des objets complets.- Voir Performance pour les temps mesures.
API HTTP¶
- Service Litestar optionnel :
pip install 'ddi-l[server]'puisddi serveexpose la validation, l'analyse et la conversion via HTTP, avec la documentation OpenAPI sur/schema. Chaque point de terminaison est une fine enveloppe autour deddi_l.operations, que la ligne de commande appelle également : les deux ne peuvent pas diverger sur la validité d'un document. - OpenAPI qui se décrit lui-même :
/schemasert Swagger UI, et un navigateur qui ouvre la racine y est redirigé. Chaque point de terminaison déclare son corps de requête, ses paramètres de requête et un schéma de réponse type avec un exemple réel ; « Try it out » est prérempli avec une instance DDI valide. - Des valeurs par défaut adaptées à un service : corps de requête plafonné
à 32 Mio, nombre de traitements simultanés borne (
--max-jobs,503au-delà), schéma par défaut chargé au démarrage, aucune écriture disque, CORS désactivé sauf origines nommées, et le même durcissement XML que la bibliothèque. - Sortie JSON-LD :
POST /v1/convert/jsonldetddi to-jsonldrestituent une étude en données liées à l'aide du vocabulaire DDI-RDF Discovery (« Disco ») de la DDI Alliance, avec Dublin Core et SKOS pour les libellés et les URN DDI comme IRI. Couvre le sous-ensemble de découverte de DDI et fonctionne à sens unique, conformément à la spécification Disco ;to-jsonreste le format sans perte et réversible (XML vers JSON puis retour rend exactement les octets fournis, tout comme/v1/roundtrip). ddi_l.operations: le coeur indépendant du transport, utilisable directement pour intégrer ddi-l dans une autre application.
Couche de modèles¶
- Génération des modèles depuis les XSD : chaque classe de modèle est générée depuis le XSD officiel DDI 3.3, source unique de vérité pour les champs, l'ordre des éléments, les espaces de noms et la documentation. Les 508 types complexes du XSD sont couverts.
- Moteur XML générique :
from_xml()/to_xml()pilote par les tables générées_FIELD_XML_MAP,_ATTR_XML_MAPet_ELEMENT_ORDER, émettant les enfants dans l'ordre déclaré par le XSD. - Préfixes d'espaces de noms DDI stables : la sortie utilise les préfixes
canoniques
r:,s:,d:,l:,c:,a:,p:,pr:(ddiprofile) etprc:(process) plutôt que des noms générésns0/p0, et la sérialisation préfère le préfixe enregistré d'un espace de noms à un préfixe auto-généré. - Constantes d'espaces de noms : exportées pour chaque module DDI, y
compris
DDI_PROFILE_NSetDATASET_NS. - Type : livre
py.typed; l'API publique est entièrement annotée.
Outils et distribution¶
- CLI :
ddi validate,ddi lint,ddi to-json,ddi to-jsonld,ddi from-json,ddi roundtrip,ddi versionsetddi serve. Les commandes acceptent-o/--outputet--ddi-version;ddi validate --format jsonproduit un tableau JSON (vide si le document est valide) pour les scripts. - Backend lxml optionnel :
pip install ddi-l[full]active une analyse plus rapide des gros documents. - Référence d'API générée à partir des docstrings du code source, en plus des guides.
- Chaque exemple de code documenté est exécuté en CI, y compris les exemples R.
- Python 3.11, 3.12, 3.13 et 3.14 pris en charge et testés en CI.
- Publication PyPI via la publication de confiance OIDC de GitHub.
- Documentation bilingue en anglais et en français, dont un guide pour utiliser ddi-l depuis R avec reticulate.
- Cursus de formation : un cours progressif de 16 modules avec exercices, quiz, guide de l'instructeur, corrigés et aide-mémoire bilingue.