Saver Strategy
SaverStrategy
Bases: ABC
Abstract base class for saving logger metadata.
The MetadataSaver class defines the interface for persisting logging configuration and tag metadata to files in various formats (JSON, YAML, TOML, etc.). Implementations handle format-specific serialization while the base class provides common metadata assembly logic.
This class uses the Strategy pattern to allow runtime selection of metadata file formats without modifying the logger code.
Methods:
| Name | Description |
|---|---|
save |
Save metadata dictionary to file in the implementation's format. |
get_extension |
Return the file extension for this saver's format. |
save_logger_metadata |
sensor_type: str, tags: List[ReadTag]) -> None High-level method that assembles and saves complete logger metadata. |
Notes
Metadata Structure ~~~~~~~~~~~~~~~~~~ The metadata dictionary contains:
date: ISO format date string (YYYY-MM-DD)interval_seconds: Logging interval as integersensor_type: Sensor class name as stringtags: Dictionary mapping tag names to their metadata dicts
Example structure::
{
"date": "2025-10-24",
"interval_seconds": 60,
"sensor_type": "GMP252",
"tags": {
"CO2": {
"description": "CO2 concentration",
"unit": "ppm",
"precision": 1,
"min_interval": 10
},
"TEMPERATURE": {
"description": "Sensor temperature",
"unit": "°C",
"precision": 0.1,
"min_interval": 1
}
}
}
Tag Metadata Extraction
~~~~~~~~~~~~~~~~~~~~~~~
Tags must have a metadata attribute with a to_dict() method that
returns their metadata as a dictionary. If to_dict() is not available,
the tag is skipped (no error is raised).
See Also
JSONMetadataSaver : JSON format implementation SensorLogger : Uses MetadataSaver for metadata persistence ReadTag : Base class for measurement tags
Examples:
Implementing a custom metadata saver:
>>> from pathlib import Path
>>> from typing import Dict, Any
>>>
>>> class CustomMetadataSaver(MetadataSaver):
... def save(self, filepath: Path, metadata: Dict[str, Any]) -> None:
... with open(filepath, 'w') as f:
... for key, value in metadata.items():
... f.write(f"{key}: {value}\n")
...
... def get_extension(self) -> str:
... return 'txt'
>>>
>>> saver = CustomMetadataSaver()
>>> saver.save_logger_metadata(
... Path('metadata.txt'),
... date=datetime.now().date(),
... interval_seconds=60,
... sensor_type='GMP252',
... tags=[CO2, TEMPERATURE]
... )
Source code in atmospyre/loggers/strategies/saver.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | |
Functions
save(filepath, metadata)
abstractmethod
Save metadata dictionary to file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
Path where the metadata file should be saved. Parent directories must exist. |
required |
metadata
|
Dict[str, Any]
|
Complete metadata dictionary to serialize and save. Structure
is defined by the |
required |
Notes
Implementations should:
- Create or overwrite the file at the specified path
- Handle format-specific encoding and serialization
- Ensure the file is human-readable when possible
- Preserve data types where the format supports it
Examples:
>>> metadata = {
... 'date': '2025-10-24',
... 'interval_seconds': 60,
... 'sensor_type': 'GMP252',
... 'tags': {'CO2': {...}}
... }
>>> saver.save(Path('./metadata.json'), metadata)
Source code in atmospyre/loggers/strategies/saver.py
get_extension()
abstractmethod
Get file extension for this saver's format.
Returns:
| Type | Description |
|---|---|
str
|
File extension without leading dot (e.g., 'json', 'yaml', 'toml'). |
Examples:
Source code in atmospyre/loggers/strategies/saver.py
save_logger_metadata(filepath, date, interval_seconds, sensor_type, tags)
Save complete logger metadata to file.
Assembles metadata from logger configuration and tag metadata, then saves it using the implementation's format. This is the primary method used by SensorLogger to persist metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
Path where the metadata file should be saved. |
required |
date
|
date
|
Date of the logging session, written in ISO format (YYYY-MM-DD). |
required |
interval_seconds
|
int
|
Logging interval in seconds. |
required |
sensor_type
|
str
|
Name of the sensor class being logged. |
required |
tags
|
List[ReadTag]
|
List of tags being logged. Each tag's metadata is extracted using
its |
required |
Notes
Tags without a metadata attribute or without a to_dict() method
on their metadata are silently skipped. This allows mixing tags with
and without detailed metadata.
The assembled metadata structure is passed to the save() method
for format-specific serialization.
Examples:
>>> from datetime import date
>>> from atmospyre.sensors.implementations.co2.vaisala.gmp252 import GMP252, CO2, TEMPERATURE
>>>
>>> saver = JSONMetadataSaver()
>>> sensor = GMP252(port='/dev/ttyUSB0')
>>>
>>> saver.save_logger_metadata(
... filepath=Path('./metadata.json'),
... date=date(2025, 10, 24),
... interval_seconds=60,
... sensor_type='GMP252',
... tags=[CO2, TEMPERATURE]
... )
>>> # Creates metadata.json with complete logging configuration