Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Join us at AWS re:Invent 2024! Learn how to use MongoDB for AI use cases.
MongoDB Developer
Python
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
Pythonchevron-right

Scaling for Demand: Deploying Python Applications Using MongoDB Atlas on Azure App Service

Anaiya Raisinghani12 min read • Published Apr 05, 2023 • Updated Apr 02, 2024
AzureMongoDBPython
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Managing large amounts of data locally can prove to be a challenge, especially as the amount of saved data grows. Fortunately, there is an efficient solution available. By utilizing the features of Flask, MongoDB Atlas, and Azure App Service, you can build and host powerful web applications that are capable of storing and managing tons of data in a centralized, secure, and scalable manner. Say goodbye to unreliable local files and hello to a scalable solution.
This in-depth tutorial will teach you how to build a functional CRUD (Create, Read, Update, and Delete) Flask application that connects to a MongoDB Atlas database, and is hosted on Azure App Service. Using Azure App Service and MongoDB together can be a great way to build and host web applications. Azure App Service makes it easy to build and deploy web apps, while MongoDB is great for storing and querying large amounts of data. With this combination, you can focus on building your application and let Azure take care of the underlying infrastructure and scaling.
This tutorial is aimed at beginners, but feel free to skip through this article and focus on the aspects necessary to your project.
We are going to be making a virtual bookshelf filled with some of my favorite books. Within this bookshelf, we will have the power to add a new book, view all the books in our bookshelf, exchange a book for another one of my favorites, or remove a book we would like to read. At the end of our tutorial, our bookshelf will be hosted so anyone with our website link can enjoy our book list too.

Requirements

Before we begin, there are a handful of prerequisites we need:

Setting up a MongoDB Atlas cluster

Within MongoDB Atlas, we need to create a free cluster. Follow the instructions in our MongoDB Atlas Tutorial. Once your cluster has provisioned, create a database and collection within Atlas. Let’s name our database “bookshelf” and our collection “books.” Click on “Insert Document” and add in a book so that we have some data to start with. Your setup should look like this:
Alt Text: screenshot of our “books” collection showing the addition of “The Great Gatsby”
Now that we have our bookshelf set up, we are ready to connect to it and utilize our CRUD operations. Before we get started, let’s focus on how to properly connect.

Cluster security access

Now that we have our cluster provisioned and ready to use, we need to make sure we have proper database access. Through Atlas, we can do this by heading to the “Security” section on the left-hand side of the screen. Ensure that under “Database Access,” you have enabled a user with at least “Read and Write'' access. Under “Network Access,” ensure you’ve added in any and all IP addresses that you’re planning on accessing your database from. An easy way to do this is to set your IP address access to “0.0.0.0/0.” This allows you to access your cluster from any IP address. Atlas provides additional optional security features through Network Peering and Private Connections, using all the major cloud providers. Azure Private Link is part of this additional security feature, or if you’ve provisioned an M10 or above cluster, the use of Azure Virtual Private Connection.

Setting up a Python virtual environment

Before we open up our Visual Studio Code, use your terminal to create a directory for where your bookshelf project will live.
Once we have our directory made, open it up in VSCode and access the terminal inside of VSCode. We are going to set up our Python virtual environment. We do this so all our files have a fun spot to live, where nothing else already downloaded can bother them.
Set up your environment with:
1python3 -m venv venv
Activate your environment with:
1source venv/bin/activate
You’ll know you’re in your virtual environment when you see the little (venv) at the beginning of your hostname in your command line.
Once we are in our virtual environment, we are ready to set up our project requirements. A ‘requirements.txt’ file is used to specify the dependencies (various packages and their versions) required by the project to run. It helps ensure the correct versions of packages are installed when deploying the project to a new environment. This makes it much easier to reproduce the development environment and prevents any compatibility issues that may arise when using different versions of dependencies.

Setting up our ‘requirements.txt’ file

Our ‘requirements.txt’ file will consist of four various dependencies this project requires. The first is Flask. Flask is a web micro-framework for Python. It provides the basic tools for building web apps, such as routing and request handling. Flask allows for easy integration with other libraries and frameworks and allows for flexibility and customizability. If you’ve never worked with Flask before, do not worry. By the end of this tutorial, you will have a clear understanding of how useful Flask can be.
The second dependency we have is PyMongo. PyMongo is a Python library for working with MongoDB. It provides a convenient way to interact with MongoDB databases and collections. We will be using it to connect to our database.
The third dependency we have is Python-dotenv. This is a tool used to store and access important information, like passwords and secret keys, in a safe and secure manner. Instead of hard-coding this information, Python-dotenv allows us to keep this information in an environment variable in a separate file that isn’t shared with anyone else. Later in this tutorial, we will go into more detail on how to properly set up environment variables in our project.
The last dependency we have in our file is Black. Black is a code formatter for Python and it enforces a consistent coding style, making it easier for developers to read and maintain the code. By using a common code style, it can improve readability and maintainability.
Include these four dependencies in your ‘requirements.txt’ file.
1Flask==2.2.2
2pymongo==4.3.3
3python-dotenv==0.21.1
4black==22.12.0
This way, we can install all our dependencies in one step:
1pip install -r requirements.txt
Troubleshooting: After successfully installing PyMongo, a line in your terminal saying dnspython has been installed will likely pop up. It is worth noting that without dnspython properly downloaded, our next package dotenv won’t work. If, when attempting to run our script later, you are getting ModuleNotFoundError: No module named dotenv, include dnspython==2.2.1 in your ‘requirements.txt’ file and rerun the command from above.

Setting up our ‘app.py’ file

Our ‘app.py’ file is the main file where our code for our bookshelf project will live. Create a new file within our “azuredemo” directory and name it ‘app.py’. It is time for us to include our imports:
1import bson
2import os
3from dotenv import load_dotenv
4from flask import Flask, render_template, request
5from pymongo import MongoClient
6from pymongo.collection import Collection
7from pymongo.database import Database
Here we have our environment variable imports, our Flask imports, our PyMongo imports, and the BSON import we need in order to work with binary JSON data.
Once we have our imports set up, we are ready to connect to our MongoDB Atlas cluster and implement our CRUD functions, but first let’s test and make sure Flask is properly installed.
Run this very simple Flask app:
1app: Flask = Flask(__name__)
2# our initial form page
3@app.route(‘/’)
4def index():
5 return “Hi!”
Here, we continue on to creating a new Flask application object, which we named “app” and give it the name of our current file. We then create a new route for the application. This tells the server which URL to listen for and which function to run when that URL is requested. In this specific example, the route is the homepage, and the function that runs returns the string “Hi!”.
Run your flask app using:
1flask run
This opens up port 5000, which is Flask’s default port, but you can always switch the port you’re using by running the command:
1flask run -p [port number]
When we access http://127.0.0.1:5000, we see: screenshot of our port 5000 showing “Hi!” on the screen
So, our incredibly simple Flask app works! Amazing. Let’s now connect it to our database.

Connecting our Flask app to MongoDB

As mentioned above, we are going to be using a database environment variable to connect our database. In order to do this, we need to set up an .env file. Add this file in the same directory we’ve been working with and include your MongoDB connection string. Your connection string is a URL-like string that is used to connect to a MongoDB server. It includes all the necessary details to connect to your specific cluster. This is how your setup should look:
screenshot of file tree and the MongoDB connection string
Change out the username and password for your own. Make sure you have set the proper Network Access points from the paragraph above.
We want to use environment variables so we can keep them separate from our code. This way, there is privacy since the CONNECTION_STRING contains sensitive information. It is crucial for security and maintainability purposes.
Once you have your imports in, we need to add a couple lines of code above our Flask instantiation so we can connect to our .env file holding our CONNECTION_STRING, and connect to our Atlas database. At this point, your app.py should look like this:
1import bson
2import os
3from dotenv import load_dotenv
4from flask import Flask, render_template, request
5from pymongo import MongoClient
6from pymongo.collection import Collection
7from pymongo.database import Database
8# access your MongoDB Atlas cluster
9load_dotenv()
10connection_string: str = os.environ.get(“CONNECTION_STRING”)
11mongo_client: MongoClient = MongoClient(connection_string)
12
13# add in your database and collection from Atlas
14database: Database = mongo_client.get_database(“bookshelf”)
15collection: Collection = database.get_collection(“books”)
16# instantiating new object with “name”
17app: Flask = Flask(__name__)
18
19# our initial form page
20@app.route(‘/’)
21def index():
22 return “Hi!”
Let’s test app.py and ensure our connection to our cluster is properly in place. Add in these two lines after your collection = database[“books”] line and before your #instantiating new object with name line to check and make sure your Flask application is really connected to your database:
1book = {“title”: “The Great Gatsby”, “author”: “F. Scott Fitzgerald”, “year”: 1925}
2collection.insert_one(book)
Run your application, access Atlas, and you should see the additional copy of “The Great Gatsby” added.
screenshot of our “books” collection showing both copies of “The Great Gatsby”
Amazing! We have successfully connected our Flask application to MongoDB. Let’s start setting up our CRUD (Create, Read, Update, Delete) functions.
Feel free to delete those two added lines of code and manually remove both the Gatsby documents from Atlas. This was for testing purposes!

Creating CRUD functions

Right now, we have hard-coded in our “Hi!” on the screen. Instead, it’s easier to render a template for our homepage. To do this, create a new folder called “templates” in your directory. Inside of this folder, create a file called: index.html. Here is where all the HTML and CSS for our homepage will go. This is highly customizable and not the focus of the tutorial, so please access this code from my Github (or make your own!).
Once our index.html file is complete, let’s link it to our app.py file so we can read everything correctly. This is where the addition of the render_template import comes in. Link your index.html file in your initial form page function like so:
1# our initial form page
2@app.route(‘/’)
3def index():
4 return render_template(“index.html”)
When you run it, this should be your new homepage when accessing http://127.0.0.1:5000/:
screenshot of the updated homepage
We are ready to move on to our CRUD functions.

Create and read functions

We are combining our two Create and Read functions. This will allow us to add in a new book to our bookshelf, and be able to see all the books we have in our bookshelf depending on which request method we choose.
1# CREATE and READ
2@app.route('/books', methods=["GET", "POST"])
3def books():
4 if request.method == 'POST':
5 # CREATE
6 book: str = request.json['book']
7 pages: str = request.json['pages']
8
9 # insert new book into books collection in MongoDB
10 collection.insert_one({"book": book, "pages": pages})
11
12 return f"CREATE: Your book {book} ({pages} pages) has been added to your bookshelf.\n "
13
14 elif request.method == 'GET':
15 # READ
16 bookshelf = list(collection.find())
17 novels = []
18
19 for titles in bookshelf:
20 book = titles['book']
21 pages = titles['pages']
22 shelf = {'book': book, 'pages': pages}
23 novels.insert(0,shelf)
24
25 return novels
This function is connected to our ‘/books’ route and depending on which request method we send, we can either add in a new book, or see all the books we have already in our database. We are not going to be validating any of the data in this example because it is out of scope, but please use Postman, cURL, or a similar tool to verify the function is properly implemented. For this function, I inserted:
1{
2 “book”: “The Odyssey”,
3 “pages”: 384
4}
If we head over to our Atlas portal, refresh, and check on our “bookshelf” database and “books” collection, this is what we will see:
screenshot of our “books” collection showing “The Odyssey”
Let’s insert one more book of our choosing just to add some more data to our database. I’m going to add in “The Perks of Being a Wallflower.”
Amazing! Read the database collection back and you should see both novels.
Let’s move onto our UPDATE function.

Update

For this function, we want to exchange a current book in our bookshelf with a different book.
1# UPDATE
2@app.route("/books/<string:book_id>", methods = ['PUT'])
3def update_book(book_id: str):
4 new_book: str = request.json['book']
5 new_pages: str = request.json['pages']
6 collection.update_one({"_id": bson.ObjectId(book_id)}, {"$set": {"book": new_book, "pages": new_pages}})
7
8 return f"UPDATE: Your book has been updated to: {new_book} ({new_pages} pages).\n"
This function allows us to exchange a book we currently have in our database with a new book. The exchange takes place via the book ID. To do so, access Atlas and copy in the ID you want to use and include this at the end of the URL. For this, I want to switch “The Odyssey” with “The Stranger”. Please use your testing tool to communicate to the update endpoint and view the results in Atlas.
Once you hit send and refresh your Atlas database, you’ll see: screenshot of our “books” collection with “The Stranger” and “The Perks of Being a Wallflower”
“The Odyssey” has been exchanged with “The Stranger”!
Now, let’s move onto our last function: the DELETE function.

Delete

1# DELETE
2@app.route("/books/<string:book_id>", methods = ['DELETE'])
3def remove_book(book_id: str):
4 collection.delete_one({"_id": bson.ObjectId(book_id)})
5
6 return f"DELETE: Your book (id = {book_id}) has been removed from your bookshelf.\n"
This function allows us to remove a specific book from our bookshelf. Similarly to the UPDATE function, we need to specify which book we want to delete through the URL route using the novels ID. Let’s remove our latest book from the bookshelf to read, “The Stranger”.
Communicate with the delete endpoint and execute the function.
In Atlas our results are shown:
screenshot of the “books” collection showing “The Perks of Being a Wallflower”
“The Stranger” has been removed!
Congratulations, you have successfully created a Flask application that can utilize CRUD functionalities, while using MongoDB Atlas as your database. That’s huge. But…no one else can use your bookshelf! It’s only hosted locally. Microsoft Azure App Service can help us out with this. Let’s host our Flask app on App Service.

Host your application on Microsoft Azure App Service

We are using Visual Studio Code for this demo, so make sure you have installed the Azure extension and you have signed into your subscription. There are other ways to work with Azure App Service, and to use Visual Studio Code is a personal preference.
screenshot of app.py and the Azure Resources panel in VSCode
If you’re properly logged in, you’ll see your Azure subscription on the left-hand side.
Click the (+) sign next to Resources: screenshot of where to click the (+) sign to create a new resource in VSCode
Click on “Create App Service Web App”: screenshot of how to select the proper resource for this project
Enter a new name. This will serve as your website URL, so make sure it’s not too hectic: screenshot of how to enter a unique name for the new web app
Select your runtime stack. Mine is Python 3.9: screenshot of which runtime stack to select for this project
Select your pricing tier. The free tier will work for this demo. screenshot of which pricing tier to select for this project
In the Azure Activity Log, you will see the web app being created.  screenshot of the output once your web app is created
You will be asked to deploy your web app, and then choose the folder you want to deploy: screenshot of which folder to choose to deploy your web app
It will start deploying, as you’ll see through the “Output Window” in the Azure App Service Log.
Once it’s done, you’ll see a button that says “Browse Website.” Click on it. screenshot of output once your project is deployed and how to view it
As you can see, our application is now hosted at a different location! It now has its own URL. screenshot of our project hosted on a different Azure server
Let’s make sure we can still utilize our CRUD operations with our new URL. Test again for each function.
At each step, if we refresh our MongoDB Atlas database, we will see these changes take place there as well. Great job!

Conclusion

Congratulations! We have successfully created a Flask application from scratch, connected it to our MongoDB database, and hosted it on Azure App Service. These skills will continue to come in handy and I hope you enjoyed the journey. Separately, Azure App Service and MongoDB host a variety of benefits. Together, they are unstoppable! Combined, they provide a powerful platform for building and scaling web applications that can handle large amounts of data. Azure App Service makes it easy to deploy and scale web apps, while MongoDB provides a flexible and scalable data storage solution.
Get information on MongoDB Atlas, Azure App Service, and Flask.
If you liked this tutorial and would like to dive even further into MongoDB Atlas and the functionalities available, please view my YouTube video.

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Getting Started With MongoDB and AWS CodeWhisperer


Sep 26, 2024 | 3 min read
Article

Multi-agent Systems With AutoGen and MongoDB


Sep 18, 2024 | 10 min read
Tutorial

Simplify Semantic Search With LangChain and MongoDB


Oct 28, 2024 | 4 min read
Tutorial

How to Choose the Best Embedding Model for Your LLM Application


Nov 07, 2024 | 16 min read
Table of Contents