Last active
October 1, 2019 17:06
-
-
Save lmazuel/9be97aba96106a438a742763bdebcc18 to your computer and use it in GitHub Desktop.
Etag
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import Flask, request | |
from flask_restful import Resource, Api | |
from azure.appconfiguration import AzureAppConfigurationClient | |
app = Flask(__name__) | |
api = Api(app) | |
class Config(Resource): | |
def __init__(self): | |
self.client = AzureAppConfigurationClient.from_connection_string(connection_str) | |
self.cache = {} | |
def _refresh_cache(): | |
# Let's have a thread running this in parallel every 10 seconds or so | |
# Shoudl lock but, meee, let's assume the cache is a locked one like. | |
for key, value in self.cache.items(): | |
if (result := self.client.get_configuration_setting(key, etag=value.etag)) is not None: | |
self.cache[key] = result | |
def get(self, key_id): | |
cache = self.cache.get(key_id, None) | |
etag = cache.etag if cache else None # Means I have no etag, probably should be '*' under the hood? As a client, impl detail. | |
try: | |
# Assuming I get None | |
return (self.client.get_configuration_setting(mykey, etag=etag) or cache).value | |
except ResourceNotFoundError: | |
return f"Resource {key_id} doesn't exist", 404 | |
def put(self, key_id): | |
value = request.form['value'] | |
# I want to cache it first if it exists already, so I have the etag | |
try: | |
cache = self.cache.setdefault(key_id, self.client.get_configuration_setting(mykey)) | |
etag = cache.etag | |
raise_condition = MatchConditions.IfModified | |
except ResourceNotFoundError: | |
etag = None # Means I have no etag, probably should be '*' under the hood? As a client, impl detail. | |
raise_condition = MatchConditions.IfExists | |
settings_to_send = ConfigurationSetting( | |
key=key_id, | |
value=value, | |
content_type="text/plain" | |
) | |
try: | |
self.set_configuration_setting(settings_to_send, etag=etag, raise_condition=raise_condition) | |
except ResourceExists: | |
return f"You can't create resource {key_id} anymore, someone did it before you", 400 | |
except ResourceModifed: | |
return f"Since the last time you saw resource {key_id} it has changed, can't write", 400 | |
except ResourceReadOnlyError: | |
return f"Resource {key_id} not writable, can't write", 400 | |
return f"Resource {key_id} updated" | |
api.add_resource(TodoSimple, '/<string:todo_id>') | |
if __name__ == '__main__': | |
app.run(debug=True) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
from azure.core.exceptions import ResourceNotFoundError, ResourceModified | |
from azure.core import MatchConditions | |
from azure.appconfiguration import AzureAppConfigurationClient | |
from azure.eventhub import IotHubClient | |
client = AzureAppConfigurationClient.from_connection_string(connection_str) | |
iothub_client = IotHubClient.from_connection_string(connection_str2) | |
mykey = 'key' | |
# Monitor value and send a notification if anything changes | |
# | |
# Version 1 | |
# I belive if nothing changed, I should receive None, since I don't think | |
# it's possible to store the None value. Discard this impl if it's possible | |
# to store a None value | |
cache = client.get_configuration_setting(mykey) | |
while True: | |
print(f"My value {cache.value}") | |
try: | |
if (current := client.get_configuration_setting(mykey, etag=cache.etag)) is not None: | |
iothub_client.send(f"Key {cache.key} changed") | |
cache = current | |
continue | |
except ResourceNotFoundError: | |
iothub_client.send(f"Resource {cache.key} doesn't exist anymore") | |
break | |
time.sleep(10) | |
# Version 2 | |
# If None is a possible value, use exception instead | |
cache = client.get_configuration_setting(mykey) | |
while True: | |
print(f"My value {cache.value}") | |
try: | |
cache = client.get_configuration_setting(mykey, etag=cache.etag, raise_condition=MatchConditions.IfModified) | |
except ResourceModifiedError as err: | |
iothub_client.send(f"Key {cache.key} changed") | |
cache = err.model | |
except ResourceNotFoundError: | |
iothub_client.send(f"Resource {cache.key} doesn't exist anymore") | |
break | |
time.sleep(10) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
from azure.core.exceptions import ResourceNotFoundError | |
from azure.appconfiguration import AzureAppConfigurationClient | |
client = AzureAppConfigurationClient.from_connection_string(connection_str) | |
mykey = 'key' | |
# Refresh as needed | |
# I want to show this value every 10 seconds. I expect to receive None if nothing has changed, so I use the one in cache | |
# Under the hood I probably received a 304 and I don't care at my level | |
cache = client.get_configuration_setting(mykey) | |
while True: | |
print(f"My value {cache.value}") | |
try: | |
cache = client.get_configuration_setting(mykey, etag=cache.etag) | |
except ResourceNotFoundError: | |
print(f"Resource {cache.key} doesn't exist anymore, quit") | |
break | |
time.sleep(10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment