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

Make pydantic based config system #141

Open
wants to merge 6 commits into
base: python3
Choose a base branch
from

Conversation

anand2312
Copy link

@anand2312 anand2312 commented Jul 24, 2022

The configuration system has been revamped by making pydantic
do the parsing for us.

Functions that work with the new system but have backwards compatible
signatures were made in the new config.py file; functions that weren't
being used anywhere were not replicated.
The old script.py can be deleted once all references to it has been
safely replaced.

Functions that work with the new system but have backwards compatible
signatures were made in the new config.py file; functions that weren't
being used anywhere were not replicated.
The old script.py can be deleted once all references to it has been
safely replaced.
@@ -0,0 +1 @@
from . import webdav as webdav
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not need the as webdav part.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't needed syntactically, but running mypy in strict mode will complain about it. Although I can remove it because we haven't really decided on whether we are going to enforce a type-checker in the first place.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. However, thinking about this, do we need the import at all? Even if the global variable (get_logger) within webdav.py would be needed, it could be initialized lazily upon import. (It should be removed anyway, though; as mentioned below, "caching" loggers is not needed, Python handles that for you.)

from pydantic import BaseSettings


logger = None
Copy link

@fmoc fmoc Jul 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global variables are the root of evil. Generally, you should try to avoid them.

With Python's logging facilities, you do not need to "cache" logger objects anyway. Python handles this internally. Please see below for more information.

if not logger:
if level is None:
level = logging.INFO # change here to DEBUG if you want to debug config stuff
logging.basicConfig(level=level)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set the logger's log level here if you want to, but the global call should be moved to the entry script.

I know this can be confusing. In Python, loggers can have levels. All messages lower than the logger's level will be suppressed. If the log message is not suppressed by the logger, the global configuration is then checked, if I remember this correctly. If the log message passes this check, it should be displayed.


# this should probably be moved into a utilities module
def get_logger(name: str = "config", level: int | None = None) -> logging.Logger:
global logger
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to cache the logger, Python does this internally. You can call getLogger as often as you want to, it will return the same object every time (at least when not using multithreading, of course). The method can be considered idempotent.

def oc_server_datadirectory(self) -> str:
return os.path.join("/var/www/html", self.oc_root, "data")

# these methods exists for backwards compatibility
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend to refactor those in the future? As demonstrated correctly below, Python's getattr and dict facilities are perfect Pythonic replacements.

with open(fp, "r") as file:
return Configuration(**yaml.load(file))

def configure_from_blob(fp: Path | str) -> Configuration:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style wise, you should always have at least two blank lines to separate methods.

You may want to include pep8/flake8 as development dependencies and run these on your code changes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added black, but forgot to run it this time 😅 I can set up pre-commit to automatically run these hooks every time you commit, but should I include that with this PR, or make a new one?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to handle this in a follow-up PR. I'd also like to have a GitHub actions check that checks the formatting with black.

@fmoc
Copy link

fmoc commented Jul 25, 2022

Looks quite good. I left some suggestions.

@anand2312
Copy link
Author

@fmoc thanks for the review!
Re: the logger comments - I was thinking of switching to loguru. It automatically solves some of the issues you highlighted, as it provides just one logger that is globally used. I also find it a bit more pythonic to use than stdlib logging. What do you think?

@fmoc
Copy link

fmoc commented Aug 4, 2022

Never heard of before. @SamuAlfageme what do you think about that new dependency?

@SamuAlfageme
Copy link
Contributor

@anand2312 @fmoc It indeed looks nice. You can go ahead and include it in your working branch. You will have the chance to demonstrate how it improves the existing logging libraries.

All logging calls have to be slowly converted after this.
@SamuAlfageme
Copy link
Contributor

@anand2312 is this ready for another round of review after your last commit? Would you be up to running a demonstration of your changes later this week?

@anand2312
Copy link
Author

@SamuAlfageme there's a little more stuff left, I'll push them by tomorrow

@anand2312
Copy link
Author

I reverted the loguru commit as it would need a big change (changing all logger calls to use loguru), and it would be confusing if I did that work in this same PR.
@fmoc sorry for the delay, I've made the change to not cache the logger, is there anything else I should change in this PR?

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

Successfully merging this pull request may close these issues.

3 participants