autopilot
autopilot copied to clipboard
Change prefs to `pydantic`
Trying pydantic right now and absolutely love it. Seems like a superset of dataclasses that makes typing very easy.
For example:
from pydantic import BaseModel, Field
from typing import Optional
from pathlib import Path
class Directories(BaseModel):
user_dir: Path = Path.home() / 'autopilot'
prefs_file: Path = user_dir / 'prefs.json'
class Audio_Prefs(BaseModel):
fs:int = 192000
device: str = Field(description="The sound device to use!")
class Pigpio_Prefs(BaseModel):
mask: str = 'etc.'
class Prefs(BaseModel):
audio_prefs: Audio_Prefs
pigpio_prefs: Optional[Pigpio_Prefs] = None
def save(self, file: Path = Directories.prefs_file):
with open(file, 'w') as pfile:
pfile.write(self.json())
@classmethod
def load(cls, file: Path = Directories.prefs_file) -> 'Prefs':
with open(file, 'r') as pfile:
prefs_raw = pfile.read()
return Prefs.parse_raw(prefs_raw)
This would solve a lot of problems, like the ballooning complexity of the prefs file and its relatively undocumented state, the ability to have impossible values which causes a lot of coercion throughout the program, and the awkwardness of the current multiprocessing-safe prefs which could be solved by writing/reading to a file with a lock.
We could also make a trivial mapping from types to graphical elements and solve this and make the prefs TUI a lot a lot a lot easier to manage, re: https://github.com/wehr-lab/autopilot/issues/153
ope https://pydantic-docs.helpmanual.io/usage/settings/
One gotcha I've run into before when hardcoding my own prefs
-esque code is things like "True" vs True, or "1" vs 1, or "None" vs None vs np.nan vs "" vs, and you want something to handle that sanely when converting to/from plaintext. I imagine pydantic might be good for that
One gotcha I've run into before when hardcoding my own
prefs
-esque code is things like "True" vs True, or "1" vs 1, or "None" vs None vs np.nan vs "" vs, and you want something to handle that sanely when converting to/from plaintext. I imagine pydantic might be good for that
Definitely. and the current prefs manager is a really huge mess for any circumstance where you're using autopilot stuff in a nonstandard context due to the use of the multiprocessing manager... Definitely need to move to a different model of setting prefs where it's not globally shared across the module but each module knows how to get its own. Prefs are basically never prefs.set
anyway, and the times they are are just sort of a stopgap that should be resolved.