Skip to content
ZERONE
Nazaj na vpoglede
Arhitekturni patterni2026-07-06 · 8 min branja

Anatomija Blender-add-ona, ki govori OAuth in REST — brez zamrznitve UI-ja

Blenderjev bpy-API teče v main threadu. Blokirni HTTP-call za 500-MB-.blend-upload pusti Blender 90 sekund „ne odziva se več“ — večina uporabnikov proces prisili v ponovni zagon. Fix je Background-Worker s Timer-Callbackom v main thread plus OAuth device flow (brez browser-callbacka).

Naš zer0one-blender-addon (na GitHubu) doda Blenderju menu `File → Send to ZER0ONE Lab`. Klik, in aktualna scena gre na Cinema-Render-backend. Prva verzija je vzela ~2 tedna — prve dni je vsaka iteracija prišla nazaj z „zakaj se Blender ne odziva več“. Trije problemi, ki jih je bilo pri tem treba rešiti, so razmeroma tipični za vse Blender-add-one, ki hočejo komunicirati z zunanjimi API-ji.

Problem 1: Auth-Flow brez browser-callbacka

Standardni OAuth-flow: uporabnik klikne „Login“, odpre se brskalnik, uporabnik na Provider-strani avtorizira, Provider redirecta nazaj na endpoint `localhost:8080/callback`, tvoja app kodo prebere iz URL-ja. Deluje za web-app-e. V Blenderju: ne — Blender ne more zanesljivo zagnati HTTP-serverja v ozadju (oziroma gre, ampak se lomi na Windows-firewall-setupih, macOS-sandboxu in nekaterih Linux-distribucijah z različnimi vrstami napak).

Čista rešitev je OAuth 2.0 Device Flow (RFC 8628). Flow:

  1. Add-on naredi `POST /oauth/device/code` s Client-ID. Server odgovori z `device_code`, `user_code`, `verification_uri`.
  2. Add-on uporabniku pokaže: „Odpri `https://zer0onelab.com/device\` v svojem brskalniku in vnesi kodo `ABCD-1234`.“ Uporabnik to naredi (na poljubni napravi — telefon, drug laptop, vseeno).
  3. Add-on poll-a `POST /oauth/token` z `device_code` vsakih 5 sekund. Server odgovarja z `authorization_pending`, dokler uporabnik ne potrdi, nato z resničnim access-tokenom.

Brez browser-callbacka, brez HTTP-serverja v Blender-procesu. Uporabnik avtorizacijo izvede na napravi po lastni izbiri. Na laptopu z lokalnim brskalnikom istega računalnika, na studio-render-mašinah, ki brskalnika nimajo, prav tako.

Opomba k implementaciji: Blenderjev embedded Python nima `requests`, a `urllib.request` zadošča za vse OAuth-klice. To prihrani dependencies-bundle-vprašanje, ki bi drugače postalo versioning-hell.

Problem 2: Async brez asyncio (ker bpy z asyncio ne igra)

Blender zaganja Python v main threadu. `bpy.ops` in vse scene-modifikacije morajo teči v main threadu — če jih poskusiš klicati iz background-threada, dobiš bodisi crash bodisi undefined behavior.

Vendar 500-MB-upload pri 100 Mbit traja ~45 sekund. Če to počneš v main threadu, je Blender v tem času trdo zamrznjen — Windows kaže „not responding“, macOS okno pobarva sivo, uporabnik proces zapre.

Vzorec, ki smo ga našli:

```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):
    # blocking upload, ampak v background-threadu
    with open(self.blend_path, 'rb') as f:
        # chunked upload s progress-callbackom
        response = upload_with_progress(f, callback=lambda p: setattr(self, 'progress', p))
    self.result = response
    self.done = True

Timer v main threadu, ki polla upload-status:

def upload_status_poll(thread): if thread.done: # ovrednoti uspeh ali napako, v main threadu (bpy safe) show_result_popup(thread.result) return None # None = Timer se ustavi # progress-bar update (bpy.context.scene.frame_current += 0 forces a redraw) bpy.context.workspace.status_text_set(f"Upload {thread.progress:.0%}") return 0.2 # naslednji call čez 200 ms ```

Trik je `bpy.app.timers.register(upload_status_poll)` — Blender callback pokliče v main threadu vsakih 200 ms. Background-thread opravi dejansko delo, timer status komunicira nazaj. Brez asyncio, brez bpy-race-condition-ov.

Problem 3: Chunked upload in retry

500-MB-.blend-upload se pri prekinjenem WLAN-u po 3 minutah prekine z „connection reset“. Uporabnik mora upload popolnoma na novo začeti. Po tretjem poskusu je add-on odinstaliran.

Fix: chunked upload z resume-tokenom. Upload je razdeljen na 8-MB-bloke. Vsak blok dobi svojo HTTP-PUT-zahtevo. Server si zapomni indeks zadnjega uspešnega bloka. Ob reconnectu add-on vpraša za zadnji sprejeti blok in začne od tam naprej.

Implementirali smo to preko S3-kompatibilnega R2-API-ja Cloudflare-a (naš storage-backend) z `Multipart Upload`. Na strani Blenderja je koda ~120 vrstic vključno z retry-logiko. Na strani serverja ni potrebno nič dodatnega — R2 ima to vgrajeno.

Kaj smo še odnesli

  • Blender 4.2+ ima nov Extensions-sistem. Stari Add-on-Zip-format še vedno deluje, a novi add-oni bi morali priložiti Extensions-Manifest-datoteko — potem lahko Blender add-on distribuira preko Blender Extensions Marketplace. To je SEO-kanal za Blender-add-one.
  • Version-kompatibilnost je committee. Add-on za Blender 4.2 v 4.3 večinoma še teče, v 5.0 pogosto ne. Imamo `bl_info`-blok, ki eksplicitno lista „4.2, 4.3, 4.4“ — Blender sicer opozarja.
  • Uporabniki obožujejo change-log v samem add-onu. Pri vsaki novi verziji pri prvem zagonu po posodobitvi pokažemo kratek „What's new“-popup. Vidno zmanjša support-vprašanja.

Meta-lekcija

Dober Blender-add-on se od slabega razlikuje v točno treh detajlih: auth brez brskalnika (device flow), uploads brez freeze-a (background-thread + timer-callback), napake z recovery-jem (chunked + resume). Vsi trije so standardni distributed-systems-vzorci iz web-developmenta, ampak v Blender-skupnosti redko čisto implementirani. Če svoj add-on tako zgradiš, se vidno dvigneš nad 80 % cloud-integracij v Blender-ekosistemu.

Celoten add-on je open source na GitHubu, MIT-licenciran. Če sam gradiš Blender-add-on in imaš vprašanja o device-flow-u ali chunked-uploadu — [email protected]. Add-on je eden izmed client-layerjev ZER0ONE Lab Cinema Render.

Podoben izziv tudi pri vas?

Verjetno smo že videli kaj podobnega. Pogovorimo se.

Začnimo pogovor