Skip to content
ZERONE
Natrag na uvide
Arhitektonski patterni2026-07-06 · 8 min čitanja

Anatomija Blender add-ona koji priča OAuth i REST — bez zamrzavanja UI-ja

Blenderov bpy API radi u main threadu. Blokirajući HTTP-poziv za 500 MB .blend upload ostavlja Blender „ne odgovara" 90 sekundi — a većina korisnika onda prisili proces na restart. Fix je background-worker s timer-callbackom u main thread, plus OAuth Device Flow (bez browser-callbacka).

Naš zer0one-blender-addon (na GitHubu) dodaje Blenderu izbornik `File → Send to ZER0ONE Lab`. Klik, i aktualna scena šalje se na Cinema-Render-backend. Prva verzija trebala je ~2 tjedna — prvih dana svaka iteracija vratila se sa „zašto Blender više ne odgovara". Tri problema koja je pritom trebalo riješiti prilično su tipična za sve Blender-add-one koji žele razgovarati s vanjskim API-jima.

Problem 1: Auth-Flow bez browser-callbacka

Standardni OAuth-Flow: user klikne „Login", browser se otvori, user autorizira na provider-siteu, provider redirecta natrag na `localhost:8080/callback` endpoint, tvoja app čita code iz URL-a. Radi za web-appove. U Blenderu: ne — Blender u pozadini ne može pouzdano pokrenuti HTTP-server (odnosno može, ali puca na Windows-firewall-setupovima, macOS-sandboxu i pojedinim Linux-distribucijama s različitim tipovima grešaka).

Čisto rješenje je OAuth 2.0 Device Flow (RFC 8628). Flow:

  1. Add-on radi `POST /oauth/device/code` s Client-ID-om. Server odgovara sa `device_code`, `user_code`, `verification_uri`.
  2. Add-on korisniku pokazuje: „Otvori `https://zer0onelab.com/device\` u svojem browseru i unesi kod `ABCD-1234`." User to napravi (na bilo kojem uređaju — mobitel, drugi laptop, svejedno).
  3. Add-on polla `POST /oauth/token` s `device_code`-om svakih 5 sekundi. Server odgovara `authorization_pending` dok korisnik ne potvrdi, zatim pravim Access-Tokenom.

Bez browser-callbacka, bez HTTP-servera u Blender-procesu. User autorizaciju radi na uređaju po vlastitom izboru. Na laptopu s lokalnim browserom istog stroja, na studio-render-mašinama koje nemaju browser — jednako.

Napomena o implementaciji: Blenderov ugrađeni Python nema `requests`, ali `urllib.request` je dovoljan za sve OAuth pozive. To štedi pitanje dependency-bundlea koje inače postaje versioning-hell.

Problem 2: Async bez asyncija (jer bpy ne trpi asyncio)

Blender startaje Python u main threadu. `bpy.ops` i sve scene-modifikacije moraju ići u main threadu — ako ih pokušaš pozvati iz background threada, dobivaš ili crash ili undefined behavior.

Ali 500 MB upload na 100 Mbit-a traje otprilike 45 sekundi. Ako to radiš u main threadu, Blender je za to vrijeme tvrdo zamrznut — Windows pokazuje „not responding", macOS obojava prozor sivo, user zatvara proces.

Pattern koji smo pronaš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, ali u 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 u main threadu koji polla upload-status:

def upload_status_poll(thread): if thread.done: # uspjeh ili grešku obraditi, u main threadu (bpy safe) show_result_popup(thread.result) return None # None = timer staje # progress-bar updateati (bpy.context.scene.frame_current += 0 forsira redraw) bpy.context.workspace.status_text_set(f"Upload {thread.progress:.0%}") return 0.2 # sljedeći poziv za 200 ms ```

Trik je `bpy.app.timers.register(upload_status_poll)` — Blender poziva callback u main threadu, svakih 200 ms. Background-thread radi stvarni posao, timer komunicira status natrag. Bez asyncija, bez bpy race-conditiona.

Problem 3: Chunked Upload i Retry

500 MB .blend upload puca kod prekinutog WLAN-a nakon 3 minute s „connection reset". Korisnik mora upload potpuno ispočetka. Nakon trećeg puta add-on se deinstalira.

Fix: Chunked-Upload s Resume-Tokenom. Upload se dijeli u blokove od 8 MB. Svaki blok dobiva vlastiti HTTP-PUT-request. Server pamti index posljednjeg uspješnog bloka. Kod reconnecta add-on pita za posljednji primljeni blok i pokreće od toga dalje.

Implementirali smo to preko S3-kompatibilnog R2 API-ja Cloudflarea (naš storage-backend) s `Multipart Uploadom`. Sa strane Blendera kod je ~120 linija uključujući retry-logiku. Sa strane servera ne treba ništa dodatno — R2 to ima ugrađeno.

Što smo još pritom uzeli

  • Blender 4.2+ ima novi Extensions-sustav. Stari add-on-zip-format i dalje radi, ali novi add-oni trebali bi isporučivati extensions-manifest-datoteku — tada Blender može add-on distribuirati preko Blender Extensions Marketplacea. To je SEO-kanal za Blender-add-one.
  • Kompatibilnost verzija je odbor. Add-on za Blender 4.2 u 4.3 uglavnom radi, u 5.0 često ne. Imamo `bl_info` blok koji eksplicitno navodi „4.2, 4.3, 4.4" — Blender inače upozorava.
  • Korisnici vole changelog u samom add-onu. Pokazujemo kod svake nove verzije kratki „What's new" popup kod prvog pokretanja nakon updatea. Vidljivo smanjuje broj support-upita.

Meta-lekcija

Dobar Blender-add-on razlikuje se od lošeg u točno tri detalja: Auth bez browsera (Device Flow), Uploadi bez freezea (background-thread + timer-callback), Greške s recoveryjem (Chunked + Resume). Sva tri su standardni distributed-systems patterni iz web-developmenta, ali u Blender zajednici rijetko su čisto implementirani. Ako svoj add-on tako izgradiš, vidljivo se izdvajaš od 80 % cloud-integracija u Blender ekosustavu.

Kompletan add-on je open source na GitHubu, MIT-licenciran. Ako sam gradiš Blender-add-on i imaš pitanja o Device Flowu ili chunked uploadu — [email protected]. Add-on je jedan od klijentskih slojeva ZER0ONE Lab Cinema Rendera.

Sličan izazov i kod vas?

Vjerojatno smo već vidjeli nešto slično. Razgovarajmo.

Započnite razgovor