Edits to users.yaml

I need a place to store some extra attributes on a per-user basis. What are your thoughts about storing these in the ~/.octoprint/users.yaml file?

michael:
  active: true
  apikey: null
  password: REDACTED
  roles:
  - user
  - admin
  settings: {}

Currently, that's what it looks like and this is what I might propose. Would this break anything?

michael:
  active: true
  apikey: null
  password: REDACTED
  roles:
  - user
  - admin
  settings: {}
  custom:
    avatar: '/home/pi/whatever/michael.png'
    fullName: 'OutsourcedGuru'
    favoriteCookie: 'Do-Si-Dos'

...or...

  custom: {'avatar': '/home/pi/whatever/michael.png', 'fullName': 'OutsourcedGuru', 'favoriteCookie': 'Do-Si-Dos'}

Why not throw into the already existing user settings?

I thought that was sort of yours and I didn't want to step on your toes.

Nah. Not really. I built it in for situations like this, core or plugins having to store user specific data. Might make sense to create some sort of namespacing in there though.

I've got a few that I'd like to store in there for this particular design. I can throw you a preliminary list next week if you'd like but it's almost set in stone at this point.

How about {'pluginid_favoriteCookies': 'Do-Si-Dos', ...} for namespacing?

To match the way that IDs are generated for templates and elsewhere I'd go with plugin_<identifier>_<key>

Thanks, that will be awesome. :slight_smile:

Of course, exercising the REST API with Postman always works. I immediately cat the file and the contents have been updated.

Yesterday, I swear this was working by directly calling the changeUserSettings() function. Woke up this morning and that didn't work. So I re-tooled things to call the REST API. It acts like it works but it doesn't write the information to the file itself.

# key in this context is 'michael', value might be 'MB'
userSettings = op.obj._user_manager.getAllUserSettings(key)
userSettings["plugin_ID_fullName"] = str(value) # Needed str() since it was trying to do u'Something'
u = json.dumps(userSettings)
r = requests.patch(api_url, u, headers={"X-Api-Key":api_key,"Content-Type":"application/json"})
# r.status_code will be 200 as expected
# Calling it directly instead of using the REST API worked yesterday but not today
#op.obj._user_manager.changeUserSettings(key, userSettings)

I'm seeing that behind-the-scenes there is a UserManager class as well as a FilebasedUserManager. I've reviewed my current and past octoprint.log files and they have no references to ...falling back to FilebasedUserManager! in them.

The biggest difference I can see is that Postman uses the hostname (and some IP address) rather than localhost and 127.0.0.1.

Update: I tried this using the hostname but that didn't help. I've converted this into the standard plugins settings storage and it's now working as expected.