Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CircuitPython Secrets

CircuitPython Secrets

This are some notes around the use of secrets.py in CircuitPython.

Current Events

Today CP examples suggest a secrets.py files for storing passwords, SSIDs, keys, etc as a dictionary.

File: secrets.py

secrets = {
key = value,
key1 = value1
}

Usage of this looks like so:

from secrets import secrets

print(secrets['key'])

Issues with Current Events

  1. Secrets is a core module in Python, so we're teaching new coders a practice which will surely leads to confusion if\when they move on to Python coding.
  2. Using a dictionary is not wrong, but combersome and lacks the helpful functionality other approaches would have, such as autocomplete.

Potential Approaches

New File Name

At a minimum, suggesting the use of secrets.py should be changed. The good thing about that name though is that it does imply that it is information you don't want to put into your GitHub repo. Some potential new file names:

  • config.py <-- This could be for all configuraion you can commit.
  • config_secrets.py <-- this could be for all configuration you should NOT commit.

Adding config.secrets.py to the .gitignore should also be recommended and added to .gitignore tools.

Question: Should the recommendation also be use the CAPS style since these are truly globals? ex: config_secrets.KEY1

New Data Format

The dictionary format could be improved. Using variables would allow for dot notation and autcomplete.

file: config_secrets.py

key = value
key1 = value1

file: code.py

import config_secrets.py

print(config_secrets.key1)

Environment Variables in CPython and MicroPython

In CPython, it is common to use OS environment variables and the OS Core Module to work with the values:

  • os.get_env: os.getenv(key, default=None) returns the value of the environment variable or the supplied default.
  • os.environ: Tuple-like string mapping of environment variables at thetime of os import. Updating the object also updates the environment and is preferred to calling os.putenv or os.unsetenv directly.
  • os.putenv: Creates or updates an evironment variable, does not update os.environ.
  • os.unsetenv: Deletes an environment variable, does not update os.environ
  • os.environb: Bytes version of os.environ. Linux Only
  • os.get_envb: Bytes version of os.get_env. Linux Only

os.get_env() is the very common method usesin CPython applications.

There are also many environment libraries for CPython and frameworks (Django, ertc..) to help manage not only run-time but dev, test, production environments.

In MicroPython there is nothing implemented in the MP core libraries. There is an external library ShenTengTu/micropython-env which doesn't appear to be in wide use (2 ⭐️). The approach in ShenTengTu/micropython-env is to import from JSON files or MessagePack

More Reasearch

  1. It was suggested by @tannewt, that CP could use an approach similiar to the environment variable approach. How these are set initially is still an unknown to me. I could see os.put_env() being called from the REPL or from boot.py to set values from config_secrets.py. for example: os.load_env(config_secrets) and then using os.get_env().
  2. Are values preserved across reboots is an interesting discussion...
@askpatrickw

This comment has been minimized.

Copy link
Owner Author

@askpatrickw askpatrickw commented Jun 27, 2021

python dotenv is another great tool to look at ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment