Model API
A model is created by either extending the Model
class or using the datafile()
decorator.
Decorator
Given this example dataclass:
from dataclasses import dataclass
@dataclass
class Item:
name: str
count: int
available: bool
Synchronization is enabled by adding the @datafile(<pattern>)
decorator:
from dataclasses import dataclass
from datafiles import datafile
@datafile("items/{self.name}.yml")
@dataclass
class Item:
name: str
count: int
available: bool
or by replacing the @dataclass
decorator entirely:
from datafiles import datafile
@datafile("items/{self.name}.yml")
class Item:
name: str
count: int
available: bool
Filename
Instances of the class are synchronized to disk according to the <pattern>
string:
Item("abc") # <=> items/abc.yml
Item("def") # <=> items/def.yml
Filename patterns are relative to the file in which the model is defined unless <pattern>
is an absolute path or explicitly relative to the current directory:
- Absolute path:
/tmp/items/{self.name}.yml
- Relative to model's module:
items/{self.name}.yml
- Relative to the current directory:
./items/{self.name}.yml
- Relative to the user's home directory:
~/items/{self.name}.yml
Attributes included in the filename pattern and those with default value are automatically excluded from serialization since these redundant values are not required to restore objects from disk.
Options
The following options can be passed to the @datafile()
decorator:
Name | Type | Description | Default |
---|---|---|---|
attrs |
dict |
Map of attributes to datafile.converters classes for serialization. |
{} 1 |
manual |
bool |
Synchronize object and file changes manually. | False |
defaults |
bool |
Include attributes with default values when serializing. | False |
infer |
bool |
Automatically infer new attributes from the file. | False |
frozen |
bool |
Freeze the underlying dataclass and prevent multiple loads. |
False |
1 By default, synchronized attributes are inferred from the type annotations.
For example:
from datafiles import datafile
@datafile("items/{self.name}.yml", manual=True, defaults=True)
class Item:
name: str
count: int
available: bool
@datafile("config.yml", infer=True)
class Config:
default_count: int = 42
Meta class
Alternatively, any of the above options can be configured through code by setting datafile_<option>
in a Meta
class:
from datafiles import datafile, converters
@datafile("items/{self.name}.yml")
class Item:
name: str
count: int
available: bool
class Meta:
datafile_attrs = {"count": converters.Integer}
datafile_manual = True
datafile_defaults = True
Base class
Finally, a datafile can explicitly extend datafiles.Model
and set the pattern in the Meta
class:
from dataclasses import dataclass
from datafiles import Model, converters
@dataclass
class Item(Model):
name: str
count: int
available: bool
class Meta:
datafile_pattern = "items/{self.name}.yml"
datafile_attrs = {"count": converters.Integer}
datafile_manual = True
datafile_defaults = True