Universal Archive & Installer Engine — V2.0 Exemples

Universal_Installer
Exemples & Cas d'usage V2.0

38 exemples complets : compression UXC v3+IA, chiffrement AES-256-GCM, delta patches, cloud S3/Azure/GCS, API REST, CLI Watch, installateurs Windows/Linux/macOS, plugins, CI/CD.

UXC v3+IA+Delta AES-256-GCM Cloud S3/Azure/GCS API REST FastAPI ZIP · 7Z · TAR · ISO MSI · MSIX · Snap · PKG · DMG CI/CD · Batch · Watch
01

UXC v3 — Compression basique (CLI)

L'algorithme UXC v3 est le format natif de Universal_Installer : compression maximale avec IA prédictive par bloc, décompression parallèle ultra-rapide par ANS pré-calculés, dictionnaire partagé inter-fichiers.

Compression niveau max avec IACLI · UXC v3
CLI
# Niveau max avec IA (recommandé pour distribution) universal-installer compress ./mon_projet/ -o release.uxc -l max # Avec threads explicites et vérification SHA-256 universal-installer compress ./mon_projet/ -o release.uxc -l max --threads 8 --verify # Exclure fichiers inutiles universal-installer compress ./projet/ -o release.uxc -l max \ --exclude "*.tmp,*.pyc,__pycache__,.git,.DS_Store" # Niveau ultra — archives long terme universal-installer compress ./dataset/ -o archive.uxc -l ultra # Sans IA (comparaison) universal-installer compress ./projet/ -o noai.uxc -l max --no-ai
Format : UXC v3.0 IA algo : ONNX (uxc:68% zstd:18% lz4:9% stored:5%) Fichiers : 2847 Dossiers: 234 Original : 50.2 Mo → Compressé: 16.8 Mo (66.6%) Durée : 19.1s @ 2.6 Mo/s (8 threads) SHA-256 : a3f7c8d1e2b5f4a9... ✅
📂Décompression UXC multi-threadCLI · UXC v3
CLI
# Décompression parallèle automatique sur tous les cœurs universal-installer extract release.uxc -o ./sortie/ # [████████████████████] 100% — 16.8 Mo → 50.2 Mo — 1.1s (8 threads) universal-installer extract release.uxc -o ./flat/ --flat universal-installer extract release.uxc -o ./sortie/ --overwrite
Le niveau max avec IA est le meilleur choix pour les installateurs : l'IA détecte automatiquement les fichiers déjà compressés (JPEG, PNG, ZIP, MP4) et les stocke en STORED, évitant un traitement inutile.
02

UXC v3 — API Python complète

🔌Compression avec IA + dict partagé + progressAPI Python · UXC v3
Python
from universal_installer.core.uxc.engine import UXCCompressor import os, json, datetime c = UXCCompressor( level="max", threads=os.cpu_count(), use_shared_dict=True, # dict LZ77 partagé inter-fichiers (V1.2) auto_algo=True, # IA sélection par bloc (V2.0) exclude=["*.tmp", "*.log", "__pycache__", ".git"], progress_cb=lambda p: print(f"\r{p:.0%}", end=""), ) with c: c.add_directory("./mon_projet") c.add_file("./CHANGELOG.md") meta = {"version": "2.0.0", "built_at": str(datetime.datetime.now())} c.add_bytes("build_info.json", json.dumps(meta).encode()) stats = c.compress("release.uxc") print(f"Ratio : {stats.ratio:.1%}") print(f"Durée : {stats.elapsed:.1f}s @ {stats.throughput:.0f} Mo/s") print(f"SHA-256 : {stats.sha256}") print(f"IA blocs : uxc={stats.ai_uxc}% zstd={stats.ai_zstd}% stored={stats.ai_stored}%")
📖Explorateur et extraction APIAPI Python · UXC
from universal_installer import Archive, Extractor with Archive("release.uxc") as arc: info = arc.get_info() print(f"Format: {info.format} Ratio: {info.ratio:.1%} Chiffré: {info.encrypted}") entries = sorted(arc.list(), key=lambda e: e.size, reverse=True) for e in entries[:5]: print(f"{e.name:50} {e.size/1e3:.1f} Ko {e.ratio:.0%}") with Extractor("release.uxc") as e: e.extract_all("./sortie/") e.extract_file("config/app.json", "./out/") e.extract_pattern("**/*.dll", "./libs/") raw = e.read_file("config/app.json") # → bytes en mémoire cfg = json.loads(raw)
03

Chiffrement AES-256-GCM V1.1

Chiffrement intégré nativement dans le format UXC. Chaque bloc est chiffré avec un nonce unique dérivé de son index. PBKDF2-HMAC-SHA256, 600 000 itérations, tag GCM 16B par bloc.

🔒Compression chiffrée et extraction déchiffréeCLI + API · AES-256-GCM
CLI
# Compression avec chiffrement AES-256-GCM universal-installer compress ./data/ \ -o archive.uxc -l max \ --password "mon_mot_de_passe_fort" # Extraction déchiffrée universal-installer extract archive.uxc \ -o ./sortie/ \ --password "mon_mot_de_passe_fort" # Vérification intégrité (SHA-256 + GCM tags) universal-installer verify archive.uxc \ --password "mon_mot_de_passe_fort"
API Python
from universal_installer import compress, extract stats = compress( "./data/", "archive.uxc", format="uxc", level="max", password="mon_mot_de_passe_fort", ) print(f"Chiffré : {stats.encrypted}") print(f"SHA-256 : {stats.sha256}") extract( "archive.uxc", "./sortie/", password="mon_mot_de_passe_fort", )
Mot de passe perdu = archive irrécupérable. AES-256-GCM sans backdoor, 600 000 itérations PBKDF2. Utilisez un gestionnaire de mots de passe. Aucun mécanisme de récupération.
04

IA Prédictive Algo V2.0

Le module IA analyse chaque bloc de 64 Ko avec 19 features d'entropie et sélectionne automatiquement l'algorithme optimal en <1ms via ONNX Runtime ou scikit-learn.

🤖Prédiction algo + entraînement modèle offlineAPI Python · IA V2.0
Python
from universal_installer.core.uxc.ai_selector import ( AIAlgoSelector, AlgoSelectorTrainer, extract_features ) # Runtime : prédiction par bloc sel = AIAlgoSelector() print(f"Backend : {sel.backend}") # "onnx" | "sklearn" | "heuristic" data = open("monFichier.bin", "rb").read() algo = sel.predict(data) # → "uxc" | "zstd" | "lz4" | "stored" print(f"Algo optimal : {algo}") # Analyser les 19 features features = extract_features(data) print(f"Entropie : {features.entropy:.2f} bits") print(f"Score texte : {features.is_likely_text:.2f}") print(f"Score compressé : {features.is_likely_compressed:.2f}") # Benchmark comparatif ratios = sel.benchmark_block(data) print(f"uxc={ratios['uxc_estimate']:.1%} zstd={ratios['zstd']:.1%}") # ─── Entraînement offline sur votre corpus ─── trainer = AlgoSelectorTrainer() nb = trainer.collect_samples("./training_corpus/", max_files=500) print(f"{nb} blocs collectés") acc = trainer.train() print(f"Précision : {acc:.1%}") trainer.export_onnx("~/.universal_installer/models/algo_selector.onnx") trainer.export_sklearn("~/.universal_installer/models/algo_selector.pkl") print("Modèles exportés ✓")
05

Delta Patches .uxcd V2.0

Crée des patches différentiels entre deux versions d'une archive UXC. Le .uxcd ne contient que les blocs modifiés — les blocs identiques sont référencés par SHA-256 (0 byte de données).

🗺Créer, appliquer et analyser un patch deltaCLI + API · Delta V2.0
CLI
# Créer le patch universal-installer delta create \ v1.0.uxc v1.1.uxc \ -o update_v1.0_to_v1.1.uxcd # → Blocs modifiés: 142/2847 # → Taille patch: 480 Ko (ratio 68%) # Appliquer le patch universal-installer delta apply \ v1.0.uxc \ update_v1.0_to_v1.1.uxcd \ -o v1.1_restored.uxc # → SHA-256 vérifié ✅ 0.3s # Statistiques du patch universal-installer delta stats update_v1.0_to_v1.1.uxcd
API Python
from universal_installer.core.uxc.delta import UXCDelta p = UXCDelta() # Créer le patch stats = p.create_patch( "v1.0.uxc", "v1.1.uxc", "update.uxcd") print(f"Modifiés : {stats['changed_blocks']}/{stats['total_blocks']}") print(f"Patch size : {stats['patch_size_bytes']/1024:.1f} Ko") print(f"Économie : {stats['ratio']:.1%}") # Appliquer le patch result = p.apply_patch( "v1.0.uxc", "update.uxcd", "v1.1.uxc") print(f"SHA-256 ok : {result['verified']}") # Statistiques du patch info = p.patch_stats("update.uxcd") print(f"identical={info['identical_blocks']}") print(f"bsdiff={info['bsdiff_patches']}") print(f"full={info['full_patches']}")
Installez bsdiff4 (pip install universal-installer[delta]) pour des patches optimaux. Sans bsdiff4, les blocs modifiés sont stockés complets (fallback FULL) — le patch est plus volumineux mais fonctionne identiquement.
06

ZIP — Opérations classiques

📦Créer, lire et éditer un ZIPCLI + API · ZIP
CLI
# Compression ZIP standard universal-installer compress ./src/ \ -o backup.zip -l normal # ZIP avec mot de passe universal-installer compress ./conf/ \ -o secret.zip -p "monmotdepasse" # ZIP en volumes de 700 Mo universal-installer compress ./data/ \ -o archive.zip --split 700M # Extraction universal-installer extract backup.zip -o ./sortie/
API Python
from universal_installer import compress, Archive compress("./source", "backup.zip", format="zip", level="normal") with Archive("backup.zip", mode="a") as arc: arc.add_file("./nouveau.txt") arc.add_bytes("meta.json", b'{"date":"2027-01-15"}') arc.delete("obsolete.txt") arc.delete_pattern("**/*.pyc")
ZIP est recommandé pour la compatibilité maximale avec des outils tiers (WinRAR, 7-Zip, Finder macOS, Explorateur Windows). Pour la compression maximale, préférez UXC v3.
07

7Z — Haute compression

7️⃣7-Zip niveau ultra avec chiffrement AESCLI + API · 7Z
CLI
# Ultra — meilleur ratio 7Z universal-installer compress ./data/ \ -o archive.7z -l ultra --threads 4 # Avec chiffrement AES-256 universal-installer compress ./conf/ \ -o secure.7z -l max -p "secret" # Extraction universal-installer extract archive.7z \ -o ./out/ --threads 8
API Python
from universal_installer import compress compress( "./data", "archive.7z", format="7z", level="ultra", threads=4, password="secret", )
08

TAR / ZST / XZ — Linux & CI

🐧Formats TAR compressésCLI + API
CLI
# TAR.ZST — ultra-rapide, bon ratio universal-installer compress ./projet/ \ -o backup.tar.zst -l max # TAR.XZ — meilleur ratio, lent universal-installer compress ./src/ \ -o archive.tar.xz -l ultra # TAR.GZ — compatibilité universelle universal-installer compress ./dist/ \ -o release.tar.gz -l normal
API Python
from universal_installer import compress # ZST — meilleur choix CI/CD compress("./artefacts", "artefacts.tar.zst", format="tar.zst", level="max") # XZ pour archives long terme compress("./sources", "sources.tar.xz", format="tar.xz", level="ultra")
09

Extraction Universelle

📂Extraire tous les formats — auto-détection magic bytesCLI + API
CLI
# Format auto-détecté par magic bytes universal-installer extract archive.uxc -o ./sortie/ universal-installer extract archive.zip -o ./sortie/ universal-installer extract archive.7z -o ./sortie/ universal-installer extract archive.rar -o ./sortie/ universal-installer extract image.iso -o ./contenu/ universal-installer extract fichier.dat -o ./sortie/ # inconnu universal-installer extract arc.uxc.001 -o ./sortie/ # multi-vol
API Python
from universal_installer import extract from universal_installer.utils import detect_format # Détecter le format fmt = detect_format("fichier_inconnu.dat") print(f"Format détecté : {fmt}") # Extraction universelle extract("archive.uxc", "./sortie/") extract("archive.zip", "./sortie/") extract("image.iso", "./contenu/")
10

Extraction Sélective

🎯Extraire un sous-ensemble de fichiersCLI + API
CLI
# Extraire uniquement les fichiers Python universal-installer extract archive.uxc \ -o ./sortie/ -f "**/*.py" # Un fichier spécifique universal-installer extract archive.zip \ -o ./out/ -f "config/app.json" # Sans arborescence universal-installer extract archive.uxc \ -o ./flat/ --flat
API Python
from universal_installer import Extractor with Extractor("release.uxc") as e: e.extract_pattern("**/*.dll", "./libs/") e.extract_pattern("**/*.py", "./src/") # Lire en mémoire sans écriture disque raw = e.read_file("config/app.json") exists = e.exists("assets/logo.png")
11

ISO — Images Disque

💿Créer et extraire des images ISOCLI + API · ISO
CLI
# ISO depuis un dossier universal-installer compress ./package/ \ -o package.iso -f iso # Extraire une ISO universal-installer extract image.iso -o ./contenu/ universal-installer inspect image.iso
API Python
from universal_installer import compress, extract compress("./package/", "package.iso", format="iso") extract("image.iso", "./contenu/")
12

CAB / WIM — Formats Windows V1.1

🗄Lecture et extraction de formats Windows natifsCLI + API · CAB · WIM
CLI — CAB
universal-installer inspect archive.cab universal-installer extract archive.cab -o ./sortie/ # Créer un CAB (cabfile requis) universal-installer compress ./files/ -o archive.cab -f cab
CLI — WIM
universal-installer inspect install.wim universal-installer list install.wim universal-installer extract install.wim -o ./image_windows/
API Python
from universal_installer import Archive # CAB — parsing binaire natif (magic MSCF) with Archive("archive.cab") as arc: info = arc.get_info() print(f"Format : {info.format} v{info.version}") for e in arc.list(): print(f"{e.name} {e.size} bytes")
13

RAR — Lecture

📁Lire et extraire des archives RARCLI + API · RAR (lecture seule)
CLI
universal-installer inspect archive.rar universal-installer extract archive.rar -o ./sortie/ universal-installer extract archive.rar -f "*.pdf" -o ./docs/ # Convertir en UXC universal-installer convert archive.rar -o archive.uxc -l max
API Python
from universal_installer import extract, convert_archive extract("archive.rar", "./sortie/") # RAR → UXC sans fichier intermédiaire convert_archive("archive.rar", "archive.uxc", target_level="max", in_memory=True)
RAR est en lecture uniquement (format propriétaire WinRAR). Universal_Installer ne peut pas créer de fichiers .rar. Utilisez UXC ou 7Z comme alternatives open source.
14

Conversion entre Formats

🔄Convertir sans fichier intermédiaireCLI + API
CLI
# ZIP → UXC v3 avec IA universal-installer convert source.zip -o source.uxc -l max # RAR → ZIP (format éditable) universal-installer convert archive.rar -o archive.zip # TAR.GZ → 7Z (compression maximale) universal-installer convert backup.tar.gz -o backup.7z -l ultra # Dossier → ISO universal-installer compress ./package/ -o package.iso -f iso
API Python
from universal_installer import convert_archive convert_archive( source="ancien.zip", destination="nouveau.uxc", target_level="max", in_memory=True, # zéro fichier intermédiaire verify=True, # SHA-256 vérifié après )
15

SFX — Archive Auto-extractible V1.1

📦Créer un installateur .exe auto-extractibleCLI + API · SFX
CLI
universal-installer sfx create archive.uxc \ -o setup.exe \ --run-after install.bat \ --title "Mon Application V2.0" \ --silent
API Python
from universal_installer.archive.sfx import SFXBuilder, SFXOptions opts = SFXOptions( archive_path="mon_app.uxc", output_path="setup.exe", title="Mon Application V2.0", run_after="install.bat", extract_dir="C:\\MonApp", silent=False, overwrite=True, ) SFXBuilder(opts).build()
Installez PyInstaller (pip install universal-installer[sfx]) pour un vrai EXE natif sans Python requis sur la cible. Sans PyInstaller, un stub Python est utilisé (Python requis sur la cible).
16

Multi-volumes Split / Join V1.1

📂Découper et assembler des archives volumineusesCLI + API · Multi-volumes
CLI
# Découper en volumes de 700 Mo universal-installer split archive.uxc \ --size 700M -o ./volumes/ # → archive.uxc.001 / .002 / .003 # Assembler universal-installer join \ ./volumes/archive.uxc.001 \ -o archive_restored.uxc # Via uxc-extract (assemblage auto) uxc-extract ./volumes/archive.uxc.001 -o ./sortie/
API Python
from universal_installer.archive.sfx import MultiVolumeManager vols = MultiVolumeManager.split( "archive.uxc", size_mb=700, output_dir="./volumes/") print(f"{len(vols)} volumes créés") out = MultiVolumeManager.join( "./volumes/archive.uxc.001", "archive_restored.uxc")
17

Réparation d'Archive Corrompue V1.1

🔧Récupérer le maximum d'une archive corrompueCLI + API · Réparation
CLI
universal-installer repair \ archive_corrompue.uxc \ -o archive_reparee.uxc # ✅ Récupération OK # Fichiers récupérés : 2843/2847 # Blocs réparés (→ zéros) : 4 uxc-extract archive_corrompue.uxc \ -o ./sortie/ --repair
API Python
from universal_installer.core.uxc.engine import UXCRepair result = UXCRepair.repair( "archive_corrompue.uxc", "archive_reparee.uxc") print(f"OK : {result['ok']}") print(f"Fichiers : {result['file_count']}") print(f"Réparés : {result['repaired_blocks']}")
18

Prévisualisation Fichiers V1.1

👁Prévisualiser un fichier sans extraction sur disqueGUI + API Python

Via GUI : double-cliquez sur n'importe quel fichier dans l'explorateur. Chargement en thread background. Texte (512 Ko), JSON formaté, Images PNG/JPG/GIF, PDF page 1, Hex dump.

API Python
from universal_installer.ui.gui.preview import open_preview from universal_installer import Extractor # Ouvrir la prévisualisation GUI open_preview(archive_path="release.uxc", entry_name="src/engine.py", password=None, parent=main_window) # Accès direct aux données en mémoire with Extractor("release.uxc") as e: raw = e.read_file("config/app.json") print(raw.decode("utf-8")) img_data = e.read_file("assets/logo.png") # → bytes PNG prêt pour PIL/Qt
19

Cloud — AWS S3 V2.0

Compress & upload atomique vers AWS S3. Retry exponentiel 3×, presigned URLs, toutes storage classes. Compatible MinIO, Wasabi, Backblaze B2 via endpoint custom.

Compression + upload S3 atomiqueAPI Python · Cloud S3 V2.0
Python
from universal_installer.cloud import CloudStorage, S3Config # AWS S3 (credentials depuis env AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY) storage = CloudStorage(S3Config( bucket="my-releases", region="eu-west-3", storage_class="STANDARD", )) result = storage.compress_and_upload( source="./dist/", remote_key="releases/app-v2.0.0.uxc", format="uxc", level="max", retry=3, progress_cb=lambda p: print(f"\r{p:.0%}", end=""), ) print(f"\nURL : {result.public_url}") print(f"SHA-256 : {result.sha256}") print(f"Ratio : {result.ratio:.1%}") print(f"Vitesse : {result.upload_speed_mbps:.1f} Mo/s") # Lister les objets objects = storage.list_objects(prefix="releases/") for obj in objects: print(f"{obj['key']} {obj['size']/1e6:.1f} Mo") # URL temporaire (1 heure) url = storage.get_url("releases/app-v2.0.0.uxc", expires_in=3600) # MinIO / endpoint custom storage_minio = CloudStorage(S3Config( bucket="my-bucket", endpoint_url="http://localhost:9000", access_key="minioadmin", secret_key="minioadmin", ))
L'upload est atomique : compression locale (temp) puis upload avec 3 tentatives. En cas d'échec définitif, le temp est supprimé. Le bucket ne contiendra jamais d'archive partielle.
20

Cloud — Azure Blob Storage V2.0

Compression + upload Azure atomiqueAPI Python · Azure V2.0
from universal_installer.cloud import CloudStorage, AzureConfig import os storage = CloudStorage(AzureConfig( container="releases", connection_string=os.environ.get( "AZURE_STORAGE_CONNECTION_STRING", "DefaultEndpointsProtocol=https;AccountName=myaccount;..." ), )) result = storage.compress_and_upload( source="./dist/", remote_key="app-v2.0.0.uxc", format="uxc", level="max", ) print(f"Uploadé : {result.public_url}") # Upload direct storage.upload("./release/app.uxc", "releases/app-v2.0.0.uxc") # SAS token 1h sas_url = storage.get_url("releases/app-v2.0.0.uxc", expires_in=3600)
21

Cloud — Google Cloud Storage V2.0

Compression + upload GCS atomiqueAPI Python · GCS V2.0
from universal_installer.cloud import CloudStorage, GCSConfig storage = CloudStorage(GCSConfig( bucket="my-archives", project="my-gcp-project", credentials_file="~/.gcloud/key.json", # ou env : GOOGLE_APPLICATION_CREDENTIALS storage_class="NEARLINE", # STANDARD|NEARLINE|COLDLINE|ARCHIVE )) result = storage.compress_and_upload( source="./dist/", remote_key="releases/app-v2.0.0.uxc", format="uxc", level="max", ) print(f"Uploadé vers GCS : {result.public_url}") objects = storage.list_objects(prefix="releases/") url = storage.get_url("releases/app-v2.0.0.uxc", expires_in=3600)
22

API REST — curl & Python V2.0

L'API REST FastAPI permet d'intégrer Universal_Installer dans n'importe quel langage via HTTP. Démarrez avec universal-installer-api --port 8080.

🌐Compression, extraction et delta via HTTPcurl + Python · REST API V2.0
curl
# Health check curl http://localhost:8080/health # Compresser curl -X POST http://localhost:8080/compress \ -H "Authorization: Bearer ma_cle" \ -F "file=@./dist.zip" -F "format=uxc" -F "level=max" \ -o release.uxc # Extraire curl -X POST http://localhost:8080/extract \ -F "file=@archive.uxc" -F "password=secret" \ -o extracted.zip # Créer un patch delta curl -X POST http://localhost:8080/delta/create \ -F "source=@v1.0.uxc" -F "target=@v1.1.uxc" \ -o update.uxcd # Appliquer un patch curl -X POST http://localhost:8080/delta/apply \ -F "source=@v1.0.uxc" -F "patch=@update.uxcd" \ -o v1.1_restored.uxc
Python (httpx)
import httpx BASE = "http://localhost:8080" HEADERS = {"Authorization": "Bearer ma_cle"} with httpx.Client() as client: resp = client.post(f"{BASE}/compress", headers=HEADERS, files={"file": ("dist.zip", open("./dist.zip", "rb"))}, data={"format": "uxc", "level": "max"}, timeout=300, ) open("release.uxc", "wb").write(resp.content) print(f"Ratio : {resp.headers['X-Ratio']}") print(f"SHA-256 : {resp.headers['X-SHA256']}") # WebSocket progression import asyncio, websockets, json async def watch_progress(session_id): async with websockets.connect( f"ws://localhost:8080/ws/progress/{session_id}" ) as ws: async for msg in ws: d = json.loads(msg) print(f"{d['status']} — {d['progress']:.0%}") if d['status'] in ("done", "error"): break
23

CLI Watch — Surveillance Auto V2.0

Surveille un dossier et comprime automatiquement selon la stratégie choisie : immediate, debounced, scheduled ou incremental. Upload cloud auto optionnel.

👀4 stratégies + upload cloud automatiqueCLI + API Python · Watch V2.0
CLI
# Debounced — recommandé pour le développement universal-installer watch ./mon_projet \ --output ./backups/ --strategy debounced \ --delay 10 --format uxc --level normal --max-archives 20 # Incrémental — seulement les fichiers modifiés universal-installer watch ./data --output ./backups/ --strategy incremental # Schedulé — toutes les 5 minutes universal-installer watch ./logs --output ./backups/ \ --strategy scheduled --interval 300 # Upload S3 automatique après chaque compression universal-installer watch ./dist --output ./backups/ \ --cloud s3 --bucket my-bucket --region eu-west-3
API Python
from universal_installer.ui.cli.watch import FileWatcher from universal_installer.cloud import CloudStorage, S3Config watcher = FileWatcher( source="./mon_projet", output_dir="./backups/", format="uxc", strategy="debounced", debounce_delay=5.0, max_archives=20, cloud_storage=CloudStorage(S3Config(bucket="my-backups")), exclude=["*.pyc", "__pycache__", ".git"], on_compress=lambda path, stats: print( f"✅ {path} ratio={stats['ratio']:.1%}"), ) watcher.start(block=False) # thread daemon # ... code principal ... watcher.stop()
24

MSI — Installateur Simple

Packager une application Python compilée (PyInstaller) en installateur Windows MSI professionnel via WiX Toolset 4.x.

🏗Créer un MSI depuis un dossier dist/CLI + API · MSI
CLI
universal-installer msi create \ --name "MonApplication" \ --version 2.0.0 \ --manufacturer "Tristan Ruard" \ --source ./dist/mon_app/ \ --icon ./assets/icon.ico \ --license ./LICENSE.rtf \ --output ./release/MonApp-2.0.0.msi
API Python
from universal_installer.installer import MSIBuilder builder = MSIBuilder( name="MonApplication", version="2.0.0", manufacturer="Tristan Ruard", source_dir="./dist/", output="./release/MonApp-2.0.0.msi", ) builder.set_icon("./assets/icon.ico") builder.set_license("./LICENSE.rtf") builder.add_shortcut("MonApp", "MonApp.exe", desktop=True, start_menu=True) builder.build() print("MSI créé ✓")
Nécessite WiX Toolset 4.x sur Windows uniquement : dotnet tool install --global wix.
25

MSI — Configuration Avancée

MSI avec raccourcis, registre, associations, conditionsAPI Python · MSI
Python
from universal_installer.installer import MSIBuilder builder = MSIBuilder( name="MonApplication", version="2.0.0", manufacturer="Tristan Ruard", source_dir="./dist/", output="./release/MonApp.msi", upgrade_code="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ) builder.set_icon("./assets/icon.ico") builder.set_license("./LICENSE.rtf") builder.set_banner("./assets/banner.bmp") # 493×58 builder.set_dialog_bg("./assets/dialog.bmp") # 493×312 builder.add_shortcut("MonApp", "MonApp.exe", desktop=True, start_menu=True, start_menu_folder="Tristan Ruard") builder.add_env_variable("MONAPP_HOME", "[INSTALLDIR]") builder.add_registry_key("HKLM", r"Software\MonApp", {"Version": "2.0.0", "InstallDir": "[INSTALLDIR]"}) builder.add_file_association(".mxf", "Fichier MonApp", "MonApp.exe", icon="MonApp.exe,0") builder.add_condition("VersionNT >= 1000", "Windows 10 ou supérieur requis.") builder.build() print("MSI complet créé : raccourcis + registre + associations ✓")
26

MSIX — Package Moderne Windows 10/11

📱Créer un package MSIX signéCLI + API · MSIX
CLI
universal-installer msix create \ --name "MonApp" \ --publisher "CN=TristanRuard" \ --version 2.0.0.0 \ --source ./dist/ \ --assets ./assets/logos/ \ --cert ./cert.pfx \ --cert-pass "secret" \ --output ./release/MonApp.msix
API Python
from universal_installer.installer import MSIXBuilder builder = MSIXBuilder( name="MonApp", publisher="CN=TristanRuard", version="2.0.0.0", source_dir="./dist/", output="./release/MonApp.msix", ) builder.add_visual_assets("./assets/logos/") builder.add_capability("internetClient") builder.add_file_association(".mxf", "Fichier MonApp") builder.sign("./cert.pfx", "secret", timestamp="http://timestamp.sectigo.com") builder.build() print("MSIX signé créé ✓")
27

Snap Linux V2.0

🐧Build Snap complet avec confinement strictCLI + API · Snap V2.0
CLI
universal-installer snap create \ --name "mon-app" \ --version 2.0.0 \ --summary "Mon Application" \ --source ./dist/ \ --output ./release/ \ --confinement strict \ --grade stable
API Python
from universal_installer.installer.linux import SnapBuilder builder = SnapBuilder( name="mon-app", version="2.0.0", summary="Mon Application", description="Application Python V2.0", source_dir="./dist/", output="./release/", confinement="strict", grade="stable", architectures=["amd64"], ) builder.add_command("mon-app", "./bin/mon_app", plugs=["network", "home"]) snap_path = builder.build() print(f"Snap : {snap_path}")
Prérequis : sudo snap install snapcraft --classic. Le YAML snapcraft est généré automatiquement depuis la configuration Python.
28

AppImage Linux V2.0

🐧Build AppImage portable — compatible toutes distrosCLI + API · AppImage V2.0
CLI
universal-installer appimage create \ --name "MonApp" --version 2.0.0 \ --source ./dist/ \ --executable ./bin/mon_app \ --icon ./assets/icon.png \ --categories "Utility;" \ --output ./release/MonApp-2.0.0-x86_64.AppImage
API Python
from universal_installer.installer.linux import AppImageBuilder builder = AppImageBuilder( name="MonApp", version="2.0.0", source_dir="./dist/", output="./release/MonApp-2.0.0-x86_64.AppImage", executable="./bin/mon_app", icon="./assets/icon.png", categories="Utility;", arch="x86_64", ) path = builder.build() print(f"AppImage : {path}")
appimagetool est automatiquement téléchargé depuis GitHub AppImageKit dans ~/.local/bin/ si absent du PATH. L'AppImage produit est exécutable directement sur toute distribution Linux sans installation.
29

PKG macOS V2.0

🍎Installateur PKG avec signature Developer IDCLI + API · macOS PKG V2.0
CLI
universal-installer pkg create \ --name "MonApp" --version 2.0.0 \ --identifier "com.tristan.monapp" \ --source ./dist/MonApp.app \ --output ./release/MonApp-2.0.0.pkg \ --install-location /Applications \ --min-os 12.0 \ --sign "Developer ID Installer: Tristan Ruard" \ --postinstall ./scripts/postinstall.sh
API Python
from universal_installer.installer.macos import PKGBuilder builder = PKGBuilder( name="MonApp", version="2.0.0", identifier="com.tristan.monapp", source_dir="./dist/MonApp.app", output="./release/MonApp-2.0.0.pkg", install_location="/Applications", min_os_version="12.0", ) builder.add_postinstall_script("./scripts/postinstall.sh") builder.sign("Developer ID Installer: Tristan Ruard") pkg_path = builder.build() print(f"PKG signé : {pkg_path}")
Nécessite macOS et xcode-select --install. La signature nécessite un certificat Developer ID Installer (Apple Developer Program).
30

DMG macOS V2.0

🍎Image disque DMG professionnelleCLI + API · macOS DMG V2.0
CLI
universal-installer dmg create \ --name "MonApp" --version 2.0.0 \ --app ./dist/MonApp.app \ --output ./release/MonApp-2.0.0.dmg \ --background ./assets/dmg_bg.png \ --window-size 660 400 --icon-size 128
API Python
from universal_installer.installer.macos import DMGBuilder builder = DMGBuilder( name="MonApp", version="2.0.0", app_path="./dist/MonApp.app", output="./release/MonApp-2.0.0.dmg", background_image="./assets/dmg_bg.png", window_size=(660, 400), icon_size=128, volume_name="MonApp 2.0.0", ) dmg_path = builder.build() print(f"DMG : {dmg_path}")
31

Plugin Custom — Format tiers V1.2

🔌Créer et enregistrer un plugin de formatAPI Python · Plugin API
Python
# xyz_handler.py — Plugin de format .xyz from universal_installer.plugin import register_handler, ArchivePlugin @register_handler( extensions=[".xyz"], magic=b"XYZ!", name="XYZ Format Handler", version="1.0.0", ) class XYZHandler(ArchivePlugin): def open(self, path, mode="r", password=None): self._path = path def close(self): pass def list(self): return [] def read(self, name): return b"" def write(self, name, data): pass def extract_all(self, dest, overwrite=True): pass def get_info(self): return None # Charger et utiliser les plugins from universal_installer.plugin import load_plugins, get_plugin_handler plugins = load_plugins() print(f"{len(plugins)} plugin(s) chargé(s)") for p in plugins: print(f" {p.name} v{p.version} — {p.extensions}") # Utiliser le handler handler_cls = get_plugin_handler("archive.xyz") if handler_cls: with handler_cls() as h: h.open("archive.xyz") entries = h.list()
pyproject.toml (entry_point pip)
[project.entry-points."universal_installer.plugins"] xyz-format = "mon_plugin.xyz_handler:XYZHandler"
32

Marketplace V2.0

🏪Gérer les plugins du catalogue communautéCLI + API Python · Marketplace V2.0
CLI
universal-installer marketplace list universal-installer marketplace search "audio" universal-installer marketplace install xyz-format universal-installer marketplace uninstall xyz-format universal-installer marketplace update-all
API Python
from universal_installer.marketplace import ( MarketplaceManager, SecurityError) mgr = MarketplaceManager() catalog = mgr.fetch_catalog(force_refresh=True) print(f"{len(catalog.plugins)} plugins") results = mgr.search("audio") for p in results: print(f"{'🔒' if p.verified else ' '} {p.name} v{p.version}") try: mgr.install("xyz-format") print("✅ Plugin installé") except SecurityError as e: print(f"⛔ SHA-256 invalide : {e}") results = mgr.update_all() ok = sum(1 for v in results.values() if v) print(f"{ok}/{len(results)} mis à jour")
33

Édition MSI / MSIX Existants

🔧Inspecter et modifier un MSI existantCLI + API · MSI/MSIX
CLI
universal-installer msi inspect app.msi universal-installer msi list-files app.msi # ProductName : MonApp # ProductVersion : 2.0.0 # Files : 47 Shortcuts : 2
API Python
from universal_installer.installer import MSIEditor with MSIEditor("app.msi") as msi: v = msi.get_property("ProductVersion") msi.set_property("ProductVersion", "2.0.1") msi.replace_file("app.exe", "./new_app.exe") for sc in msi.list_shortcuts(): print(f"{sc.name} → {sc.target}")
34

Édition d'Archives

Modifier une archive sans la recréerAPI Python
Python
from universal_installer import Archive import json, datetime with Archive("release.zip", mode="a") as arc: arc.add_file("./CHANGELOG.md") meta = {"version": "2.0.0", "built_at": str(datetime.datetime.now())} arc.add_bytes("build_meta.json", json.dumps(meta).encode()) arc.delete("debug.log") arc.delete_pattern("**/*.pyc") arc.rename("config.example", "config.default") arc.update_file("README.md", "./README_v2.md") arc.mkdir("docs/") print(f"Archive mise à jour : {arc.count} fichiers")
35

Traitement en masse (Batch)

Convertir, compresser ou inspecter des centaines d'archives en parallèle avec gestion des erreurs et rapport de résultats.

🔁Convertir tous les ZIP d'un dossier en UXC v3API Python · Batch
Python
from pathlib import Path from universal_installer import convert_archive from concurrent.futures import ThreadPoolExecutor, as_completed source_dir = Path("./archives_zip/") output_dir = Path("./archives_uxc/") output_dir.mkdir(exist_ok=True) zips = list(source_dir.glob("**/*.zip")) print(f"{len(zips)} archives ZIP trouvées") results = {"ok": 0, "error": 0} def convert_one(zip_path): out = output_dir / zip_path.with_suffix(".uxc").name try: convert_archive(str(zip_path), str(out), target_level="max", in_memory=True) return ("ok", zip_path.name) except Exception as e: return ("error", f"{zip_path.name}: {e}") with ThreadPoolExecutor(max_workers=4) as ex: futures = {ex.submit(convert_one, z): z for z in zips} for future in as_completed(futures): status, msg = future.result() results[status] += 1 print(f"{'✅' if status=='ok' else '❌'} {msg}") print(f"\nBilan : {results['ok']} OK, {results['error']} erreurs")
36

Pipeline CI/CD V2.0

Pipeline complet : PyInstaller → UXC v3+IA → delta patch → vérification SHA-256 → upload S3 → installateur multi-plateforme → rapport JSON.

🚀Build script CI/CD V2.0 completAPI Python · CI/CD · V2.0
Python
#!/usr/bin/env python3 import subprocess, sys, json, platform from pathlib import Path from universal_installer import compress from universal_installer.cloud import CloudStorage, S3Config from universal_installer.core.uxc.delta import UXCDelta from universal_installer.installer import MSIBuilder from universal_installer.installer.linux import AppImageBuilder from universal_installer.installer.macos import PKGBuilder from universal_installer.utils import verify_integrity VERSION = "2.0.0" APP_NAME = "MonApplication" DIST = Path("./dist/MonApp") RELEASE = Path("./release") PREVIOUS_UXC = Path("./previous/MonApp-1.9.0.uxc") RELEASE.mkdir(exist_ok=True) print(f"=== Build {APP_NAME} v{VERSION} ===") # 1. Compilation PyInstaller print("[1/6] PyInstaller...") subprocess.run([sys.executable, "-m", "PyInstaller", "--onedir", "--name", APP_NAME, "src/main.py"], check=True) # 2. Archive UXC v3 + IA print("[2/6] Compression UXC v3 + IA...") uxc_path = RELEASE / f"{APP_NAME}-{VERSION}.uxc" stats = compress(str(DIST), str(uxc_path), format="uxc", level="max", verify_after=True) print(f" Ratio: {stats.ratio:.1%} | SHA-256: {stats.sha256[:16]}...") # 3. Patch delta depuis version précédente if PREVIOUS_UXC.exists(): print("[3/6] Patch delta...") patch_path = RELEASE / f"update_1.9.0_to_{VERSION}.uxcd" ds = UXCDelta().create_patch(str(PREVIOUS_UXC), str(uxc_path), str(patch_path)) print(f" Blocs modifiés: {ds['changed_blocks']} Patch: {ds['patch_size_bytes']/1024:.1f} Ko") else: patch_path = None print("[3/6] Patch delta ignoré (pas de version précédente)") # 4. Vérification intégrité print("[4/6] Vérification intégrité...") ok, detail = verify_integrity(str(uxc_path)) if not ok: raise RuntimeError(f"Intégrité KO : {detail}") print(" ✅ SHA-256 OK") # 5. Upload S3 print("[5/6] Upload S3...") storage = CloudStorage(S3Config(bucket="my-releases", region="eu-west-3")) storage.upload(str(uxc_path), f"releases/v{VERSION}/{APP_NAME}-{VERSION}.uxc") if patch_path and patch_path.exists(): storage.upload(str(patch_path), f"releases/v{VERSION}/{patch_path.name}") print(" Upload OK") # 6. Installateur selon plateforme sys_name = platform.system() print(f"[6/6] Installateur {sys_name}...") installer_path = None if sys_name == "Windows": msi = RELEASE / f"{APP_NAME}-{VERSION}.msi" b = MSIBuilder(name=APP_NAME, version=VERSION, manufacturer="Tristan Ruard", source_dir=str(DIST), output=str(msi)) b.set_icon("./assets/icon.ico") b.add_shortcut(APP_NAME, "MonApp.exe", desktop=True, start_menu=True) b.build() installer_path = msi elif sys_name == "Linux": ai = RELEASE / f"{APP_NAME}-{VERSION}-x86_64.AppImage" AppImageBuilder(name=APP_NAME, version=VERSION, source_dir=str(DIST), output=str(ai), executable="./bin/MonApp").build() installer_path = ai elif sys_name == "Darwin": pkg = RELEASE / f"{APP_NAME}-{VERSION}.pkg" PKGBuilder(name=APP_NAME, version=VERSION, identifier="com.tristan.monapp", source_dir="./dist/MonApp.app", output=str(pkg), install_location="/Applications").build() installer_path = pkg # Rapport JSON report = { "app": APP_NAME, "version": VERSION, "uxc": str(uxc_path), "ratio": f"{stats.ratio:.1%}", "sha256": stats.sha256, "installer": str(installer_path) if installer_path else None, "delta_patch": str(patch_path) if patch_path else None, "platform": sys_name, } (RELEASE / "build_report.json").write_text(json.dumps(report, indent=2)) print(f"=== Build terminé : {RELEASE} ===")
37

Benchmark & Comparaison d'algorithmes

📊Comparer UXC v3+IA vs 7Z vs ZIP vs ZSTCLI + API · Benchmark
CLI
universal-installer benchmark \ --input ./donnees_test/ \ --formats uxc,zip,7z,zst \ --levels max,ultra
FORMAT RATIO COMP. DECOMP. THREADS IA UXC-max+IA 66.8% 19.1s 1.1s 8 ONNX UXC-max 64.2% 18.3s 1.2s 8 — 7z-ultra 66.1% 145.2s 4.8s 1 — ZIP-max 52.1% 8.1s 2.1s 1 — ZST-19+IA 62.4% 11.2s 0.7s 8 ONNX
API Python
from universal_installer.utils import benchmark results = benchmark( input_path="./test_data/", formats=["uxc", "zip", "7z", "zst"], levels=["max"], ai=True, ) for r in sorted(results, key=lambda x: x.ratio, reverse=True): print( f"{r.format:15} ratio={r.ratio:.1%} " f"comp={r.compress_time:.1f}s " f"decomp={r.decompress_time:.1f}s" )
38

Intégrité & Vérification

🔒Checksums et vérification d'intégritéCLI + API
CLI
# SHA-256 embarqué dans le header UXC universal-installer verify archive.uxc # Calculer checksums universal-installer hash archive.zip # SHA-256 : a3f7c8d1e2b5f4a9... # CRC-32 : 0xA3F7C8D1 # MD5 : d41d8cd98f00b204... # Statut : ✅ INTÉGRITÉ OK # SHA-512 uniquement universal-installer hash archive.uxc -a sha512
API Python
from universal_installer.utils import ( verify_integrity, compute_hash) ok, detail = verify_integrity("release.uxc") if not ok: raise RuntimeError(f"Corruption : {detail}") hashes = compute_hash("archive.zip", algos=["sha256", "crc32", "md5"]) print(hashes["sha256"]) # Vérification en masse from pathlib import Path for arch in Path("./release").glob("*.uxc"): ok, _ = verify_integrity(str(arch)) print(f"{'✅' if ok else '❌'} {arch.name}")
Chaque archive .uxc embarque le SHA-256 dans le header (32B). Avec AES-256-GCM, chaque bloc possède un tag GCM 16B. La vérification est automatique à l'extraction (désactivable avec --no-verify).