For the final project, we are going to build an app called "Neighborly". Neighborly is a Python Flask-powered web application that allows neighbors to post advertisements for services and products they can offer.
The Neighborly project is comprised of a front-end application that is built with the Python Flask micro framework. The application allows the user to view, create, edit, and delete the community advertisements.
The application makes direct requests to the back-end API endpoints. These are endpoints that we will also build for the server-side of the application.
You can see an example of the deployed app below.
You will need to install the following locally:
On Mac, you can do this with:
# install pipenv
brew install pipenv
# install azure-cli
brew update && brew install azure-cli
# install azure function core tools
brew tap azure/functions
brew install azure-functions-core-tools@3
In case you need to return to the project later on, it is suggested to store any commands you use so you can re-create your work. You should also take a look at the project rubric to be aware of any places you may need to take screenshots as proof of your work (or else keep your resource up and running until you have passed, which may incur costs).
We need to set up the Azure resource group, region, storage account, and an app name before we can publish.
-
Create a resource group.
-
Create a storage account (within the previously created resource group and region).
-
Create an Azure Function App within the resource group, region and storage account.
- Note that app names need to be unique across all of Azure.
- Make sure it is a Linux app, with a Python runtime.
Example of successful output, if creating the app
myneighborlyapiv1
:Your Linux function app 'myneighborlyapiv1', that uses a consumption plan has been successfully created but is not active until content is published using Azure Portal or the Functions Core Tools.
-
Set up a Cosmos DB Account. You will need to use the same resource group, region and storage account, but can name the Cosmos DB account as you prefer. Note: This step may take a little while to complete (15-20 minutes in some cases).
-
Create a MongoDB Database in CosmosDB Azure and two collections, one for
advertisements
and one forposts
. -
Print out your connection string or get it from the Azure Portal. Copy/paste the primary connection string. You will use it later in your application.
Example connection string output:
bash-3.2$ Listing connection strings from COSMOS_ACCOUNT: + az cosmosdb keys list -n neighborlycosmos -g neighborlyapp --type connection-strings { "connectionStrings": [ { "connectionString": "AccountEndpoint=https://neighborlycosmos.documents.azure.com:443/;AccountKey=xxxxxxxxxxxx;", "description": "Primary SQL Connection String" }, { "connectionString": "AccountEndpoint=https://neighborlycosmos.documents.azure.com:443/;AccountKey=xxxxxxxxxxxxx;", "description": "Secondary SQL Connection String" } ... [other code omitted] ] }
-
Import Sample Data Into MongoDB.
-
Download dependencies:
# get the mongodb library brew install [email protected] # check if mongoimport lib exists mongoimport --version
-
Import the data from the
sample_data
directory for Ads and Posts to initially fill your app.Example successful import:
Importing ads data -------------------> 2020-05-18T23:30:39.018-0400 connected to: mongodb://neighborlyapp.mongo.cosmos.azure.com:10255/ 2020-05-18T23:30:40.344-0400 5 document(s) imported successfully. 0 document(s) failed to import. ... Importing posts data -------------------> 2020-05-18T23:30:40.933-0400 connected to: mongodb://neighborlyapp.mongo.cosmos.azure.com:10255/ 2020-05-18T23:30:42.260-0400 4 document(s) imported successfully. 0 document(s) failed to import.
-
-
Hook up your connection string into the NeighborlyAPI server folder. You will need to replace the url variable with your own connection string you copy-and-pasted in the last step, along with some additional information.
- Tip: Check out this post if you need help with what information is needed.
- Go to each of the
__init__.py
files in getPosts, getPost, getAdvertisements, getAdvertisement, deleteAdvertisement, updateAdvertisement, createAdvertisements and replace your connection string. You will also need to set the relateddatabase
andcollection
appropriately.
# inside getAdvertisements/__init__.py def main(req: func.HttpRequest) -> func.HttpResponse: logging.info('Python getAdvertisements trigger function processed a request.') try: # copy/paste your primary connection url here #------------------------------------------- url = "" #-------------------------------------------- client=pymongo.MongoClient(url) database = None # Feed the correct key for the database name to the client collection = None # Feed the correct key for the collection name to the database ... [other code omitted]
Make sure to do the same step for the other 6 HTTP Trigger functions.
-
Deploy your Azure Functions.
-
Test it out locally first.
# cd into NeighborlyAPI cd NeighborlyAPI # install dependencies pipenv install # go into the shell pipenv shell # test func locally func start
You may need to change
"IsEncrypted"
tofalse
inlocal.settings.json
if this fails.At this point, Azure functions are hosted in localhost:7071. You can use the browser or Postman to see if the GET request works. For example, go to the browser and type in:
# example endpoint for all advertisements http://localhost:7071/api/getadvertisements #example endpoint for all posts http://localhost:7071/api/getposts
-
Now you can deploy functions to Azure by publishing your function app.
The result may give you a live url in this format, or you can check in Azure portal for these as well:
Expected output if deployed successfully:
Functions in <APP_NAME>: createAdvertisement - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/createadvertisement deleteAdvertisement - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/deleteadvertisement getAdvertisement - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/getadvertisement getAdvertisements - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/getadvertisements getPost - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/getpost getPosts - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/getposts updateAdvertisement - [httpTrigger] Invoke url: https://<APP_NAME>.azurewebsites.net/api/updateadvertisement
Note: It may take a minute or two for the endpoints to get up and running if you visit the URLs.
Save the function app url https://<APP_NAME>.azurewebsites.net/api/ since you will need to update that in the client-side of the application.
-
We are going to update the Client-side settings.py
with published API endpoints. First navigate to the settings.py
file in the NeighborlyFrontEnd/ directory.
Use a text editor to update the API_URL to your published url from the last step.
# Inside file settings.py
# ------- For Local Testing -------
#API_URL = "http://localhost:7071/api"
# ------- For production -------
# where APP_NAME is your Azure Function App name
API_URL="https://<APP_NAME>.azurewebsites.net/api"
-
Deploy your client app. Note: Use a different app name here to deploy the front-end, or else you will erase your API. From within the
NeighborlyFrontEnd
directory:- Install dependencies with
pipenv install
- Go into the pip env shell with
pipenv shell
- Deploy your application to the app service. Note: It may take a minute or two for the front-end to get up and running if you visit the related URL.
Make sure to also provide any necessary information in
settings.py
to move from localhost to your deployment. - Install dependencies with
-
Create an Azure Registry and dockerize your Azure Functions. Then, push the container to the Azure Container Registry.
-
Create a Kubernetes cluster, and verify your connection to it with
kubectl get nodes
. -
Deploy app to Kubernetes, and check your deployment with
kubectl config get-contexts
.
- Create a Logic App that watches for an HTTP trigger. When the HTTP request is triggered, send yourself an email notification.
- Create a namespace for event hub in the portal. You should be able to obtain the namespace URL.
- Add the connection string of the event hub to the Azure Function.
Before completing this step, make sure to have taken all necessary screenshots for the project! Check the rubric in the classroom to confirm.
Clean up and remove all services, or else you will incur charges.
# replace with your resource group
RESOURCE_GROUP="<YOUR-RESOURCE-GROUP>"
# run this command
az group delete --name $RESOURCE_GROUP