-
Notifications
You must be signed in to change notification settings - Fork 2
Swap to Sanitization Strategies in store init #210
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
Changes from all commits
b367cc4
23c348d
f18650f
a701a5a
b5c5bb3
85d85c7
b3ab611
0e08bf6
f0a86f0
4dceee2
632c5dc
abf92d3
93fab79
2a14639
9ce20b6
506939a
85920ae
0cdbf25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
|
|
||
| from key_value.shared.utils.compound import compound_key | ||
| from key_value.shared.utils.managed_entry import ManagedEntry | ||
| from key_value.shared.utils.sanitization import HybridSanitizationStrategy | ||
| from key_value.shared.utils.sanitization import HybridSanitizationStrategy, SanitizationStrategy | ||
| from key_value.shared.utils.sanitize import ALPHANUMERIC_CHARACTERS | ||
| from typing_extensions import override | ||
|
|
||
|
|
@@ -21,12 +21,36 @@ | |
| ALLOWED_KEY_COLLECTION_CHARACTERS: str = ALPHANUMERIC_CHARACTERS | ||
|
|
||
|
|
||
| class KeyringV1KeySanitizationStrategy(HybridSanitizationStrategy): | ||
| def __init__(self) -> None: | ||
| super().__init__( | ||
| replacement_character="_", | ||
| max_length=MAX_KEY_COLLECTION_LENGTH, | ||
| allowed_characters=ALLOWED_KEY_COLLECTION_CHARACTERS, | ||
| ) | ||
|
|
||
|
|
||
| class KeyringV1CollectionSanitizationStrategy(HybridSanitizationStrategy): | ||
| def __init__(self) -> None: | ||
| super().__init__( | ||
| replacement_character="_", | ||
| max_length=MAX_KEY_COLLECTION_LENGTH, | ||
| allowed_characters=ALLOWED_KEY_COLLECTION_CHARACTERS, | ||
| ) | ||
|
Comment on lines
+33
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider reducing duplication between strategy classes.
🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| class KeyringStore(BaseStore): | ||
| """Python keyring-based key-value store using keyring library. | ||
|
|
||
| This store uses the Python keyring to persist key-value pairs. Each entry is stored | ||
| This store uses the system's keyring to persist key-value pairs. Each entry is stored | ||
| as a password in the keychain with the combination of collection and key as the username. | ||
|
|
||
| This store has specific restrictions on what is allowed in keys and collections. Keys and collections are not sanitized | ||
| by default which may result in errors when using the store. | ||
|
|
||
| To avoid issues, you may want to consider leveraging the `KeyringV1KeySanitizationStrategy` | ||
| and `KeyringV1CollectionSanitizationStrategy` strategies. | ||
|
|
||
| Note: TTL is not natively supported by Python keyring, so TTL information is stored | ||
| within the JSON payload and checked at retrieval time. | ||
| """ | ||
|
|
@@ -38,23 +62,23 @@ def __init__( | |
| *, | ||
| service_name: str = DEFAULT_KEYCHAIN_SERVICE, | ||
| default_collection: str | None = None, | ||
| key_sanitization_strategy: SanitizationStrategy | None = None, | ||
| collection_sanitization_strategy: SanitizationStrategy | None = None, | ||
| ) -> None: | ||
| """Initialize the Python keyring store. | ||
|
|
||
| Args: | ||
| service_name: The service name to use in the keychain. Defaults to "py-key-value". | ||
| default_collection: The default collection to use if no collection is provided. | ||
| key_sanitization_strategy: The sanitization strategy to use for keys. | ||
| collection_sanitization_strategy: The sanitization strategy to use for collections. | ||
| """ | ||
| self._service_name = service_name | ||
|
|
||
| sanitization_strategy = HybridSanitizationStrategy( | ||
| replacement_character="_", max_length=MAX_KEY_COLLECTION_LENGTH, allowed_characters=ALLOWED_KEY_COLLECTION_CHARACTERS | ||
| ) | ||
|
|
||
| super().__init__( | ||
| default_collection=default_collection, | ||
| collection_sanitization_strategy=sanitization_strategy, | ||
| key_sanitization_strategy=sanitization_strategy, | ||
| collection_sanitization_strategy=collection_sanitization_strategy, | ||
| key_sanitization_strategy=key_sanitization_strategy, | ||
| ) | ||
|
|
||
| @override | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| from key_value.aio.stores.memcached.store import MemcachedStore | ||
| from key_value.aio.stores.memcached.store import MemcachedStore, MemcachedV1KeySanitizationStrategy | ||
|
|
||
| __all__ = ["MemcachedStore"] | ||
| __all__ = ["MemcachedStore", "MemcachedV1KeySanitizationStrategy"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore legacy load compatibility.
Existing indices still hold
"value"as the old JSON string. Calling.get("flattened")on that string raises immediately, breaking every read after deployment. Please keep the guard so both legacy and new documents deserialize.🤖 Prompt for AI Agents