Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a safe_get_config #217

Open
BryceStevenWilley opened this issue Dec 5, 2023 · 2 comments
Open

Add a safe_get_config #217

BryceStevenWilley opened this issue Dec 5, 2023 · 2 comments

Comments

@BryceStevenWilley
Copy link
Contributor

We've added a lot of chained code that gets things from the config, i.e.:

x = get_config("assembly line", {}).get("interview list")

This is fine, but there's an issue if people have something wrong in their config file, like this error recently in teams:

  File "/usr/share/docassemble/local3.10/lib/python3.10/site-packages/docassemble/AssemblyLine/sessions.py", line 1303, in config_with_language_fallback
    if interview_list_config.get(config_key):
AttributeError: 'NoneType' object has no attribute 'get'

Which has to be caused by a call to get_config("assembly line", {}) being present (so the empty dict isn't returned), but still returning null.

My question is if we want a safer version, like safe_get_config that internally would be something like this:

def safe_get_config(config_key, *further_keys):
    obj = get_config(config_key) or {}
    for config_key in further_keys:
        obj = obj.get(config_key) or {}
    return obj

Making sure that we would never have a no attribute 'get' error in production, no matter what the config looks like. Cons are that it might be harder to determine a misconfigured server, but IMO there's enough issues with YAML and spelling and stuff that hiding None key-values in dictionaries shouldn't make the problem worse.

@nonprofittechy
Copy link
Member

This could help simplify a common pattern. I'm open to it. I did look into whether there's a good existing tool or pattern for this, like xpath for XML. There is dpath, but it's a pretty heavy dependency and we're just using one possible option of it, so a new function seems fine.

@BryceStevenWilley
Copy link
Contributor Author

Dumping my progress so far on this: code is in https://github.com/SuffolkLITLab/docassemble-ALToolbox/tree/safe_config.

I had intended for it to be used as safe_get_config("assembly line", "interview list", "special key") or "default", but that prevents people from ever setting things as blank strings, and it would always get overriden by "default". So a slight change in the definition (looks fairly close to a version I wrote in EFSPIntegration):

def safe_get_config(config_keys: List[str], default: Any) -> Any:

Internally, we can return the default whenever to_return is None. I haven't seen null explicitly set in a config on MassAccess or MPLP, so I think that's fine.

I also slowed down on this because we rarely have configs that are nested beyond 2 dictionaries in the config, so adding this function doesn't avoid any really gnarly code.

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

No branches or pull requests

2 participants