Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat:KeyringSettingsSource class to load keyring variables#140

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
lmmx wants to merge6 commits intopydantic:main
base:main
Choose a base branch
Loading
fromlmmx:FEAT-keyring-settings-source

Conversation

lmmx
Copy link

@lmmxlmmx commentedAug 12, 2023
edited
Loading

Proposal

PR to fulfill the feature proposal:

Details

  • Akeyring_backend is provided, and behaves similarly to theenv_file: if the named backend is not found, nothing is loaded. If not specified, the default backend is used.

mypy linting

The CI workflow does not install the project dependencies so the linting step is failing.

If Ipip install -e[keyring] the mypy error is resolved.

Due to incorrectly cast annotations in the source package I had to usecast to get the correct annotation. Not all backends seem to support the enumeration of all keys in the keyring, so to begin with I have restricted the implementation to theSecretService backend (Linux).

pre-commit run --color never --all-files
check yaml...............................................................Passedcheck toml...............................................................Passedfix end of files.........................................................Passedtrim trailing whitespace.................................................PassedLint.....................................................................PassedMypy.....................................................................PassedPyupgrade................................................................Passed

Request for review

  • Is the approach oftry/except ImportError: pass acceptable? An alternative would be to set a variable that could be used to gate the calling of thekeyring module.
  • How should I implement error handling for the access of the variables? (As mentioned in the original proposal). If the keyring is locked it will raise an error. I haven't added this handling to keep the original proposal simple.

@lmmxlmmx changed the titlefeat: contribute KeyringSettingsSource class to load keyring variablesfeat:KeyringSettingsSource class to load keyring variablesAug 12, 2023
@hramezani
Copy link
Member

Thanks@lmmx for the proposal and the PR 🙏

The CI workflow does not install the project dependencies so the linting step is failing.

You can addkeyring to thelinting requirements and then runpip-compile --output-file=requirements/linting.txt requirements/linting.in

Is the approach of try/except ImportError: pass acceptable? An alternative would be to set a variable that could be used to gate the calling of the keyring module.

We haveemail-validator as an optional dependency inPydantic. Please take a look atpydantic.networks.py and especiallyimport_email_validator.
Also, I think we need to includeKeyringSettingsSource in sources ifkeyring is installed.

How should I implement error handling for the access of the variables? (As mentioned in the original proposal). If the keyring is locked it will raise an error. I haven't added this handling to keep the original proposal simple.

I think you can raise aSettingsError

I think we need to have:

  • Proper support on Linux and Mac
  • Tests
  • Documentation
lmmx reacted with thumbs up emoji

@lmmx
Copy link
Author

lmmx commentedAug 14, 2023
edited
Loading

TODO list

  • pip compile
  • Optional dependency import
  • Settings source edit
  • raiseSettingsError upon keyring variable access error
  • Linux support
    • Implemented viasecretstorage as described
  • Mac OSX support
  • Tests
  • Documentation

No comments 👍

  • pip compile
  • raiseSettingsError upon keyring variable access error
  • Linux support
  • Documentation

Optional dependency import

The example ofemail_validator goes like so:

  • TYPE_CHECKING conditional block that imports the optional dependency else sets it to Nonesource

  • Helper function calledimport_email_validator() that may raiseImportError, followed by differential declaration of a class that relies on it dependent on theTYPE_CHECKING context (if so, just declaring asAnnotated[str, ...]).source

Settings source edit

Also, I think we need to includeKeyringSettingsSource in sources ifkeyring is installed.

I hadn't thought of that, I just added it and let it default toNone, I'll review...

Mac support

OS X has asecurity module whichkeyring can access and adump-keychain method which would provide equivalent functionality. I need to look at this in more detail.

Tests

I used this as a dependency in an early stage projectmagic-scrapehere (dependency declaredhere) and by patching thepydantic_settings.KeyringSettingsSource.__call__ methodhere (equivalently I could also have patched the_read_keyring method) I have been able to test the integration of this with my package.

This already helped me uncover and fix bugs in the implementation (in case sensitivity handling), so testing should be easy to build off of this.

@dmontagudmontagu mentioned this pull requestAug 16, 2023
13 tasks
@lmmx
Copy link
Author

lmmx commentedAug 17, 2023
edited
Loading

I thought about the way pydantic is importing optional dependencies and as I recalled seeing a cleaner way in pandas, I reviewed their approach,import_optional_dependency.source ->example usage

The rest of the comment explains why I'm choosing a combination of both, if it's of interest!

Theirs is not type equivalent: in pydantic the TYPE_CHECKING block ensures the type of the module name is always an imported module's type, whereas in pandas the return type of the helper function isOptional. This is only permissible there because they use--skip-unannotated and said helper function has no annotated return type.

Theirs is however cleaner: the import site is not required to be wrapped inif TYPE_CHECKING, and indeed their_optional.py module has scaled well to handle many optional deps.

pydantic's approach usesglobal to redefine the module which was imported asNone in the else condition of theif TYPE_CHECKING block used to spoof the module type as if it were a non-Optional dependency.

We can parameteriseglobals()[package_name] instead and put theTYPE_CHECKING condition within the helper function, thereby achieving the same outcome (spoofed always-module that's actuallyOptional) but without the overhead at site of use. I expect this would look cleaner and hope this would therefore be acceptable in my PR.

In this case I would need to add multiple import lines to the block:

ifTYPE_CHECKING:importkeyringfromkeyring.backends.SecretServiceimportKeyringasSecretServiceKeyringelse:keyring=NoneSecretServiceKeyring=None

as opposed to one line, without aTYPE_CHECKING block

keyring,SecretServiceKeyring=import_optional_dependency("keyring","keyring.backends.SecretService.Keyring")

I'll put it together and fall back to the template of the single-module import function if I've misjudged part of this or if you don't like the idea.

@cisaacstern
Copy link

May I ask what the status of this PR is?

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@lmmx@hramezani@cisaacstern

[8]ページ先頭

©2009-2025 Movatter.jp