Skip to content

Commit

Permalink
Python with callback Samples (#844)
Browse files Browse the repository at this point in the history
* Async

* Update app.py

* Updated with callback

* Update app.py

* Removing Async, formatting

* Updating requirements
  • Loading branch information
mrm9084 authored Dec 30, 2023
1 parent d3dcf03 commit 6e43442
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 96 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,6 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
.env

# Python env
env/
20 changes: 10 additions & 10 deletions examples/Python/python-django-webapp-sample/hello_azure/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from django.shortcuts import render
from django.conf import settings

def index(request):

async def index(request):
# Refresh the configuration from App Configuration service.
settings.AZURE_APPCONFIGURATION.refresh()
# Update Django settings with the app configuration key-values
settings.CONFIG.update(settings.AZURE_APPCONFIGURATION)
settings.AZURE_APP_CONFIG.refresh()

context = {
"message": settings.CONFIG.get('message'),
"key": settings.CONFIG.get('secret_key'),
"color": settings.CONFIG.get('color'),
"font_size": settings.CONFIG.get('font_size')
}
return render(request, 'hello_azure/index.html', context)
"message": settings.CONFIG.get("message"),
"key": settings.CONFIG.get("secret_key"),
"color": settings.CONFIG.get("color"),
"font_size": settings.CONFIG.get("font_size"),
}
return render(request, "hello_azure/index.html", context)
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
"""

import os
from pathlib import Path
import configparser
from azure.appconfiguration.provider import load, SettingSelector, SentinelKey
from pathlib import Path
from azure.appconfiguration.provider import SettingSelector, WatchKey
from azure.appconfiguration.provider.aio import load
from azure.identity import DefaultAzureCredential

c_parser = configparser.ConfigParser()
c_parser.read('static/config.ini')
c_parser.read("static/config.ini")

CONFIG = c_parser['DEFAULT']
CONFIG = c_parser["DEFAULT"]

ENDPOINT = os.environ.get("AZURE_APPCONFIG_ENDPOINT")

Expand All @@ -30,17 +31,28 @@
# Select only key-values that start with 'testapp_settings_' and trim the prefix
selects = SettingSelector(key_filter="testapp_settings_*")
selects_secret = SettingSelector(key_filter="secret_key")
AZURE_APPCONFIGURATION = load(endpoint=ENDPOINT,
keyvault_credential=credential,
credential=credential,
selects=[selects, selects_secret],
trim_prefixes=["testapp_settings_"],
refresh_on=[SentinelKey("sentinel")]
)


def callback():
global AZURE_APP_CONFIG
# Update Django settings with the app configuration key-values
CONFIG.update(AZURE_APP_CONFIG)


AZURE_APP_CONFIG = load(
endpoint=ENDPOINT,
selects=[selects, selects_secret],
credential=credential,
keyvault_credential=credential,
trim_prefixes=["testapp_settings_"],
refresh_on=[WatchKey("sentinel")],
on_refresh_success=callback,
)


# Updates the config object with the app configuration key-values and resolved key vault reference values.
# This will override any values in the config object with the same key.
CONFIG.update(AZURE_APPCONFIGURATION)
CONFIG.update(AZURE_APP_CONFIG)

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Expand All @@ -50,7 +62,7 @@

# SECURITY WARNING: keep the secret key used in production secret!
# This is a key vault reference. The corresponding secret in key vault is returned.
SECRET_KEY = CONFIG.get('secret_key')
SECRET_KEY = CONFIG.get("secret_key")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
Expand All @@ -61,53 +73,53 @@
# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hello_azure'
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"hello_azure",
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = 'quickstartproject.urls'
ROOT_URLCONF = "quickstartproject.urls"

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]

WSGI_APPLICATION = 'quickstartproject.wsgi.application'
WSGI_APPLICATION = "quickstartproject.wsgi.application"


# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}

Expand All @@ -117,26 +129,26 @@

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]


# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/

LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = "en-us"

TIME_ZONE = 'UTC'
TIME_ZONE = "UTC"

USE_I18N = True

Expand All @@ -146,10 +158,10 @@
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATICFILES_DIRS = (str(BASE_DIR.joinpath('static')),)
STATIC_URL = 'static/'
STATICFILES_DIRS = (str(BASE_DIR.joinpath("static")),)
STATIC_URL = "static/"

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Django==4.1.13
whitenoise==6.4.0
azure-appconfiguration-provider==1.1.0b1
azure-appconfiguration-provider==1.1.0b3
azure-identity==1.12.0
71 changes: 37 additions & 34 deletions examples/Python/python-flask-webapp-sample/app.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
import os
from flask import Flask, render_template
from azure.appconfiguration.provider import load, SettingSelector, SentinelKey
from azure.appconfiguration.provider import load, SettingSelector, WatchKey
from azure.identity import DefaultAzureCredential

app = Flask(__name__)


ENDPOINT = os.environ.get("AZURE_APPCONFIG_ENDPOINT")

# Set up credentials and settings used in resolving key vault references.
ENDPOINT = os.environ.get("AZURE_APPCONFIG_ENDPOINT")
credential = DefaultAzureCredential()

# Load app configuration key-values and resolved key vault reference values.
# Select only key-values that start with 'testapp_settings_' and trim the prefix
selects = SettingSelector(key_filter="testapp_settings_*")
selects_secret = SettingSelector(key_filter="secret_key")
azure_app_config = load(endpoint=ENDPOINT,
keyvault_credential=credential,
credential=credential,
selects=[selects, selects_secret],
trim_prefixes=["testapp_settings_"],
refresh_on=[SentinelKey("sentinel")],
)

# App Configuration provider implements the Mapping Type which is compatible with the existing Flask config.
# Update Flask config mapping with loaded values in the App Configuration provider.


def callback():
app.config.update(azure_app_config)


global azure_app_config
azure_app_config = load(
endpoint=ENDPOINT,
selects=[selects, selects_secret],
credential=credential,
keyvault_credential=credential,
trim_prefixes=["testapp_settings_"],
refresh_on=[WatchKey("sentinel")],
on_refresh_success=callback,
)
app.config.update(azure_app_config)

@app.route('/')

@app.route("/")
def index():
# Refresh the configuration from App Configuration service.
azure_app_config.refresh()
# Update Flask config mapping with loaded values in the App Configuration provider.
app.config.update(azure_app_config)
print('Request for index page received')
context = {}
context['message'] = app.config.get('message')
context['font_size'] = app.config.get('font_size')
context['color'] = app.config.get('color')
context['key'] = app.config.get('secret_key') # This is a key vault reference. The corresponding secret in key vault is returned.
return render_template('index.html', **context)


if __name__ == '__main__':
app.run()
global azure_app_config
# Refresh the configuration from App Configuration service.
azure_app_config.refresh()

print("Request for index page received")
context = {}
context["message"] = app.config.get("message")
context["font_size"] = app.config.get("font_size")
context["color"] = app.config.get("color")
context["key"] = app.config.get(
"secret_key"
) # This is a key vault reference. The corresponding secret in key vault is returned.
return render_template("index.html", **context)


if __name__ == "__main__":
app.run()
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Flask==2.3.2
azure-identity==1.12.0
azure-appconfiguration-provider==1.1.0b2
azure-appconfiguration-provider==1.1.0b3

0 comments on commit 6e43442

Please sign in to comment.