← Back to Blog

FastAPI + Svelte: typed Python procedures as Svelte stores

·9 min read

Svelte's store contract fits TanStack Svelte Query naturally, every createQuery call returns a store you subscribe to with the $ prefix. @pyrpc/svelte puts typed procedure wrappers on top of that, so you get full inference from Python to Svelte template with no glue code.

Client setup

// src/lib/pyrpc.ts
import { createSvelteClient } from "@pyrpc/svelte"
import type { Types } from "@pyrpc/types"

export const api = createSvelteClient<Types>({
  baseUrl: import.meta.env.VITE_API_URL ?? "http://localhost:8000",
})
<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import { QueryClient, QueryClientProvider } from "@tanstack/svelte-query"
  const queryClient = new QueryClient()
</script>

<QueryClientProvider client={queryClient}>
  <slot />
</QueryClientProvider>

Using the stores

<!-- src/routes/+page.svelte -->
<script lang="ts">
  import { api } from "$lib/pyrpc"

  let name = ""

  const greeting = api.read_root.createQuery()
  const item = api.read_item.createQuery(() => ({ item_id: 42, q: "test" }))
  const createItem = api.create_item.createMutation()

  function handleCreate() {
    if (name.trim()) {
      $createItem.mutate({ name, description: `Item: ${name}` })
      name = ""
    }
  }
</script>

{#if $greeting.isPending}
  <p>Loading…</p>
{:else}
  <pre>{JSON.stringify($greeting.data)}</pre>
{/if}

<pre>{JSON.stringify($item.data)}</pre>

<input bind:value={name} placeholder="Item name" />
<button on:click={handleCreate} disabled={$createItem.isPending}>
  {$createItem.isPending ? "Creating…" : "Create"}
</button>

{#if $createItem.isSuccess}
  <pre>{JSON.stringify($createItem.data)}</pre>
{/if}

Key Svelte patterns

Store subscription. Prefix stores with $ to read their current value, both in the template and in <script>.

Reactive args. Pass a getter function to createQuery when args depend on reactive state. The query re-fetches whenever the getter returns a new value.

Run it

# Terminal 1
cd server && uv add pyrpc-core[fastapi] && pyrpc dev

# Terminal 2
cd client && npm install && npm run dev

Open http://localhost:5173. Full source at examples/fastapi-svelte.