1:"$Sreact.fragment"
2:I[75473,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
3:I[78515,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
4:I[30687,["/_next/static/chunks/fd0661f1506dcbc6.js"],"Toaster"]
5:I[61076,["/_next/static/chunks/fd0661f1506dcbc6.js"],"Analytics"]
7:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"OutletBoundary"]
8:"$Sreact.suspense"
a:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"ViewportBoundary"]
c:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"MetadataBoundary"]
e:I[90849,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
:HL["/_next/static/chunks/609ea7bc18d0d15f.css","style"]
:HL["/_next/static/chunks/93b606aa9fdccd13.css","style"]
:HL["/_next/static/media/797e433ab948586e-s.p.479bea2b.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
:HL["/_next/static/media/caa3a2e1cccd8315-s.p.3b6cae6d.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
0:{"P":null,"b":"TlpKRvbES4zzM7LeczAM7","c":["","blog","asyncio-sync-hooks"],"q":"","i":false,"f":[[["",{"children":["blog",{"children":[["slug","asyncio-sync-hooks","d"],{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/609ea7bc18d0d15f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/chunks/93b606aa9fdccd13.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/fd0661f1506dcbc6.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":[["$","head",null,{"children":[["$","script",null,{"async":true,"src":"https://www.googletagmanager.com/gtag/js?id=AW-18009878040"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"\n          window.dataLayer = window.dataLayer || [];\n          function gtag(){dataLayer.push(arguments);}\n          gtag('js', new Date());\n          gtag('config', 'AW-18009878040');\n          gtag('config', 'G-W3XKYXV2SG');\n\n          // Persist UTM and gclid params to sessionStorage for cross-page tracking\n          (function() {\n            var params = new URLSearchParams(window.location.search);\n            var keys = ['utm_source','utm_medium','utm_campaign','utm_content','utm_term','gclid'];\n            keys.forEach(function(k) {\n              var v = params.get(k);\n              if (v) sessionStorage.setItem(k, v);\n            });\n          })();\n        "}}]]}],["$","body",null,{"className":"font-sans antialiased","children":[["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}],["$","$L4",null,{"position":"top-center","richColors":true,"toastOptions":{"style":{"background":"var(--popover)","color":"var(--popover-foreground)","border":"1px solid var(--border)"}}}],["$","$L5",null,{}]]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":["$L6",[["$","script","script-0",{"src":"/_next/static/chunks/94245cbda44972fe.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/af778fff4a0f4be6.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/b096b037d08e2f31.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"children":["$","$8",null,{"name":"Next.MetadataOutlet","children":"$@9"}]}]]}],{},null,false,false]},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$La",null,{"children":"$Lb"}],["$","div",null,{"hidden":true,"children":["$","$Lc",null,{"children":["$","$8",null,{"name":"Next.Metadata","children":"$Ld"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$e",[]],"S":true}
f:I[15579,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Navigation"]
10:I[3013,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],""]
:HL["/blog/posts/asyncio-sync-hooks/hero.jpg","image"]
:HL["/blog/posts/logo.png","image"]
6:[["$","$Lf",null,{}],["$","main",null,{"className":"pt-20 md:pt-24","children":["$","article",null,{"children":[["$","header",null,{"className":"border-b border-border","children":["$","div",null,{"className":"container mx-auto px-6 py-14 md:py-20","children":[["$","$L10",null,{"href":"/blog","className":"mb-8 inline-flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-foreground","children":[["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-left mr-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1l729n",{"d":"m12 19-7-7 7-7"}],["$","path","x3x0zl",{"d":"M19 12H5"}],"$undefined"]}],"Blog"]}],["$","div",null,{"className":"grid gap-8 md:grid-cols-[1fr_0.9fr] md:items-start","children":[["$","div",null,{"className":"max-w-3xl","children":[["$","div",null,{"className":"mb-5 flex flex-wrap items-center gap-3 text-sm text-muted-foreground","children":[["$","span",null,{"className":"rounded-md border border-primary/40 bg-primary/10 px-2.5 py-1 text-primary","children":"Concurrency"}],["$","span",null,{"children":"2026-W20"}],["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":"3 min read"}],[["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":["by ",["$","span",null,{"className":"font-medium text-foreground","children":"chip"}]]}]]]}],["$","h1",null,{"className":"text-4xl font-bold leading-tight text-balance md:text-6xl","children":"Calling Coroutines from Sync Hooks"}],["$","p",null,{"className":"mt-6 text-lg leading-relaxed text-muted-foreground md:text-xl","children":"Calling async code from a sync callback raises `RuntimeError` inside a running event loop. The fix branches on `asyncio.get_running_loop()` — fire-and-forget if a loop exists, `asyncio.run()` if it doesn't."}]]}],["$","div",null,{"className":"overflow-hidden rounded-lg border border-border bg-card","children":["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden","children":[null,["$","img",null,{"src":"/blog/posts/asyncio-sync-hooks/hero.jpg","alt":"A simple wooden footbridge spanning a small stream in a forest clearing, soft morning fog.","className":"h-full w-full object-cover"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-4 top-4 h-[50px] w-[50px] mix-blend-screen"}]]}]}]]}]]}]}],["$","div",null,{"className":"container mx-auto px-6 py-12 md:py-16","children":["$","div",null,{"className":"grid gap-10 lg:grid-cols-[minmax(0,1fr)_280px] lg:items-start","children":[["$","div",null,{"className":"max-w-3xl text-muted-foreground","children":[[["$","h2","h2-0",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The problem"}],"\n",["$","p","p-0",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["You have a sync callback hook — LiteLLM's ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"log_success_event"}],", a Django signal handler, a Celery task — and you need to call async code from it. The standard advice is ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"asyncio.get_event_loop().run_until_complete(coro)"}],", but this raises ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"RuntimeError: This event loop is already running"}]," when called from inside a running async context, which is exactly where these hooks fire."]}],"\n",["$","h2","h2-1",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The approach"}],"\n",["$","p","p-1",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"The correct pattern depends on whether you're inside a running event loop or not:"}],"\n","$L11","\n","$L12","\n","$L13","\n","$L14","\n","$L15","\n","$L16"],"$L17",null]}],"$L18"]}]}]]}]}],"$L19"]
36:I[41451,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Footer"]
11:["$","div","pre-0",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["def"]}],["$","span","code-segment-1",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-2",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["_dispatch_sync"]}],["$","span","code-segment-3",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-4",{"className":"$undefined","style":{},"children":["self"]}],["$","span","code-segment-5",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[","]}],["$","span","code-segment-6",{"className":"$undefined","style":{},"children":[" coro"]}],["$","span","code-segment-7",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-8",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-9",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["-"]}],["$","span","code-segment-10",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":[">"]}],["$","span","code-segment-11",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-12",{"className":"token","style":{"color":"hsl(29, 54%, 61%)"},"children":["None"]}],["$","span","code-segment-13",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}],["$","span","code-segment-14",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-15",{"className":"$undefined","style":{},"children":["    "]}],["$","span","code-segment-16",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["import"]}],["$","span","code-segment-17",{"className":"$undefined","style":{},"children":[" asyncio\n"]}],["$","span","code-segment-18",{"className":"$undefined","style":{},"children":["    "]}],["$","span","code-segment-19",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["try"]}],["$","span","code-segment-20",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}],["$","span","code-segment-21",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-22",{"className":"$undefined","style":{},"children":["        loop "]}],["$","span","code-segment-23",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-24",{"className":"$undefined","style":{},"children":[" asyncio"]}],["$","span","code-segment-25",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-26",{"className":"$undefined","style":{},"children":["get_running_loop"]}],["$","span","code-segment-27",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-28",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-29",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-30",{"className":"$undefined","style":{},"children":["    "]}],["$","span","code-segment-31",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["except"]}],["$","span","code-segment-32",{"className":"$undefined","style":{},"children":[" RuntimeError"]}],["$","span","code-segment-33",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}],["$","span","code-segment-34",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-35",{"className":"$undefined","style":{},"children":["        loop "]}],["$","span","code-segment-36",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-37",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-38",{"className":"token","style":{"color":"hsl(29, 54%, 61%)"},"children":["None"]}],["$","span","code-segment-39",{"className":"$undefined","style":{},"children":["\n"]}],"$L1a","$L1b","$L1c","$L1d","$L1e","$L1f","$L20","$L21","$L22","$L23","$L24","$L25","$L26","$L27","$L28","$L29","$L2a","$L2b","$L2c","$L2d","$L2e","$L2f","$L30","$L31","$L32","$L33","$L34"]]}]}]
12:["$","p","p-2",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":[["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"asyncio.get_running_loop()"}]," raises ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"RuntimeError"}]," if there's no running loop (not deprecated, safe to use). If a loop is running, ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"create_task"}]," schedules the coroutine without blocking. If there's no running loop (pure sync context), ",["$","code","code-3",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"asyncio.run()"}]," spins one up."]}]
13:["$","p","p-3",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The tradeoff: ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"create_task"}]," is fire-and-forget. If the coroutine raises, the exception lands in the event loop's exception handler, not your caller. For logging hooks where you want best-effort delivery and don't want to block, this is the right choice. For anything where you need the result or need to guarantee delivery, you need a different pattern (thread pool, queue, or refactor to async)."]}]
14:["$","h2","h2-2",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"What I learned"}]
15:["$","p","p-4",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":[["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"asyncio.get_event_loop()"}]," is the source of most of the confusion here — it creates a new loop in some contexts and returns the running one in others, and its behavior changed across Python versions. ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"get_running_loop()"}]," is unambiguous: it either returns the running loop or raises. Use that and branch on the result."]}]
16:["$","p","p-5",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The other thing: LiteLLM provides async variants of all sync hooks (",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"async_log_success_event"}],"). If you control the hook registration, prefer those. The sync-to-async bridge is only necessary when you're forced into the sync API."]}]
17:["$","div",null,{"className":"mt-14 border-t border-border pt-8","children":["$","$L10",null,{"href":"/platform","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Start a build",["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]]}]}]
18:["$","aside",null,{"className":"hidden lg:block","children":["$","div",null,{"className":"sticky top-24 space-y-4","children":[["$","h3",null,{"className":"text-xs font-semibold uppercase tracking-wider text-primary","children":["More in ","Concurrency"]}],["$","div",null,{"className":"space-y-4","children":[["$","$L10","bcrypt-async-event-loop",{"href":"/blog/bcrypt-async-event-loop","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/bcrypt-async-event-loop/hero.jpg","alt":"A solitary traffic light glowing red over an empty asphalt road at dusk, no cars, no people, sharp editorial photography.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Concurrency"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W20"," · ","4 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"bcrypt in an Async Codebase — The Three Places It Bites You"}]]}]]}],["$","$L10","toctou-async-database-handlers",{"href":"/blog/toctou-async-database-handlers","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/toctou-async-database-handlers/hero.jpg","alt":"A close-up macro shot of two identical brass keys sliding into the same antique brass door lock simultaneously against a dark wooden door, dramatic side lighting, no people, sharp editorial focus.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Concurrency"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W20"," · ","4 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"TOCTOU Races in Async Database Handlers"}]]}]]}],["$","$L10","async-sqlite-fastapi",{"href":"/blog/async-sqlite-fastapi","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/async-sqlite-fastapi/hero.jpg","alt":"A single brass funnel on a worn wooden workbench with one droplet caught mid-fall above its narrow neck, sharp focus on the droplet, soft side light, no people, editorial.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Concurrency"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W20"," · ","4 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Blocking SQLite in an Async FastAPI Route"}]]}]]}]]}],["$","$L10",null,{"href":"/blog?category=concurrency","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Read all in ","Concurrency","$L35"]}]]}]}]
19:["$","$L36",null,{}]
1a:["$","span","code-segment-40",{"className":"$undefined","style":{},"children":["    "]}]
1b:["$","span","code-segment-41",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["if"]}]
1c:["$","span","code-segment-42",{"className":"$undefined","style":{},"children":[" loop "]}]
1d:["$","span","code-segment-43",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["is"]}]
1e:["$","span","code-segment-44",{"className":"$undefined","style":{},"children":[" "]}]
1f:["$","span","code-segment-45",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["not"]}]
20:["$","span","code-segment-46",{"className":"$undefined","style":{},"children":[" "]}]
21:["$","span","code-segment-47",{"className":"token","style":{"color":"hsl(29, 54%, 61%)"},"children":["None"]}]
22:["$","span","code-segment-48",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}]
23:["$","span","code-segment-49",{"className":"$undefined","style":{},"children":["\n"]}]
24:["$","span","code-segment-50",{"className":"$undefined","style":{},"children":["        loop"]}]
25:["$","span","code-segment-51",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}]
26:["$","span","code-segment-52",{"className":"$undefined","style":{},"children":["create_task"]}]
27:["$","span","code-segment-53",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}]
28:["$","span","code-segment-54",{"className":"$undefined","style":{},"children":["coro"]}]
29:["$","span","code-segment-55",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}]
2a:["$","span","code-segment-56",{"className":"$undefined","style":{},"children":["\n"]}]
2b:["$","span","code-segment-57",{"className":"$undefined","style":{},"children":["    "]}]
2c:["$","span","code-segment-58",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["else"]}]
2d:["$","span","code-segment-59",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}]
2e:["$","span","code-segment-60",{"className":"$undefined","style":{},"children":["\n"]}]
2f:["$","span","code-segment-61",{"className":"$undefined","style":{},"children":["        asyncio"]}]
30:["$","span","code-segment-62",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}]
31:["$","span","code-segment-63",{"className":"$undefined","style":{},"children":["run"]}]
32:["$","span","code-segment-64",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}]
33:["$","span","code-segment-65",{"className":"$undefined","style":{},"children":["coro"]}]
34:["$","span","code-segment-66",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}]
35:["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]
b:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
37:I[94060,["/_next/static/chunks/316a3a63422f35de.js"],"IconMark"]
9:null
d:[["$","title","0",{"children":"Calling Coroutines from Sync Hooks — Bridgestack"}],["$","meta","1",{"name":"description","content":"Calling async code from a sync callback raises `RuntimeError` inside a running event loop. The fix branches on `asyncio.get_running_loop()` — fire-and-forget if a loop exists, `asyncio.run()` if it doesn't."}],["$","meta","2",{"name":"generator","content":"v0.app"}],["$","meta","3",{"property":"og:title","content":"Bridgestack — custom software, flat prices from $9.99"}],["$","meta","4",{"property":"og:description","content":"Talk to Tom, your AI PM. A fleet of AI agents builds your product. Flat one-time price. 7 days to test before you pay. Source code is yours."}],["$","meta","5",{"property":"og:url","content":"https://www.bridgestack.systems"}],["$","meta","6",{"property":"og:site_name","content":"Bridgestack"}],["$","meta","7",{"property":"og:locale","content":"en_US"}],["$","meta","8",{"property":"og:image","content":"https://www.bridgestack.systems/bridgestack-landscape-1200x628.png"}],["$","meta","9",{"property":"og:image:width","content":"1200"}],["$","meta","10",{"property":"og:image:height","content":"628"}],["$","meta","11",{"property":"og:type","content":"website"}],["$","meta","12",{"name":"twitter:card","content":"summary_large_image"}],["$","meta","13",{"name":"twitter:title","content":"Bridgestack — custom software, flat prices from $9.99"}],["$","meta","14",{"name":"twitter:description","content":"Talk to Tom, your AI PM. A fleet of AI agents builds your product. 7 days to test before you pay. Source code is yours."}],["$","meta","15",{"name":"twitter:image","content":"https://www.bridgestack.systems/bridgestack-landscape-1200x628.png"}],["$","link","16",{"rel":"icon","href":"/icon-light-32x32.png","media":"(prefers-color-scheme: light)"}],["$","link","17",{"rel":"icon","href":"/icon-dark-32x32.png","media":"(prefers-color-scheme: dark)"}],["$","link","18",{"rel":"icon","href":"/icon.svg","type":"image/svg+xml"}],["$","link","19",{"rel":"apple-touch-icon","href":"/apple-icon.png"}],["$","$L37","20",{}]]
