Sync vs Async API

coodie provides two parallel APIs with identical functionality:

  • coodie.sync — synchronous (blocking) API

  • coodie.aio — asynchronous (async/await) API

Both share the same schema definitions, field types, and CQL builder. The only difference is whether database calls block the current thread or yield to the event loop.

Side-by-Side Comparison

Initialization

# === Sync ===
from coodie.sync import Document, init_coodie

init_coodie(hosts=["127.0.0.1"], keyspace="my_ks")

# === Async ===
from coodie.aio import Document, init_coodie

await init_coodie(hosts=["127.0.0.1"], keyspace="my_ks")

Defining Models

Models are defined the same way — the Document base class comes from different modules, but the field annotations are identical:

from coodie.fields import PrimaryKey
from typing import Annotated
from uuid import UUID, uuid4
from pydantic import Field

class User(Document):
    id: Annotated[UUID, PrimaryKey()] = Field(default_factory=uuid4)
    name: str
    email: str

    class Settings:
        name = "users"

Schema Sync

User.sync_table()                # sync
await User.sync_table()          # async

CRUD Operations

# --- Create ---
user = User(name="Alice", email="alice@example.com")
user.save()                      # sync
await user.save()                # async

# --- Read ---
user = User.get(id=some_id)             # sync
user = await User.get(id=some_id)       # async

# --- Update ---
user.update(name="Bob")                 # sync
await user.update(name="Bob")           # async

# --- Delete ---
user.delete()                    # sync
await user.delete()              # async

Querying

# --- Find all ---
users = User.find(name="Alice").all()            # sync
users = await User.find(name="Alice").all()      # async

# --- Count ---
n = User.find().count()                          # sync
n = await User.find().count()                    # async

# --- Create via QuerySet ---
User.find().create(name="Carol", email="carol@example.com")       # sync
await User.find().create(name="Carol", email="carol@example.com") # async

Batches

# --- Sync ---
from coodie.sync import BatchQuery

with BatchQuery() as batch:
    user1.save(batch=batch)
    user2.save(batch=batch)

# --- Async ---
from coodie.aio import AsyncBatchQuery

async with AsyncBatchQuery() as batch:
    await user1.save(batch=batch)
    await user2.save(batch=batch)

Raw CQL

from coodie.sync import execute_raw
rows = execute_raw("SELECT * FROM users WHERE id = ?", [some_id])

from coodie.aio import execute_raw
rows = await execute_raw("SELECT * FROM users WHERE id = ?", [some_id])

Keyspace Management

# --- Sync ---
from coodie.sync import create_keyspace, drop_keyspace
create_keyspace("my_ks", replication_factor=3)
drop_keyspace("my_ks")

# --- Async ---
from coodie.aio import create_keyspace, drop_keyspace
await create_keyspace("my_ks", replication_factor=3)
await drop_keyspace("my_ks")

What’s Shared

Both APIs share these modules — no separate sync/async versions needed:

Module

Purpose

coodie.fields

PrimaryKey, ClusteringKey, Counter, Frozen, Indexed

coodie.types

Custom CQL type mappings

coodie.schema

Schema introspection (build_schema)

coodie.cql_builder

CQL generation functions

coodie.results

LWTResult, PagedResult

coodie.exceptions

All exception classes

API Reference

Feature

coodie.sync

coodie.aio

Document

Document

Document

CounterDocument

CounterDocument

CounterDocument

MaterializedView

MaterializedView

MaterializedView

QuerySet

QuerySet

QuerySet

Batch

BatchQuery

AsyncBatchQuery

Init

init_coodie()

init_coodie() (async)

Raw CQL

execute_raw()

execute_raw() (async)

Create keyspace

create_keyspace()

create_keyspace() (async)

Drop keyspace

drop_keyspace()

drop_keyspace() (async)

When to Use Which

Scenario

Recommendation

FastAPI / aiohttp / Starlette

coodie.aio — these frameworks are async-native

Flask / Django (without async views)

coodie.sync — blocking calls match the request model

Scripts and CLI tools

coodie.sync — simpler, no event loop to manage

High-concurrency I/O

coodie.aio — concurrent queries without threads

Jupyter notebooks

Either — notebooks support await natively

Note

You can use both APIs in the same application by registering drivers with different names. However, don’t mix sync and async calls on the same driver — pick one per driver instance.

What’s Next?