jsonversation
A Python library for streaming JSON parsing that enables real-time processing of JSON data as it arrives. Perfect for handling large JSON responses, streaming APIs, or any scenario where you need to process JSON data progressively.
Installation
Coming soon!
Key Features
- Streaming JSON Parsing: Process JSON data as it arrives, without waiting for complete payloads
- Type-Safe Models: Define strongly-typed data structures with automatic validation
- Real-time Callbacks: React to data changes as they happen with customizable callbacks
- Progressive Updates: Handle partial JSON data and incremental updates seamlessly
Quick Start
Basic Usage
import jsonversation as jv
# Define your data structure
class ChatMessage(jv.Object):
role: jv.String
content: jv.String
timestamp: jv.String
token_count: jv.Atomic[int]
is_complete: jv.Atomic[bool]
# Create a parser
message = ChatMessage()
# Process streaming JSON data
json_chunk1 = '{"role": "assistant", "content": "Hello'
json_chunk2 = ' world!", "timestamp": "2024-01-01T12:00:00Z", "token_count": 42, "is_complete": true}'
with jv.Parser(message) as parser:
parser.push(json_chunk1)
print(message.content.get_value()) # "Hello"
parser.push(json_chunk2)
print(message.content.get_value()) # "Hello world!"
print(message.role.get_value()) # "assistant"
print(message.token_count.get_value()) # 42
print(message.is_complete.get_value()) # True
Real-time Callbacks
import jsonversation as jv
class StreamingResponse(jv.Object):
message: jv.String
tokens: jv.List[jv.String]
response = StreamingResponse()
# Set up real-time callbacks
def on_message_update(chunk: str):
print(f"New text: {chunk}")
def on_new_token(token: jv.String):
print(f"New token: {token.get_value()}")
def on_message_complete(full_message: str):
print(f"Complete message: {full_message}")
response.message.on_append(on_message_update)
response.tokens.on_append(on_new_token)
response.message.on_complete(on_message_complete)
# Simulate streaming data
with jv.Parser(response) as parser:
parser.push('{"message": "The quick')
parser.push(' brown fox", "tokens": ["The", "quick"]}')
Working with Atomic Types
The Atomic class handles primitive types that arrive as complete values rather than streaming text:
import jsonversation as jv
class APIResponse(jv.Object):
message: jv.String
status_code: jv.Atomic[int]
success: jv.Atomic[bool]
response_time: jv.Atomic[float]
response = APIResponse()
# Set up callbacks for atomic values
def on_status_change(status: int | None):
if status:
print(f"Status code: {status}")
if status >= 400:
print("Error response detected!")
def on_completion(success: bool | None):
if success is not None:
print(f"Request {'succeeded' if success else 'failed'}")
response.status_code.on_complete(on_status_change)
response.success.on_complete(on_completion)
# Process JSON with atomic values
with jv.Parser(response) as parser:
parser.push('{"message": "Request completed", "status_code": 200')
parser.push(', "success": true, "response_time": 1.23}')
# Callbacks will be triggered when atomic values are completed
print(response.status_code.get_value()) # 200
print(response.success.get_value()) # True
print(response.response_time.get_value()) # 1.23
Complex Nested Structures
import jsonversation as jv
class Author(jv.Object):
name: jv.String
email: jv.String
class Comment(jv.Object):
id: jv.String
text: jv.String
author: Author
class BlogPost(jv.Object):
title: jv.String
content: jv.String
author: Author
comments: jv.List[Comment]
tags: jv.List[jv.String]
# Create and use the parser
post = BlogPost()
# Process complex JSON
complex_json = """
{
"title": "Streaming JSON in Python",
"content": "This is a comprehensive guide...",
"author": {
"name": "Jane Doe",
"email": "jane@example.com"
},
"comments": [
{
"id": "1",
"text": "Great article!",
"author": {
"name": "John Smith",
"email": "john@example.com"
}
}
],
"tags": ["python", "json", "streaming"]
}
"""
with jv.Parser(post) as parser:
parser.push(complex_json)
# Access nested data
print(post.title.get_value()) # "Streaming JSON in Python"
print(post.author.name.get_value()) # "Jane Doe"
print(post.comments.get_value()[0].text.get_value()) # "Great article!"
print([tag.get_value for tag in post.tags.get_value()]) # ["python", "json", "streaming"]
AsyncIO
Jsonversation supports async callbacks as well. The API is very similar between the sync/async classes, with the only difference being that the async module supports async callback functions.
Example
import asyncio
import jsonversation.aio as jv
class StreamingResponse(jv.Object):
message: jv.String
tokens: jv.List[jv.String]
response = StreamingResponse()
# Set up real-time callbacks
async def on_message_update(chunk: str):
await asyncio.sleep(0.001)
print(f"New text: {chunk}")
async def on_new_token(token: jv.String):
await asyncio.sleep(0.001)
print(f"New token: {token.get_value()}")
async def on_message_complete(full_message: str):
await asyncio.sleep(0.001)
print(f"Complete message: {full_message}")
response.message.on_append(on_message_update)
response.tokens.on_append(on_new_token)
response.message.on_complete(on_message_complete)
async def run():
async with jv.Parser(response) as parser:
await parser.push('{"message": "The quick')
await parser.push(' brown fox", "tokens": ["The", "quick"]}')
asyncio.run(run())
API Reference
Core Classes
-
Parser(obj: Object)Main parser class for processing streaming JSON data.
Methods:
push(chunk: str)- Process a chunk of JSON data
-
ObjectBase class for defining structured data models.
Methods:
update(value: dict)- Update object with dictionary data
-
StringString field type with streaming capabilities.
Properties:
value- Get current string value
Methods:
on_append(callback)- Register callback for new text chunkson_complete(callback)- Register callback for completionupdate(value: str)- Update with new string value
-
List[T]List field type for collections of items.
Properties:
value- Get current list of items
Methods:
on_append(callback)- Register callback for new itemson_complete(callback)- Register callback for completionupdate(value: list)- Update with new list data
Requirements
- Python 3.9+
- jiter (for JSON parsing)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
Metadata
Release files for jsonversation 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jsonversation-0.1.3.tar.gz | 8.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jsonversation-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.5 kB
Release files / jsonversation-0.1.3.tar.gz
| Download URL | jsonversation-0.1.3.tar.gz |
|---|---|
| Size | 8.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
735db7528f0e2a3887e02ee97c356fd63b12df2371c82a45ef25826b759e26fa
|
|
BLAKE2b-256 checksum How to use checksums |
f0796e861247710152893b48f77d4fe47bc3ac0e5e155afba042483e2a44c502
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2025.
Transparency logRelease files / jsonversation-0.1.3-py3-none-any.whl
| Download URL | jsonversation-0.1.3-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b7d9e86c6b5e6843e5d154e4f35300e6ef5e6c7b377ea949d12a9a42b742ac8d
|
|
BLAKE2b-256 checksum How to use checksums |
98e6237f9fede11cd1b636a180f5985b2497d5a51701ac1d4cd35b6299ed4291
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2025.
Transparency log