Skip to content

Instantly share code, notes, and snippets.

@lmazuel
Last active October 1, 2019 17:06
Show Gist options
  • Save lmazuel/9be97aba96106a438a742763bdebcc18 to your computer and use it in GitHub Desktop.
Save lmazuel/9be97aba96106a438a742763bdebcc18 to your computer and use it in GitHub Desktop.
Etag
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)
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)
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