🧳 Part 1: Day 1 - 3
🧳 Part 2: Day 4 - 6
🧳 Part 3: Day 7 - 9
🧳 Part 4: Day 10 - 12
🧳 Part 5: Day 13 - 15
🧳 Part 6: Day 16 - 18
🧳 Part 7: Day 19 - 21
🧳 Part 8: Day 22 - 24
🧳 Part 9: Day 25 - 27
🧳 Part 10: Day 28 - 30
- 📘 Day 25
- 📘 Day 26
- 📘 Day 27
- Python with MongoDB
- MongoDB
- SQL versus NoSQL
- Getting Connection String(MongoDB URI)
- Connecting Flask application to MongoDB Cluster
- Creating a database and collection
- Inserting many documents to collection
- MongoDB Find
- Find with Query
- Find query with modifier
- Limiting documents
- Find with sort
- Update with query
- Delete Document
- Drop a collection
- 💻 Exercises: Day 27 GIVE FEEDBACK: http://thirtydayofpython-api.herokuapp.com/feedback
- MongoDB
Pandas is an open source,high-performance, easy-to-use data structures and data analysis tools for the Python programming language. Pandas adds data structures and tools designed to work with table-like data which is Series and Data Frames Pandas provides tools for data manipulation: reshaping, merging, sorting, slicing, aggregation and imputation.
pip install conda
conda install pandas
Pandas data structure is based on Series and DataFrames A series is a column and a DataFrame is a multidimensional table made up of collection of series. In order to create a pandas series we should use numpy to create a one dimensional arrays or a python list. Let's see an example of a series:
Names pandas Series
Countries Series
Cities Series
As you can see, pandas series is just one column data. If we want to have multiple columns we use data frames. The example below shows pandas DataFrames.
Let's see, an example of a pandas data frame:
Data from is a collection of rows and columns. Look at the table below it has many columns than the above
Next, we will see how to import pandas and how to create Series and DataFrames using pandas
import pandas as pd # importing pandas as pd
import numpy as np # importing numpy as np
nums = [1, 2, 3, 4,5]
s = pd.Series(nums)
s
0 1
1 2
2 3
3 4
4 5
dtype: int64
nums = [1, 2, 3, 4, 5]
s = pd.Series(nums, index=[1, 2, 3, 4, 5])
s
1 1
2 2
3 3
4 4
5 5
dtype: int64
fruits = ['Orange','Banana','Mangao']
fruits = pd.Series(fruits, index=[1, 2, 3])
fruits
1 Orange
2 Banana
3 Mangao
dtype: object
dct = {'name':'Asabeneh','country':'Finland','city':'Helsinki'}
s = pd.Series(dct)
s
name Asabeneh
country Finland
city Helsinki
dtype: object
s = pd.Series(10, index = [1, 2,3])
s
1 10
2 10
3 10
dtype: int64
s = pd.Series(np.linspace(5, 20, 10)) # linspace(starting, end, items)
s
0 5.000000
1 6.666667
2 8.333333
3 10.000000
4 11.666667
5 13.333333
6 15.000000
7 16.666667
8 18.333333
9 20.000000
dtype: float64
Pandas data frames can be created in different ways.
data = [
['Asabeneh', 'Finland', 'Helsink'],
['David', 'UK', 'London'],
['John', 'Sweden', 'Stockholm']
]
df = pd.DataFrame(data, columns=['Names','Country','City'])
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Names | Country | City | |
---|---|---|---|
0 | Asabeneh | Finland | Helsink |
1 | David | UK | London |
2 | John | Sweden | Stockholm |
data = {'Name': ['Asabeneh', 'David', 'John'], 'Country':[
'Finland', 'UK', 'Sweden'], 'City': ['Helsiki', 'London', 'Stockholm']}
df = pd.DataFrame(data)
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | |
---|---|---|---|
0 | Asabeneh | Finland | Helsiki |
1 | David | UK | London |
2 | John | Sweden | Stockholm |
data = [
{'Name': 'Asabeneh', 'Country': 'Finland', 'City': 'Helsinki'},
{'Name': 'David', 'Country': 'UK', 'City': 'London'},
{'Name': 'John', 'Country': 'Sweden', 'City': 'Stockholm'}]
df = pd.DataFrame(data)
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | |
---|---|---|---|
0 | Asabeneh | Finland | Helsinki |
1 | David | UK | London |
2 | John | Sweden | Stockholm |
import pandas as pd
df = pd.read_csv('./data/weight-height.csv')
Let's read only the first 5 rows using head()
df.head() # give five rows we can increase the number of rows by passing argument to the head() method
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Gender | Height | Weight | |
---|---|---|---|
0 | Male | 73.847017 | 241.893563 |
1 | Male | 68.781904 | 162.310473 |
2 | Male | 74.110105 | 212.740856 |
3 | Male | 71.730978 | 220.042470 |
4 | Male | 69.881796 | 206.349801 |
As you can see the csv file has three rows:Gender, Height and Weight. But we don't know the number of rows. Let's use shape meathod.
df.shape # as you can see 10000 rows and three columns
(10000, 3)
Let's get all the columns using columns.
df.columns
Index(['Gender', 'Height', 'Weight'], dtype='object')
Let's read only the last 5 rows using tail()
df.tail() # tails give the last five rows, we can increase the rows by passing argument to tail method
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Gender | Height | Weight | |
---|---|---|---|
9995 | Female | 66.172652 | 136.777454 |
9996 | Female | 67.067155 | 170.867906 |
9997 | Female | 63.867992 | 128.475319 |
9998 | Female | 69.034243 | 163.852461 |
9999 | Female | 61.944246 | 113.649103 |
Now, lets get specif colums using the column key
heights = df['Height'] # this is now a a series
heights
0 73.847017
1 68.781904
2 74.110105
3 71.730978
4 69.881796
...
9995 66.172652
9996 67.067155
9997 63.867992
9998 69.034243
9999 61.944246
Name: Height, Length: 10000, dtype: float64
weights = df['Weight'] # this is now a series
weights
0 241.893563
1 162.310473
2 212.740856
3 220.042470
4 206.349801
...
9995 136.777454
9996 170.867906
9997 128.475319
9998 163.852461
9999 113.649103
Name: Weight, Length: 10000, dtype: float64
len(heights) == len(weights)
True
heights.describe() # give statisical information about height data
count 10000.000000
mean 66.367560
std 3.847528
min 54.263133
25% 63.505620
50% 66.318070
75% 69.174262
max 78.998742
Name: Height, dtype: float64
weights.describe()
count 10000.000000
mean 161.440357
std 32.108439
min 64.700127
25% 135.818051
50% 161.212928
75% 187.169525
max 269.989699
Name: Weight, dtype: float64
df.describe() # describe can also give statistical information from a datafrom
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Height | Weight | |
---|---|---|
count | 10000.000000 | 10000.000000 |
mean | 66.367560 | 161.440357 |
std | 3.847528 | 32.108439 |
min | 54.263133 | 64.700127 |
25% | 63.505620 | 135.818051 |
50% | 66.318070 | 161.212928 |
75% | 69.174262 | 187.169525 |
max | 78.998742 | 269.989699 |
Modifying a DataFrame * We can create a new DataFrame * We can create a new column and add to DataFrame, * we can remove an existing column from DataFrame, * we can modify an existing column from DataFrame, * we can change the data type of column values from DataFrame
All the time, first we import the necessary packages. Now, lets import pandas and numpy two best friends ever.
import pandas as pd
import numpy as np
data = [
{"Name": "Asabeneh", "Country":"Finland","City":"Helsinki"},
{"Name": "David", "Country":"UK","City":"London"},
{"Name": "John", "Country":"Sweden","City":"Stockholm"}]
df = pd.DataFrame(data)
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | |
---|---|---|---|
0 | Asabeneh | Finland | Helsinki |
1 | David | UK | London |
2 | John | Sweden | Stockholm |
Adding column in DataFrame is like adding a key in dictionary.
First let's use the previous example to create a DataFrame. After we create the DataFrame, we will start modifying the columns and column values.
Let's add a weight column in the DataFrame
weights = [74, 78, 69]
df['Weight'] = weights
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | |
---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 |
1 | David | UK | London | 78 |
2 | John | Sweden | Stockholm | 69 |
Let's add a height column in the DataFrame
heights = [173, 175, 169]
df['Height'] =heights
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | |
---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 173 |
1 | David | UK | London | 78 | 175 |
2 | John | Sweden | Stockholm | 69 | 169 |
As you can see from the above DataFrame, now we new added columns, the Weight and Height. Let's add one additional column by called BMI(Body Mass Index) by calculating their BMI using thier mass and height. BMI is mass divided by height square meter(Weight/Height * Height).
As you can see, the hieght is in centimeter, so we shoud change the height to meter. So, let's modify the height row
df['Height'] = df['Height'] * 0.01
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | |
---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 |
1 | David | UK | London | 78 | 1.75 |
2 | John | Sweden | Stockholm | 69 | 1.69 |
# Using function makes our code clean but you can just calculate the bmi without function
def calculate_bmi ():
weights = df['Weight']
heights = df['Height']
bmi = []
for w,h in zip(weights, heights):
b = w/(h*h)
bmi.append(b)
return bmi
bmi = calculate_bmi()
df['BMI'] = bmi
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | |
---|---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 | 24.725183 |
1 | David | UK | London | 78 | 1.75 | 25.469388 |
2 | John | Sweden | Stockholm | 69 | 1.69 | 24.158818 |
The BMI of the above DataFrame has is float with many significant digits after decimal. Let's make it to have only one significant digit after point.
df['BMI'] = round(df['BMI'], 1)
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | |
---|---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 | 24.7 |
1 | David | UK | London | 78 | 1.75 | 25.5 |
2 | John | Sweden | Stockholm | 69 | 1.69 | 24.2 |
The information in the DataFrame seems not yet complete, let's add birth year and current year columns.
birth_year = ['1769', '1985', '1990']
current_year = pd.Series(2019, index=[0, 1,2])
df['Birth Year'] = birth_year
df['Current Year'] = current_year
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | Birth Year | Current Year | |
---|---|---|---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 | 24.7 | 1769 | 2019 |
1 | David | UK | London | 78 | 1.75 | 25.5 | 1985 | 2019 |
2 | John | Sweden | Stockholm | 69 | 1.69 | 24.2 | 1990 | 2019 |
df.Weight.dtype
dtype('int64')
df['Birth Year'].dtype # it give string object , we should change this to number
dtype('O')
df['Birth Year'] = df['Birth Year'].astype('int')
df['Birth Year'].dtype # let's check the data type now
dtype('int64')
df['Current Year'] = df['Current Year'].astype('int')
df['Current Year'].dtype
dtype('int64')
Now, the column values of birth year and current year are integers. We can calculate the age.
ages = df['Current Year'] - df['Birth Year']
ages
0 250
1 34
2 29
dtype: int64
df['Ages'] = ages
df
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | Birth Year | Current Year | Ages | |
---|---|---|---|---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 | 24.7 | 1769 | 2019 | 250 |
1 | David | UK | London | 78 | 1.75 | 25.5 | 1985 | 2019 | 34 |
2 | John | Sweden | Stockholm | 69 | 1.69 | 24.2 | 1990 | 2019 | 29 |
The person in the first row lives 250 years. It is unlikely for someone to live 250 years. Either it is a typo or the data is cooked. So lets fill that data with average of the columns without including outlier.
mean = (34 + 29)/ 2
mean = (34 + 29)/ 2
mean
31.5
df[df['Ages'] > 120]
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | Birth Year | Current Year | Ages | |
---|---|---|---|---|---|---|---|---|---|
0 | Asabeneh | Finland | Helsinki | 74 | 1.73 | 24.7 | 1769 | 2019 | 250 |
df[df['Ages'] < 120]
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
Name | Country | City | Weight | Height | BMI | Birth Year | Current Year | Ages | |
---|---|---|---|---|---|---|---|---|---|
1 | David | UK | London | 78 | 1.75 | 25.5 | 1985 | 2019 | 34 |
2 | John | Sweden | Stockholm | 69 | 1.69 | 24.2 | 1990 | 2019 | 29 |
df['Ages'] = df[df['Ages'] > 120]
- Read the hacker_ness.csv file from data directory
- Get the first five rows
- Get the last five rows
- Get the title column as pandas series
- Count the number of rows and columns
- Filter the titles which contain python
- Filter the titles which contain JavaScript
- Explore the data and make sense of the data
Python is a general purpose programming language and it can be used for many places. In this section, we will see how we use python for the web. There are many python web frame works. Django and Flask are the most popular ones. Today, we will see how to use Flask for web development.
Flask is a web development framework written in python. Flask uses Jinja2 template engine. Flask can be also used with other modern frond libraries such as react. If you did not install the virtualenv package ye install it first. Virtual environment will allows to isolate project dependencies.
After completing all the step your project file structure should look like this:
├── Procfile
├── app.py
├── env
│ ├── bin
├── requirements.txt
├── static
│ └── css
│ └── main.css
└── templates
├── about.html
├── home.html
├── layout.html
├── post.html
└── result.html
Follow, the following steps to get started with Flask. Step 1: install virtualenv using the following command.
pip install virtualenv
Step 2:
asabeneh@Asabeneh:~/Desktop$ mkdir python_for_web
asabeneh@Asabeneh:~/Desktop$ cd python_for_web/
asabeneh@Asabeneh:~/Desktop/python_for_web$ virtualenv env
asabeneh@Asabeneh:~/Desktop/python_for_web$ source env/bin/activate
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip install Flask
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$
We created a project director named pythonfor_web. Inside the project we created a virtual environment _env which could be any name but I prefer to call it env. Then we activated the virtual environment. We used pip freeze to check the installed packages in the project directory. The result of pip freeze was empty because a package was not installed yet.
Now, let's create app.py file in the project directory and write the following code. The app.py file will be the main file in the project. The following code has flask module, os module.
The home route.
# let's import the flask
from flask import Flask
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return '<h1>Welcome</h1>'
@app.route('/about')
def about():
return '<h1>About us</h1>'
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
After you run python app.py check local host 5000.
Let's add additional route. Creating about route
# let's import the flask
from flask import Flask
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return '<h1>Welcome</h1>'
@app.route('/about')
def about():
return '<h1>About us</h1>'
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
Now, we added the about route in the above code. How about if we want to render an HTML file instead of string? It is possible to render HTML file using the function render_templae. Let's create a folder called templates and create home.html and about.html in the project directory. Let's also import the render_template function from flask.
Create the HTML files inside templates folder.
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home</title>
</head>
<body>
<h1>Welcome Home</h1>
</body>
</html>
about.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
app.py
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
return render_template('home.html')
@app.route('/about')
def about():
return render_template('about.html')
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
As you can see to go to different pages or to navigate we need a navigation. Let's add a link to each page or let's create a layout which we use to every page.
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
Now, we can navigate between the pages using the above link. Let's create additional page which handle form data. You can call it any name, I like to call it post.html.
We can inject data to the HTML files using Jinja2 template engine.
# let's import the flask
from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module
app = Flask(__name__)
@app.route('/') # this decorator create the home route
def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('home.html', techs=techs, name = name, title = 'Home')
@app.route('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('about.html', name = name, title = 'About Us')
@app.route('/post')
def post():
name = 'Text Analyzer'
return render_template('post.html', name = name, title = name)
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
Let's see the templates too:
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
<h1>Welcome to {{name}}</h1>
{% for tech in techs %}
<ul>
<li>{{tech}}</li>
</ul>
{% endfor %}
</body>
</html>
about.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About Us</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
<h1>About Us</h1>
<h2>{{name}}</h2>
</body>
</html>
In the template files, there are lots of repeated codes, we can write a layout and we can remove the repetition. Let's create layout.html inside the templates folder. After we create the layout we will import to every file.
layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://fonts.googleapis.com/css?family=Lato:300,400|Nunito:300,400|Raleway:300,400,500&display=swap"
rel="stylesheet"
/>
<link
rel="stylesheet"
href="{{ url_for('static', filename='css/main.css') }}"
/>
{% if title %}
<title>30 Days of Python - {{ title}}</title>
{% else %}
<title>30 Days of Python</title>
{% endif %}
</head>
<body>
<header>
<div class="menu-container">
<div>
<a class="brand-name nav-link" href="/">30DaysOfPython</a>
</div>
<ul class="nav-lists">
<li class="nav-list">
<a class="nav-link active" href="{{ url_for('home') }}">Home</a>
</li>
<li class="nav-list">
<a class="nav-link active" href="{{ url_for('about') }}">About</a>
</li>
<li class="nav-list">
<a class="nav-link active" href="{{ url_for('post') }}"
>Text Analyzer</a
>
</li>
</ul>
</div>
</header>
<main>
{% block content %} {% endblock %}
</main>
</body>
</html>
Now, lets remove all the repeated code in the other template files and import the layout.html. The href is using url_for function with the name of the route function to connect each navigation route.
home.html
{% extends 'layout.html' %} {% block content %}
<div class="container">
<h1>Welcome to {{name}}</h1>
<p>
This application clean texts and analyse the number of word, characters and
most frequent words in the text. Check it out by click text analyzer at the
menu. You need the following technologies to build this web application:
</p>
<ul class="tech-lists">
{% for tech in techs %}
<li class="tech">{{tech}}</li>
{% endfor %}
</ul>
</div>
{% endblock %}
about.html
{% extends 'layout.html' %} {% block content %}
<div class="container">
<h1>About {{name}}</h1>
<p>
This is a 30 days of python programming challenge. If you have been coding
this far, you are awesome. Congratulations for the job well done!
</p>
</div>
{% endblock %}
post.html
{% extends 'layout.html' %} {% block content %}
<div class="container">
<h1>Text Analyzer</h1>
<form action="https://thirtydaysofpython-v1.herokuapp.com/post" method="POST">
<div>
<textarea rows="25" name="content" autofocus></textarea>
</div>
<div>
<input type="submit" class="btn" value="Process Text" />
</div>
</form>
</div>
{% endblock %}
Request methods, there are different request methods(GET, POST, PUT, DELETE) are the common request methods which allow us to do CRUD(Create Read Update Delete) operation.
In the post, route we will use GET and POST method alternative depending on the type of request, check how it looks in the code below. The request method is a function to handle request methods and also to access form data. app.py
# let's import the flask
from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module
app = Flask(__name__)
# to stop caching static file
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
@app.route('/') # this decorator create the home route
def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('home.html', techs=techs, name = name, title = 'Home')
@app.route('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('about.html', name = name, title = 'About Us')
@app.route('/result')
def result():
return render_template('result.html')
@app.route('/post', methods= ['GET','POST'])
def post():
name = 'Text Analyzer'
if request.method == 'GET':
return render_template('post.html', name = name, title = name)
if request.method =='POST':
content = request.form['content']
print(content)
return redirect(url_for('result'))
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
So far, we have seen how to use template and how to inject data to template, how to a common layout. Now, lets handle static file. Create a folder called static in the project director and create a folder called css. Inside css folder create main.css. Your main. css file will be linked to the layout.html.
You don't have to write the css file, copy and use it. Let's move on to deployment.
Heroku provides a free deployment service for both front end and fullstack applications. Create an account on heroku and install the heroku CLI for you machine. After installing heroku write the following command
asabeneh@Asabeneh:~$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Let's see the result by clicking any key from the keyboard. When you press any key from you keyboard it will open the heroku login page and click the login page. Then you will local machine will be connected to the remote heroku server. If you are connected to remote server, you will see this.
asabeneh@Asabeneh:~$ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/browser/be12987c-583a-4458-a2c2-ba2ce7f41610
Logging in... done
Logged in as [email protected]
asabeneh@Asabeneh:~$
Before we push our code to remote server, we need requirements
- requirements.txt
- Procfile
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch requirements.txt
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze > requirements.txt
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ cat requirements.txt
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch Procfile
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ ls
Procfile env/ static/
app.py requirements.txt templates/
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$
The Procfile will have the command which run the application in the web server in our case on Heroku.
web: python app.py
Now, it is ready to be deployed. Steps to deploy the application on heroku
- git init
- git add .
- git commit -m "commit message"
- heroku create 'name of the app as one word'
- git push heroku master
- heroku open(to launch the deployed application)
After this step you will get an application like this
- You will build this application. Only the text analyser part is left
Python is a backend technology and it can be connected with different data base applications such as MongoDB and SQL.
MongoDB is a NoSQL database. MongoDB stores data in a JSON like document which make MongoDB very flexible and scalable. Let's see the different terminologies of SQL and NoSQL databases. The following table will make the difference between SQL vs NoSQL databases.
In this section we will focus on a NoSQL database MongoDB. Lets sign up on mongoDB by click on the sign in button then click register on the next page.
Complete the fields and click continue
Select the free plan
Choose the proximate free region and give any name for you cluster.
Now, a free sandbox is created
All local host access
Add user and password
Create a mongoDB uri link
Select python 3.6 or above driver
Copy the connection string only link and you get something like this
mongodb+srv://asabeneh:<password>@30daysofpython-twxkr.mongodb.net/test?retryWrites=true&w=majority
Don't worry about the url, it is a means to connect your application with mongoDB. Let's replace the password placeholder with the passed you use to add a user. Example:
mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority
Now, I replaced everything and the password is 123123 and the name of the database is thirty_days_python. This is just an example, your password must a bit strong than this.
Python needs a mongoDB driver to access mongoDB database. We will use pymongo with dnspython to connect our application with mongoDB base . Inside your project directory install pymongo and dnspython.
pip install pymongo dnspython
The "dnspython" module must be installed to use mongodb+srv:// URIs. The dnspython is a DNS toolkit for Python. It supports almost all record types.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
When we run the above code we get the default mongoDB databases.
['admin', 'local']
Let's create a database, database and collection in mongoDB will be created if it doesn't exist. Let's create a data base name thirty_days_of_python and students collection. To create a database
db = client.name_of_databse # we can create a database like this or the second way
db = client['name_of_database']
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
# Creating database
db = client.thirty_days_of_python
# Creating students collection and inserting a document
db.students.insert_one({'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250})
print(client.list_database_names())
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
After we create a database, we also created a students collection and we used insert_one method to insert a document. Now, the data thirty_days_of_python and students collection have been created and the document has been inserted. Check your mongoDB cluster and you will see both the database and the collection. Inside the collection, there will be a document.
['thirty_days_of_python', 'admin', 'local']
If you see this on the mongoDB cluster, it means you have successfully created a database and a collection.
If you have seen on the figure, the document has been created with a long id which acts as a primary key. Every time we create a document mongoDB create and unique id for it.
The insert_one() method inserts one item at a time if we want to insert many documents at once either we use insert_many() method or for loop. We can use for loop to inset many documents at once.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
students = [
{'name':'David','country':'UK','city':'London','age':34},
{'name':'John','country':'Sweden','city':'Stockholm','age':28},
{'name':'Sami','country':'Finland','city':'Helsinki','age':25},
]
for student in students:
db.students.insert_one(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
The find and findOne methods common method to find data in a collection in mongoDB database. It is similar to the SELECT statement in a MySQL database. Let's use the find_one() method to get documents in the database collection.
- *find_one({"_id": ObjectId("id"}): Gets the first occurrence if an id is not provided
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = db.students.find_one()
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Helsinki', 'city': 'Helsinki', 'age': 250}
The above query returns the first entry but we can target specific document using specific _id. Let's do one example, let's use David's id to get David object. '_id':ObjectId('5df68a23f106fe2d315bbc8c')
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
from bson.objectid import ObjectId # id object
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = db.students.find_one({'_id':ObjectId('5df68a23f106fe2d315bbc8c')})
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
We have seen, how to use find_one() using the above examples. Let's move one to find()
- find(): returns all the occurrence from a collection if we don't pass a query object. The object is pymongo.cursor object.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find()
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Helsinki', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
We can specify which fields to return by passing second object in the find({}, {}). 0 means not include and 1 means include but we can not mix 0 and 1, except for _id.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find({}, {"_id":0, "name": 1, "country":1}) # 0 means not include and 1 means include
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'name': 'Asabeneh', 'country': 'Finland'}
{'name': 'David', 'country': 'UK'}
{'name': 'John', 'country': 'Sweden'}
{'name': 'Sami', 'country': 'Finland'}
In mongoDB find take a query object. We can pass a query object and we can filter the documents we like to filter out.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
Query with modifiers
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
Query with modifiers
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = db.students.find(query)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = db.students.find(query)
for student in students:
print(student)
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
We can limit the number of documents we return using the limit() method.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
db.students.find().limit(3)
By default, sort is in ascending order. We can change to descending by adding -1 parameter.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = db.students.find().sort('name')
for student in students:
print(student)
students = db.students.find().sort('name',-1)
for student in students:
print(student)
students = db.students.find().sort('age')
for student in students:
print(student)
students = db.students.find().sort('age',-1)
for student in students:
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
Ascending order
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
Descending order
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}
We will use update_one() method to update one item. It takes two object one is a qeury and the second is the new object. The first person, Asabeneh got a very implausible age. Let's update Asabeneh's age.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {'age':250}
new_value = {'$set':{'age':38}}
db.students.update_one(query, new_value)
# lets check the result if the age is modified
for student in db.students.find():
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country': 'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
When we want to update many documents at once we use *upate_many()*method.
The method delete_one() delete one document.The delete_one() take a query object parameter. It only removes the first occurrence. Let's remove one John from the collection.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {'name':'John'}
db.students.delete_one(query)
for student in db.students.find():
print(student)
# lets check the result if the age is modified
for student in db.students.find():
print(student)
app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int(os.environ.get("PORT", 5000))
app.run(debug=True, host='0.0.0.0', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country': 'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country': 'Finland', 'city': 'Helsinki', 'age': 25}
As you can see John as been removed from the collection
When we want to delete many documents we use delete_many() method, it takes a query object. If we pass an empyt query object to delete_many({}) it will delete all the documents in the collection.
Using the drop() method we can delete a collection from a database.
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:[email protected]/test?retryWrites=true&w=majority'
client = pymongo.MongoClient(MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
db.students.drop()
Now, we have deleted the students collection from the database.