Thing Setting syntax and implementation overhaul#110
Conversation
|
I like the idea of having a descriptor to represent settings, and a decorator might well be an intuitive way to do this. Currently, Properties can work in a few different ways, but I think persistent properties (or settings as I've referred to them) ought to work as "dumb" properties - i.e. there's no getter method, they just return the value. I made #109 to discuss the syntax for this. I have said "setting" instead of "persistent property", but everything's up for discussion. I note that this implementation has the same problem as the current |
|
I would be tempted to keep |
|
The problem with the dictionary is that it requires that the person writing the code that is the property to read from the dictionary, write to the dictionary, and call saving. And to use the string of the property name in the dictionary otherwise the settings don't match. It feels less like a framework feature and something that is implemented each time I can see that saving it as a private variable isn't exactly perfect either. I can see it may be good to use dictionary under the hood, but I can't see how to do this with decorators. |
|
Right. I have updated the MR and the description. I have moved the implementation details I had before into a collapsed Iteration 1 section and then re-written a new set of details for iteration 2. I think this is somewhat a nice halfway house between the ideas:
|
Barecheck - Code coverage reportTotal: 85.75%Your code coverage diff: 1.73% ▴ Uncovered files and lines |
84e1709 to
e4afc1b
Compare
976bb12 to
5af35ed
Compare
Add unit test, that is clear that docstrings should be updated if the behaviour changes
|
Tests and docs added. I think this is ready now. |
rwb27
left a comment
There was a problem hiding this comment.
This looks good to me. I have a nagging suspicion it might break some of our picamera2 code, because I remember some slightly funny things happening with those settings. However, I am sure we will be able to work around it.
Also, we previously talked about reorganising the namespace a bit, so that Thing, ThingSetting, etc. could be imported directly from the toplevel labthings_fastapi import. I'd be broadly in favour of changing the API as few times as possible, so we might want to do that before this gets released.
Co-authored-by: Richard Bowman <richard.bowman@cantab.net>
Co-authored-by: Richard Bowman <richard.bowman@cantab.net>
Yeah, I agree. I think we reorganise the namespace to get most of what we expect to import into the top level namespace before we release. We may want to call this v0.1.0? In the the hope that it is a largely stable namespace? |
This PR changes how settings are handled so that they are now identical to properties, except that they are saved to disk when the setter is called.
Problems this PR solves
Closes #107
By removing Reactive dict
Closes #108
Settings now save on update, a unit test is added to check this.
Closes #109
By implementing the agreed upon syntax
Closes #111
Settings now reliably save when set. If an internal value is set in a dictionary setting they are not saved. However, this behaviour is documented in the docstring for
ThingSettingand the associated decorator. There is also a unit test for this behaviour which states that the documentation should be updated if this is changed somehow in the future.Closes #112
Default settings are now available during initialisation but they are not loaded from disk until added to the server.
Other things in this MR
NotConnectedToServerErrorexception was added, and the message to the user was updated for when properties/events are used without a server. Previously the message just said something about a blocking portal which is not clear to someone who doesn't know the underlying LabThings-FastAPI codebase. The new message explicitly says that it cannot emit the event and asks if the Thing is connected to the server.High level implementation details
Iteration 1
Click to show details of iteration 1 that is now superseeded
Summary
This MR would make properties have an option to be persistent, saving to disk when the setter is called.
A new decorator
A new decorator
@persistent_thing_propertyis created, this acts exactly as@thing_propertyexcept that it saves to disk. This could be@thing_property(persistent=True)except that making arguments for decorators is a bit messy, and making optional arguments is even messier and quite non-standard unless I have missed something.Add attributes to PropertyDescriptor
Two attributes are added:
persistenta boolean that sets whether the Property should save to disksave_locationThis is the save path (Optional!). It starts asNone. If it isNonesaving would not happen, if it is set, saving would. Currently this just logs that it should save:Changes to
add_thingon the serverCheck through each attribute using
class_attributesutility function that already exists. If a property is found, then it is checked whether it is persistent. If it is the save location is added to the descriptorssave_location.Not added yet!
Read from disk and set the property from values on disk
Issues to consider
save_location. It is unclear to me whether there were two objects of the same class whether it would break. Ideas welcome.Iteration 2
Summary
This MR would make a decorator and a descriptor for settings. Settings would be a type of property that is persistent. i.e. if you make something a setting it is also a property
A new decorator
A new decorator
@thing_settingis created, this acts exactly as@thing_propertyexcept that it saves to disk.SettingDescriptorA subclass of
ProperyDescriptoron__set__it called the save settings method that is added to the mainThingclassChanges to
Thing{name: getattr(self, name) for name in self.settings}save_settingsmethod that is called whenever a Thing Setting is updated. It will save to file, but currently it logs. It now has the full settings dictionary, using the above comprehension without requiring the dictionary to be explicitly created and used by anyone creating aThingNot added yet!
A way to read settings from disk when started up
Issues to consider
Thingcompared to iteration 1.