Setup for backend services of Xamarin.Forms app.
- Running the Backend Locally
- Running the Backend on Azure
- API Documentation
Note: It's recommended to create all the following Azure services under the same resource group to organize all the services together.
-
python >= 3.7
-
config.py file with secrets
-
ML model endpoint
-
You can obain a tmdb API key for free as an open source developer using the above link.
pip install -r requirements.txt
Run the desired jupyter notebook (either SAR or Light GBM) and write down the REST url endpoint and the Bearer token returned at the end of the notebook by the following cell:
if service.compute_type == 'AKS':
url = service.scoring_uri
# Setup authentication using one of the keys from service
headers = dict(Authorization='Bearer {}'.format(service.get_keys()[0]))
else:
url = 'http://localhost:8889/score'
headers = None
print(headers)
print('Service URI: {}'.format(url))
The REST url endpoint SAR_MODEL_ENDPOINT and Bearer token SAR_BEARER_TOKEN will be needed in the config.py file.
Set up a single SQL database through the Azure Portal. The database will be storing the movielens dataset. In the database resource, head to Properties and then show database connection strings and finally click on ODBC. This string will give the necessary properties for the config file:
Driver={ODBC Driver 17 for SQL Server};Server=tcp:DATABASE_SERVER.database.windows.net,1433;Database=DATABASE_NAME;Uid=ADMIN_USERNAME@DATABASE_SERVER;Pwd=ADMIN_PASSWORD;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;
See DATABASE_README.md for more details.
Once your SQL database is set up, it should be connected with Azure Search to support powerful search capabilities.
- Create a new Azure Search service from the Azure Portal
- Head to your database in Azure Portal
- Under the Settings subtitle, click on Add Azure Search
- Select a Search Service: choose the Search Service you just created
- Connect your Data: choose the database with the movielens dataset and put in required credentials
- Customize Target Indexer: make sure all field names are checked for retrievable and searchable and choose genre and year for filterable and sortable.
- Create an Indexer: choose how often you want to indexer to run (i.e. how often the database will update). Once will suffice unless you plan on updating the movielens dataset in the database.
Once Azure Search is set up, obtain the search url and place it in config.py.
# Obtain these from the sar_webservice_poc and lgbm_webservice_pos notebook linked in the recommenders repository
sar_url = SAR_MODEL_ENDPOINT
sar_token = SAR_BEARER_TOKEN
lgbm_url = LGBM_MODEL_ENDPOINT
lgbm_token = LGBM_BEARER_TOKEN
# Obtain these from the "Setting up Azure SQL Database" step
server = DATABASE_SERVER
database = DATABASE_NAME
username = ADMIN_USERNAME
password = ADMIN_PASSWORD
driver = '{ODBC Driver 17 for SQL Server}'
# Obtain the API key from the tmdb website listed in the prerequisites
tmdb_key = TMDB_API_KEY
# Obtain from the "Setting up Azure Search" step
search_url = SEARCH_URL
Place the config.py file in the root backend directory. The backend set up is now finished.
python3 -m flask run
The backend API service should now be running on http://localhost:5000. See API.md for detailed documentation on available endpoints.
Note: Use the same Azure resource group as the previous Azure services.
First create an Azure Container Registry resource either on Azure Portal or through command line and keep track of the registry name when created.
az acr create --name REGISTRY_NAME --resource-group RESOURCE_GROUP --sku Basic
More info here.
az acr login --name REGISTRY_NAME
Alternatively:
docker login REGISTRY_NAME.azurecr.io
When prompted to log in, head over to Access Keys in the container registry resource, enable Admin user to obtain login credentials.
More info here.
az aks install-cli
Use the same AKS cluster as the one created by AzureML and skip the following step. If another is need, then it can be created either through Azure Portal or through command line:
az aks create -g RESOURCE_GROUP_NAME -n CLUSTER_NAME -location eastus
az aks get-credentials --resource-group RESOURCE_GROUP_NAME --name CLUSTER_NAME
docker build -f Dockerfile -t IMAGE_NAME .
docker tag IMAGE_NAME REGISTRY_NAME.azurecr.io/IMAGE_NAME:v1
docker push REGISTRY_NAME.azurecr.io/IMAGE_NAME
More info here. If you run into issues with ACR not being authorized to access AKS, then follow the instructions in this article.
If you want to test the container locally before deploying to AKS:
docker run -d -p 5000:5000 REGISTRY_NAME.azurecr.io/IMAGE_NAME:latest
It should then be running on http://localhost:5000.
Replace all the name
and app
fields with the name of your app.
First, inject the config.py file to AKS as a secret file so that the contents remain encrypted. Run the following command in the root directory of the backend folder:
kubectl create secret generic SECRET_NAME --from-file=config=PATH_TO_FILE
Note the SECRET_NAME and place it under the secretName
field in the app.yaml file.
Choose an IP address that you want the backend to be running on once it is deployed to AKS and place it under the loadBalancerIP
field.
See here for more info.
Replace the image field with the full url to the image on ACR from the previous steps.
See this article to grant your AKS cluster permission to access the container from ACR.
Using the app.yaml file, we deploy the backend to AKS.
kubectl apply -f app.yaml
Check if is is running with:
kubectl get pods
To check logs for any errors:
kubectl logs POD_ID