# dynafield
Dynamic data structures for rapidly evolving applications.
> [!IMPORTANT]
> **Project status:** dynafield is under active development. Public APIs and behaviors may change without notice and should be considered unstable.
## Overview
dynafield helps you describe, generate, and consume rich data schemas at runtime. By composing declarative field definitions you can build fully-typed [Pydantic](https://docs.pydantic.dev/latest/) models, expose them via [Strawberry GraphQL](https://strawberry.rocks/), and orchestrate runtime records without hand-writing large numbers of boilerplate classes.
The project powers internal tooling at [Revvue](https://revvue.ai) and is now open-source so other teams can benefit from the same dynamic schema capabilities.
## Key features
- **Dynamic model generation** – Produce Pydantic `BaseModel` subclasses on the fly from field definitions or existing functions.
- **Comprehensive field library** – Strings, numbers, UUIDs, JSON blobs, nested objects, lists, enumerations, and more – each with validation and default handling baked in.
- **GraphQL-ready schema types** – Convert record schemas into Strawberry GraphQL types so runtime structures can be queried just like static models.
- **Registry and record utilities** – Register multiple schemas, build typed instances from stored payloads, and apply partial updates safely.
- **JSON-friendly serialization** – Custom serializers ensure enumerations, datetimes, and nested models render predictably in API responses.
## Installation
```bash
pip install dynafield
```
The package targets Python 3.12. See `pyproject.toml` for dependency details.
## Quickstart
### Build a model from field definitions
```python
from dynafield import IntField, StrField, build_dynamic_model
fields = [
StrField(label="customer_name", min_length=1, max_length=50),
IntField(label="party_size", ge_int=1, le_int=12),
]
Booking = build_dynamic_model("Booking", fields)
record = Booking(customer_name="Ada", party_size=4)
print(record.dump()) # {'customer_name': 'Ada', 'party_size': 4}
```
### Infer fields from a function signature
```python
from datetime import datetime
from typing import Literal
from dynafield import build_model_from_function
def create_invoice(customer_email: str, amount: float, status: Literal["draft", "sent"], sent_at: datetime | None = None):
...
Invoice = build_model_from_function(create_invoice)
print(Invoice.model_fields.keys())
```
### Manage schemas with a registry
```python
from dynafield import IntField, RecordSchemaDefinition, RecordSchemaRegistry, StrField
schema = RecordSchemaDefinition(
name="BookingRecord",
description="Schema for booking records",
field_definitions=[
StrField(label="customer_name"),
IntField(label="party_size"),
],
)
registry = RecordSchemaRegistry([schema])
stored = [{"customer_name": "Ada", "party_size": 4}]
typed_records = registry.build_records(schema.id, stored)
```
### Expose schemas via GraphQL
Every field type ships with a Strawberry GraphQL counterpart. Record schemas can be turned into GraphQL types with `RecordSchemaDefinition.to_gql_type`, making it straightforward to publish dynamic structures through Strawberry and FastAPI.
## Development
1. Clone the repository and install dependencies into a virtual environment.
2. Install the development extras:
```bash
pip install -e .[dev]
```
3. Run the test suite:
```bash
pytest
```
Example applications live under `example/` and demonstrate FastAPI + Strawberry integration.
## Contributing
Contributions, issues, and discussions are welcome! Please open an issue before making significant changes so we can coordinate direction.
## License
dynafield is released under the Apache 2.0 license.
Raw data
{
"_id": null,
"home_page": null,
"name": "dynafield",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.13,>=3.12",
"maintainer_email": "Badr Elfarri <badr@revvue.ai>, Magnus Mariero <magnus@revvue.ai>",
"keywords": "redis, cache, memoization, toolkit, async",
"author": null,
"author_email": "Badr Elfarri <badr@revvue.ai>, Magnus Mariero <magnus@revvue.ai>",
"download_url": "https://files.pythonhosted.org/packages/5f/b4/9dde12132e03d312f713dec49a81633c91034d4cf5113b6a63a934c6a459/dynafield-0.0.3.tar.gz",
"platform": null,
"description": "# dynafield\n\nDynamic data structures for rapidly evolving applications.\n\n> [!IMPORTANT]\n> **Project status:** dynafield is under active development. Public APIs and behaviors may change without notice and should be considered unstable.\n\n## Overview\n\ndynafield helps you describe, generate, and consume rich data schemas at runtime. By composing declarative field definitions you can build fully-typed [Pydantic](https://docs.pydantic.dev/latest/) models, expose them via [Strawberry GraphQL](https://strawberry.rocks/), and orchestrate runtime records without hand-writing large numbers of boilerplate classes.\n\nThe project powers internal tooling at [Revvue](https://revvue.ai) and is now open-source so other teams can benefit from the same dynamic schema capabilities.\n\n## Key features\n\n- **Dynamic model generation** \u2013 Produce Pydantic `BaseModel` subclasses on the fly from field definitions or existing functions.\n- **Comprehensive field library** \u2013 Strings, numbers, UUIDs, JSON blobs, nested objects, lists, enumerations, and more \u2013 each with validation and default handling baked in.\n- **GraphQL-ready schema types** \u2013 Convert record schemas into Strawberry GraphQL types so runtime structures can be queried just like static models.\n- **Registry and record utilities** \u2013 Register multiple schemas, build typed instances from stored payloads, and apply partial updates safely.\n- **JSON-friendly serialization** \u2013 Custom serializers ensure enumerations, datetimes, and nested models render predictably in API responses.\n\n## Installation\n\n```bash\npip install dynafield\n```\n\nThe package targets Python 3.12. See `pyproject.toml` for dependency details.\n\n## Quickstart\n\n### Build a model from field definitions\n\n```python\nfrom dynafield import IntField, StrField, build_dynamic_model\n\nfields = [\n StrField(label=\"customer_name\", min_length=1, max_length=50),\n IntField(label=\"party_size\", ge_int=1, le_int=12),\n]\n\nBooking = build_dynamic_model(\"Booking\", fields)\nrecord = Booking(customer_name=\"Ada\", party_size=4)\nprint(record.dump()) # {'customer_name': 'Ada', 'party_size': 4}\n```\n\n### Infer fields from a function signature\n\n```python\nfrom datetime import datetime\nfrom typing import Literal\n\nfrom dynafield import build_model_from_function\n\n\ndef create_invoice(customer_email: str, amount: float, status: Literal[\"draft\", \"sent\"], sent_at: datetime | None = None):\n ...\n\nInvoice = build_model_from_function(create_invoice)\nprint(Invoice.model_fields.keys())\n```\n\n### Manage schemas with a registry\n\n```python\nfrom dynafield import IntField, RecordSchemaDefinition, RecordSchemaRegistry, StrField\n\nschema = RecordSchemaDefinition(\n name=\"BookingRecord\",\n description=\"Schema for booking records\",\n field_definitions=[\n StrField(label=\"customer_name\"),\n IntField(label=\"party_size\"),\n ],\n)\nregistry = RecordSchemaRegistry([schema])\n\nstored = [{\"customer_name\": \"Ada\", \"party_size\": 4}]\ntyped_records = registry.build_records(schema.id, stored)\n```\n\n### Expose schemas via GraphQL\n\nEvery field type ships with a Strawberry GraphQL counterpart. Record schemas can be turned into GraphQL types with `RecordSchemaDefinition.to_gql_type`, making it straightforward to publish dynamic structures through Strawberry and FastAPI.\n\n## Development\n\n1. Clone the repository and install dependencies into a virtual environment.\n2. Install the development extras:\n\n ```bash\n pip install -e .[dev]\n ```\n\n3. Run the test suite:\n\n ```bash\n pytest\n ```\n\nExample applications live under `example/` and demonstrate FastAPI + Strawberry integration.\n\n## Contributing\n\nContributions, issues, and discussions are welcome! Please open an issue before making significant changes so we can coordinate direction.\n\n## License\n\ndynafield is released under the Apache 2.0 license.\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Dynamic fields build up schema",
"version": "0.0.3",
"project_urls": {
"Bug Tracker": "https://github.com/revvue-ai/dynafield/issues",
"Changelog": "https://github.com/revvue-ai/dynafield/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/revvue-ai/dynafield#readme",
"Homepage": "https://github.com/revvue-ai/dynafield",
"Repository": "https://github.com/revvue-ai/dynafield"
},
"split_keywords": [
"redis",
" cache",
" memoization",
" toolkit",
" async"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7c12f2b52e0c8583cdd88d117e270648e4f5bbe3b30da9202d9ddd56923709b5",
"md5": "a33d764de5f3f4f8dc2cca3ee94b2f8b",
"sha256": "31b2475094b3865e0e1e1c274700b1137f02acab2942f1a532e2c882b564dcf9"
},
"downloads": -1,
"filename": "dynafield-0.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a33d764de5f3f4f8dc2cca3ee94b2f8b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.13,>=3.12",
"size": 21827,
"upload_time": "2025-10-08T07:18:01",
"upload_time_iso_8601": "2025-10-08T07:18:01.756435Z",
"url": "https://files.pythonhosted.org/packages/7c/12/f2b52e0c8583cdd88d117e270648e4f5bbe3b30da9202d9ddd56923709b5/dynafield-0.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5fb49dde12132e03d312f713dec49a81633c91034d4cf5113b6a63a934c6a459",
"md5": "027610758840dc0dabca6b9b07a1a858",
"sha256": "f016a34ccf4b87fd467c16b4088ab12da9de4264a50de1a68e156812588617b3"
},
"downloads": -1,
"filename": "dynafield-0.0.3.tar.gz",
"has_sig": false,
"md5_digest": "027610758840dc0dabca6b9b07a1a858",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.13,>=3.12",
"size": 23439,
"upload_time": "2025-10-08T07:18:03",
"upload_time_iso_8601": "2025-10-08T07:18:03.396420Z",
"url": "https://files.pythonhosted.org/packages/5f/b4/9dde12132e03d312f713dec49a81633c91034d4cf5113b6a63a934c6a459/dynafield-0.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-08 07:18:03",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "revvue-ai",
"github_project": "dynafield",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "dynafield"
}