Config.yaml add key question


#1

How would one add a value for a path which doesn't yet exist?

Current state:

a:
  b:
    c:
      name: Name

Expected state after (we need to create ["a", "b", "d"] somehow as an interim step):

a:
  b:
    c:
      name: Name
    d:
      name: Different

python:

s = settings()
s.set(["a", "b", "d", "name"], "Different") # This silently fails due to the path being missing
s.save()

s = settings()
s.set(["a", "b", "d"], "{}")                # This silently fails due to the path being missing
s.save()

s = settings()
s.set(["a", "b"], "d: {}")                  # This will overwrite the ["a", "b", "c"] path completely with 'd: {}'
s.save()

s = settings()
s.set(["a", "b", "d"], None)                # This silently fails
s.save()

s = settings()
s.setInt(["a", "b", "d"], None)             # This silently fails
s.save()

#2

For what it's worth, I was only able to get this to work using the REST API. I can see no way of just grafting onto the existing yaml path as described.


#3

You shouldn't be fiddling around in anything but a plugin's sub section of the config.yaml, and in order to add a key there you'd need to override the settings defaults. Same would go for core development. The idea is to not have everyone freely add stuff to config.yaml in a completely uncontrolled and non cleanable manner.

If you need to push a complex data structure to a config key, then you'd need to define that config key in the defaults and then save the full data dump to that.

This is a all a bit vague, if you can tell me an abstract why for what you are trying to do, I might be able to tell you a better how.


#4

This is all a follow-up to that previous attempt to store user-specific attributes into the settings key of the users.yaml file. That didn't work out, as described in the other thread.

So then I needed to store each user's attributes under the plugin's space in the config.yaml file.

plugins:
  pluginid:
    users:
      bob:
        fullname: Bob Ross
        occupation: oil color artist

At the point where Bob, (as an administrator) now wants to add Vincent as a new user, it's necessary to store the new information on that subtree path of ["plugins", "pluginid", "users"]. I just couldn't figure out a way of creating vincent as an empty key there as a sibling to bob. This then would have allowed settings().set() to add the other attributes.

It's a moot point now of course. I threw the entire vincent json to the REST API and "bob's your uncle", as they say in England.


#5

You'd need to have something like this as your settings defaults:

dict(users=dict())

Then you'd fetch the current users, update/add/remove an entry, and persist it back to ["users"].

Though depending on the kind of settings I'd probably rather go with my own data file in the plugin data folder. You don't have to cram everything in existing settings if something else might work better, and especially if it is data that might often get changed.


#6

I generally like having settings data to not live in the same folder as a git-controlled code space, honestly. And since config.yaml is backed up with your bundled plugin, that's preferable, I suppose.


#7

I was talking about the plugin data folder under ~/.octoprint/data/<identifier> which is also backed up :wink:


#8

Oh........ yet another thing I didn't know. :facepalm:


#9

Yeah, I recently found a good use case for this and am thinking of expanding it. Using sqlite3 in python and pointing it toward the plugin's data folder it's "easy peasy" to store all sorts of data.