Anatomia di un add-on Blender che parla OAuth e REST — senza congelare la UI
L’API bpy di Blender gira sul main thread. Una chiamata HTTP bloccante per l’upload di un file \`.blend\` da 500 MB lascia Blender „non risponde“ per 90 secondi — e la maggior parte degli utenti forza il restart del processo. Il fix è un background worker con timer callback verso il main thread, più OAuth device flow (nessun browser callback necessario).
Il nostro zer0one-blender-addon (su GitHub) aggiunge a Blender il menu `File → Send to ZER0ONE Lab`. Click, e la scena corrente viene inviata al backend Cinema Render. La prima versione ha richiesto ~2 settimane — i primi giorni ogni iterazione tornava con „perché Blender non risponde più“. I tre problemi che abbiamo dovuto risolvere sono piuttosto tipici per qualsiasi add-on Blender che parli con API esterne.
Problema 1: il flow di auth senza browser callback
Flow OAuth standard: l’utente clicca „Login“, si apre il browser, autorizza sul sito del provider, il provider redirige a un endpoint `localhost:8080/callback`, la tua app legge il code dall’URL. Funziona per le web app. In Blender: no — Blender non può avviare in modo affidabile un server HTTP in background (in teoria si può, ma si rompe su setup con firewall Windows, sandbox macOS e diverse distribuzioni Linux con errori differenti).
La soluzione pulita è OAuth 2.0 Device Flow (RFC 8628). Il flow:
- L’add-on esegue `POST /oauth/device/code` con la Client-ID. Il server risponde con `device_code`, `user_code`, `verification_uri`.
- L’add-on mostra all’utente: „Apri `https://zer0onelab.com/device\` nel tuo browser e inserisci il code `ABCD-1234`.“ L’utente lo fa (su un dispositivo qualsiasi — telefono, altro laptop, non importa).
- L’add-on fa polling su `POST /oauth/token` con il `device_code` ogni 5 secondi. Il server risponde con `authorization_pending` finché l’utente non ha confermato, poi con il vero Access Token.
Nessun browser callback, nessun server HTTP nel processo Blender. L’utente esegue l’autorizzazione sul dispositivo che preferisce. Su un laptop con browser locale sulla stessa macchina; su macchine di render di studio senza browser, allo stesso modo.
Nota di implementazione: il Python embedded di Blender non ha `requests`, ma `urllib.request` basta per tutte le chiamate OAuth. Ci si risparmia una discussione sul bundle di dipendenze che diventa altrimenti un inferno di versioning.
Problema 2: async senza asyncio (perché bpy non gioca bene con asyncio)
Blender avvia Python nel main thread. `bpy.ops` e tutte le modifiche di scena devono girare nel main thread — se provi a chiamarle da un background thread, ottieni un crash o undefined behavior.
Ma un upload da 500 MB a 100 Mbit richiede circa 45 secondi. Se lo fai nel main thread, in quel tempo Blender è completamente congelato — Windows mostra „non risponde“, macOS ingrigisce la finestra, l’utente chiude il processo.
Il pattern che abbiamo trovato:
```python class UploadThread(threading.Thread): def init(self, blend_path): super().init() self.blend_path = blend_path self.progress = 0.0 self.done = False self.result = None
def run(self):
# upload bloccante, ma nel background thread
with open(self.blend_path, 'rb') as f:
# chunked upload con progress callback
response = upload_with_progress(f, callback=lambda p: setattr(self, 'progress', p))
self.result = response
self.done = True
Timer nel main thread che polla lo stato dell’upload:
def upload_status_poll(thread): if thread.done: # valuta successo o errore, nel main thread (bpy safe) show_result_popup(thread.result) return None # None = il timer si ferma # aggiorna la progress bar (bpy.context.scene.frame_current += 0 forza un redraw) bpy.context.workspace.status_text_set(f"Upload {thread.progress:.0%}") return 0.2 # prossima call fra 200 ms ```
Il trucco è `bpy.app.timers.register(upload_status_poll)` — Blender chiama la callback nel main thread ogni 200 ms. Il background thread fa il lavoro vero, il timer comunica lo stato di ritorno. Nessun asyncio necessario, nessuna race condition su bpy.
Problema 3: chunked upload e retry
Un upload di un `.blend` da 500 MB si interrompe su WiFi instabile dopo 3 minuti con „connection reset“. L’utente deve ricominciare l’upload da zero. Alla terza volta l’add-on viene disinstallato.
Fix: chunked upload con resume token. L’upload viene diviso in blocchi da 8 MB. Ogni blocco riceve una propria richiesta HTTP PUT. Il server ricorda l’indice dell’ultimo blocco andato a buon fine. In caso di reconnect l’add-on chiede l’ultimo blocco ricevuto e riparte da lì.
Lo abbiamo implementato attraverso l’API S3-compatibile di Cloudflare R2 (il nostro storage backend) con il `Multipart Upload`. Il codice lato Blender è di ~120 righe compresa la retry logic. Lato server non serve nulla in più — R2 lo ha già integrato.
Cosa ci siamo portati a casa
- Blender 4.2+ ha un nuovo Extensions system. Il vecchio formato zip degli add-on continua a funzionare, ma i nuovi add-on dovrebbero consegnare il file manifest delle extension — così Blender può distribuire l’add-on tramite il Blender Extensions Marketplace. È il canale SEO per gli add-on Blender.
- La compatibilità di versione è un committee. Un add-on per Blender 4.2 di solito continua a funzionare su 4.3, spesso non su 5.0. Abbiamo un blocco `bl_info` che lista esplicitamente „4.2, 4.3, 4.4“ — altrimenti Blender avvisa.
- Gli utenti amano un changelog dentro l’add-on stesso. Mostriamo a ogni nuova versione un breve popup „What’s new“ al primo avvio dopo l’update. Riduce visibilmente le richieste di supporto.
Meta-lezione
Un buon add-on Blender si distingue da uno cattivo per esattamente tre dettagli: auth senza browser (Device Flow), upload senza freeze (background thread + timer callback), errori con recovery (chunked + resume). Tutti e tre sono pattern standard di distributed systems presi dal web development, ma raramente implementati in modo pulito nella community Blender. Se costruisci il tuo add-on così, ti distingui in modo visibile dal 80 % delle Cloud Integration dell’ecosistema Blender.
L’add-on completo è open source su GitHub, licenza MIT. Se stai costruendo un tuo add-on Blender e hai domande sul Device Flow o sul chunked upload — [email protected]. L’add-on è uno dei client layer di ZER0ONE Lab Cinema Render.
Stesso fuoco anche da te?
Probabilmente abbiamo già visto qualcosa di simile. Parliamone.
Iniziamo a parlarne→