Skip to main content

Add your description here

Project description

ame-json

ame-json is a Python library that enables progressive streaming of JSON data. It's built on top of pydantic and allows you to define a schema with Computation fields. These fields are populated by functions (which can be synchronous or asynchronous) that are executed as their data is needed, and the results are streamed to the client. This is particularly useful for applications where parts of the JSON response are slow to generate, as it allows the client to receive and process the faster parts of the response without waiting for the entire payload.

Features

  • Progressive Streaming: Stream complex JSON objects as they are constructed.
  • Layered Streaming: Nested objects are streamed layer by layer, allowing the client to process data as it arrives.
  • Pydantic Integration: Define your data models using pydantic.
  • Sync and Async Support: Works with both synchronous and asynchronous code.
  • Computable Fields: Defer slow computations and stream their results.

Installation

pip install ame-json

Quick Start

Here's a simple example of how to use ame-json to stream a JSON object with a computed field and a nested object.

import time
from pydantic import BaseModel
from ame_json.models.progressive_schema import ProgressiveSchema
from ame_json.models.computation import Computation

# 1. Define your data models using Pydantic
class Product(BaseModel):
    name: str
    price: float

class Address(BaseModel):
    street: str
    city: str

def get_user_products() -> list[Product]:
    """Simulates a slow database call."""
    time.sleep(2)
    return [
        Product(name="Laptop Bag", price=45.00),
        Product(name="Monitor", price=350.50),
    ]

# 2. Create a ProgressiveSchema for the streaming response
class UserProfile(ProgressiveSchema):
    user_id: int
    username: str
    address: Address
    products: Computation[list[Product]]

# 3. Instantiate your schema with data and computations
user_profile = UserProfile(
    user_id=101,
    username="jdoe",
    address=Address(street="123 Main St", city="Anytown"),
    products=Computation(get_user_products),
)

# 4. Create a streamer and iterate through the stream
streamer = user_profile.to_streamer()

for chunk in streamer.stream():
    print(chunk.decode(), end="")

Async Quick Start

ame-json also provides full support for asynchronous operations using Python's asyncio. This is ideal for applications that need to perform non-blocking I/O operations, such as fetching data from a database or an external API asynchronously.

Here's how you can use ame-json with async/await:

import asyncio
from pydantic import BaseModel
from ame_json.models.async_progressive_schema import AsyncProgressiveSchema
from ame_json.models.async_computation import AsyncComputation

# 1. Define your data models as usual
class Product(BaseModel):
    name: str
    price: float

class Address(BaseModel):
    street: str
    city: str

async def get_user_products() -> list[Product]:
    """Simulates a slow async database call."""
    await asyncio.sleep(2)
    return [
        Product(name="Laptop Bag", price=45.00),
        Product(name="Monitor", price=350.50),
    ]

# 2. Use AsyncProgressiveSchema for the streaming response
class UserProfile(AsyncProgressiveSchema):
    user_id: int
    username: str
    address: Address
    products: AsyncComputation[list[Product]]

# 3. Instantiate your schema with async computations
user_profile = UserProfile(
    user_id=101,
    username="jdoe",
    address=Address(street="123 Main St", city="Anytown"),
    products=AsyncComputation(get_user_products),
)

# 4. Create an async streamer and iterate through the stream
async def main():
    streamer = user_profile.to_streamer()
    async for chunk in streamer.stream():
        print(chunk.decode(), end="")

if __name__ == "__main__":
    asyncio.run(main())

The async equivalent of ProgressiveSchema is AsyncProgressiveSchema, and Computation is AsyncComputation. The AsyncComputation class is designed to wrap an async function, and the AsyncProgressiveJSONStreamer will await it during the streaming process.

The streaming process remains the same, but the iteration over the stream is now done asynchronously with async for.

How It Works

The streaming process works by breaking down the JSON object into layers. Each nested object or Computation field represents a new layer that is streamed separately.

The core of ame-json is the ProgressiveSchema and the Computation class.

  • ProgressiveSchema: A pydantic.BaseModel subclass that can have fields of type Computation and nested pydantic models.
  • Computation: A generic type that you wrap around a callable. ame-json will execute this callable to compute the value of the field during the streaming process.

When you create a ProgressiveJSONStreamer from a ProgressiveSchema instance, it starts serializing the object into JSON.

  1. It first sends the top-level fields of the main object.
  2. When it encounters a nested pydantic model, it sends a placeholder and adds the nested object to a queue to be processed in a subsequent layer.
  3. When it encounters a Computation field, it also sends a placeholder and starts executing the callable to compute the value.

The streamer then processes the queue, sending the content of each nested object and the results of each computation as separate chunks in the stream, each replacing its placeholder. This allows a client to parse and use the initial data immediately and then progressively render the more complex, nested, or computed parts of the JSON as they arrive.

Development

To set up the development environment:

# Clone the repository
git clone https://github.com/nasrak62/ame-json.git
cd ame-json

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -e ".[dev]"

# Run tests
pytest

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ame_json-0.2.0.tar.gz (14.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ame_json-0.2.0-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file ame_json-0.2.0.tar.gz.

File metadata

  • Download URL: ame_json-0.2.0.tar.gz
  • Upload date:
  • Size: 14.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for ame_json-0.2.0.tar.gz
Algorithm Hash digest
SHA256 351bb8c5d0eea142874a9b9cf29cb80499e392696c97fffd203e6b3304e21583
MD5 6711d40cc8632f9b2fcaf6af4039cc71
BLAKE2b-256 88c1e41a0707a6b81ee118162efcee8f506d0ee22b67d703dc2a9c45a2cd1696

See more details on using hashes here.

File details

Details for the file ame_json-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ame_json-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for ame_json-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0a7c1fe87e38c257513a9caee06074b9919651a67d2214303e4d0a5486199a11
MD5 1bdd55103ca6494f904ab5ea3c5baa49
BLAKE2b-256 26a975951e612a5184c09a229e2dc670c39d05015125f21a5e738e2d381b94c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page