# Datafiles: A file-based ORM for Python dataclasses
Datafiles is a bidirectional serialization library for Python [dataclasses](https://docs.python.org/3/library/dataclasses.html) to synchronize objects to the filesystem using type annotations. It supports a variety of file formats with round-trip preservation of formatting and comments, where possible. Object changes are automatically saved to disk and only include the minimum data needed to restore each object.
[![Travis CI](https://img.shields.io/travis/com/jacebrowning/datafiles/main.svg?label=unix)](https://app.travis-ci.com/jacebrowning/datafiles)
[![AppVeyor](https://img.shields.io/appveyor/ci/jacebrowning/datafiles/main.svg?label=windows)](https://ci.appveyor.com/project/jacebrowning/datafiles)
[![Coveralls](https://img.shields.io/coveralls/jacebrowning/datafiles.svg)](https://coveralls.io/r/jacebrowning/datafiles)
[![PyPI License](https://img.shields.io/pypi/l/datafiles.svg)](https://pypi.org/project/datafiles)
[![PyPI Version](https://img.shields.io/pypi/v/datafiles.svg)](https://pypi.org/project/datafiles)
[![PyPI Downloads](https://img.shields.io/pypi/dm/datafiles.svg?color=orange)](https://pypistats.org/packages/datafiles)
[![Gitter](https://img.shields.io/gitter/room/jacebrowning/datafiles?color=D0164E)](https://gitter.im/jacebrowning/datafiles)
Some common use cases include:
- Coercing user-editable files into the proper Python types
- Storing program configuration and state in version control
- Loading data fixtures for demonstration or testing purposes
- Synchronizing application state using file sharing services
- Prototyping data models agnostic of persistence backends
Watch [my lightning talk](https://www.youtube.com/watch?v=moYkuNrmc1I&feature=youtu.be&t=1225) for a demo of this in action!
## Overview
Take an existing dataclass such as [this example](https://docs.python.org/3/library/dataclasses.html#module-dataclasses) from the documentation:
```python
from dataclasses import dataclass
@dataclass
class InventoryItem:
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
```
and decorate it with a directory pattern to synchronize instances:
```python
from datafiles import datafile
@datafile("inventory/items/{self.name}.yml")
class InventoryItem:
...
```
Then, work with instances of the class as normal:
```python
>>> item = InventoryItem("widget", 3)
```
```yaml
# inventory/items/widget.yml
unit_price: 3.0
```
Changes to the object are automatically saved to the filesystem:
```python
>>> item.quantity_on_hand += 100
```
```yaml
# inventory/items/widget.yml
unit_price: 3.0
quantity_on_hand: 100
```
Changes to the filesystem are automatically reflected in the object:
```yaml
# inventory/items/widget.yml
unit_price: 2.5 # <= manually changed from "3.0"
quantity_on_hand: 100
```
```python
>>> item.unit_price
2.5
```
Objects can also be restored from the filesystem:
```python
>>> from datafiles import Missing
>>> item = InventoryItem("widget", Missing)
>>> item.unit_price
2.5
>>> item.quantity_on_hand
100
```
## Installation
Install this library directly into an activated virtual environment:
```
$ pip install datafiles
```
or add it to your [Poetry](https://poetry.eustace.io/) project:
```
$ poetry add datafiles
```
## Documentation
To see additional synchronization and formatting options, please consult the [full documentation](https://datafiles.readthedocs.io).
Raw data
{
"_id": null,
"home_page": "https://pypi.org/project/datafiles",
"name": "datafiles",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "dataclasses,serialization,type-annotations,object-relational mapping,YAML,JSON,TOML",
"author": "Jace Browning",
"author_email": "jacebrowning@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/5c/ef/21e5e889abde403548121e289f8588847197892756e4dc1dc4c3dd18fb98/datafiles-2.2.2.tar.gz",
"platform": null,
"description": "# Datafiles: A file-based ORM for Python dataclasses\n\nDatafiles is a bidirectional serialization library for Python [dataclasses](https://docs.python.org/3/library/dataclasses.html) to synchronize objects to the filesystem using type annotations. It supports a variety of file formats with round-trip preservation of formatting and comments, where possible. Object changes are automatically saved to disk and only include the minimum data needed to restore each object.\n\n[![Travis CI](https://img.shields.io/travis/com/jacebrowning/datafiles/main.svg?label=unix)](https://app.travis-ci.com/jacebrowning/datafiles)\n[![AppVeyor](https://img.shields.io/appveyor/ci/jacebrowning/datafiles/main.svg?label=windows)](https://ci.appveyor.com/project/jacebrowning/datafiles)\n[![Coveralls](https://img.shields.io/coveralls/jacebrowning/datafiles.svg)](https://coveralls.io/r/jacebrowning/datafiles)\n[![PyPI License](https://img.shields.io/pypi/l/datafiles.svg)](https://pypi.org/project/datafiles)\n[![PyPI Version](https://img.shields.io/pypi/v/datafiles.svg)](https://pypi.org/project/datafiles)\n[![PyPI Downloads](https://img.shields.io/pypi/dm/datafiles.svg?color=orange)](https://pypistats.org/packages/datafiles)\n[![Gitter](https://img.shields.io/gitter/room/jacebrowning/datafiles?color=D0164E)](https://gitter.im/jacebrowning/datafiles)\n\nSome common use cases include:\n\n- Coercing user-editable files into the proper Python types\n- Storing program configuration and state in version control\n- Loading data fixtures for demonstration or testing purposes\n- Synchronizing application state using file sharing services\n- Prototyping data models agnostic of persistence backends\n\nWatch [my lightning talk](https://www.youtube.com/watch?v=moYkuNrmc1I&feature=youtu.be&t=1225) for a demo of this in action!\n\n## Overview\n\nTake an existing dataclass such as [this example](https://docs.python.org/3/library/dataclasses.html#module-dataclasses) from the documentation:\n\n```python\nfrom dataclasses import dataclass\n\n@dataclass\nclass InventoryItem:\n \"\"\"Class for keeping track of an item in inventory.\"\"\"\n\n name: str\n unit_price: float\n quantity_on_hand: int = 0\n\n def total_cost(self) -> float:\n return self.unit_price * self.quantity_on_hand\n```\n\nand decorate it with a directory pattern to synchronize instances:\n\n```python\nfrom datafiles import datafile\n\n@datafile(\"inventory/items/{self.name}.yml\")\nclass InventoryItem:\n ...\n```\n\nThen, work with instances of the class as normal:\n\n```python\n>>> item = InventoryItem(\"widget\", 3)\n```\n\n```yaml\n# inventory/items/widget.yml\n\nunit_price: 3.0\n```\n\nChanges to the object are automatically saved to the filesystem:\n\n```python\n>>> item.quantity_on_hand += 100\n```\n\n```yaml\n# inventory/items/widget.yml\n\nunit_price: 3.0\nquantity_on_hand: 100\n```\n\nChanges to the filesystem are automatically reflected in the object:\n\n```yaml\n# inventory/items/widget.yml\n\nunit_price: 2.5 # <= manually changed from \"3.0\"\nquantity_on_hand: 100\n```\n\n```python\n>>> item.unit_price\n2.5\n```\n\nObjects can also be restored from the filesystem:\n\n```python\n>>> from datafiles import Missing\n>>> item = InventoryItem(\"widget\", Missing)\n>>> item.unit_price\n2.5\n>>> item.quantity_on_hand\n100\n```\n\n## Installation\n\nInstall this library directly into an activated virtual environment:\n\n```\n$ pip install datafiles\n```\n\nor add it to your [Poetry](https://poetry.eustace.io/) project:\n\n```\n$ poetry add datafiles\n```\n\n## Documentation\n\nTo see additional synchronization and formatting options, please consult the [full documentation](https://datafiles.readthedocs.io).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "File-based ORM for dataclasses.",
"version": "2.2.2",
"project_urls": {
"Documentation": "https://datafiles.readthedocs.io",
"Homepage": "https://pypi.org/project/datafiles",
"Repository": "https://github.com/jacebrowning/datafiles"
},
"split_keywords": [
"dataclasses",
"serialization",
"type-annotations",
"object-relational mapping",
"yaml",
"json",
"toml"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0a54db816106f9cbff190e1a9a43ec4dc8dbbfcd30176d5a86e8574e0c2482f9",
"md5": "bbcdf6ad9b7caed61430792aebcfd12f",
"sha256": "ad50344be44444edf8220046b3cfb81aff61aed5c3dd61f2808caf5add2f5ec2"
},
"downloads": -1,
"filename": "datafiles-2.2.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bbcdf6ad9b7caed61430792aebcfd12f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 32529,
"upload_time": "2024-01-06T23:42:33",
"upload_time_iso_8601": "2024-01-06T23:42:33.278140Z",
"url": "https://files.pythonhosted.org/packages/0a/54/db816106f9cbff190e1a9a43ec4dc8dbbfcd30176d5a86e8574e0c2482f9/datafiles-2.2.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5cef21e5e889abde403548121e289f8588847197892756e4dc1dc4c3dd18fb98",
"md5": "04536f5ffcc4ef9453c05b56a588b44e",
"sha256": "c82e3ca2e187f5fdbb6eb01c4001021c945f0e75de1e32b0aeece3615d8d478b"
},
"downloads": -1,
"filename": "datafiles-2.2.2.tar.gz",
"has_sig": false,
"md5_digest": "04536f5ffcc4ef9453c05b56a588b44e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 25328,
"upload_time": "2024-01-06T23:42:35",
"upload_time_iso_8601": "2024-01-06T23:42:35.737555Z",
"url": "https://files.pythonhosted.org/packages/5c/ef/21e5e889abde403548121e289f8588847197892756e4dc1dc4c3dd18fb98/datafiles-2.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-06 23:42:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jacebrowning",
"github_project": "datafiles",
"travis_ci": true,
"coveralls": true,
"github_actions": false,
"appveyor": true,
"lcname": "datafiles"
}