This commit is contained in:
Asabeneh 2019-12-15 04:02:33 +02:00
parent 784fc87443
commit ce0a08da26
12 changed files with 705 additions and 2175 deletions

File diff suppressed because it is too large Load Diff

125
python_for_web/.gitignore vendored Normal file
View File

@ -0,0 +1,125 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

1
python_for_web/Procfile Normal file
View File

@ -0,0 +1 @@
web: python app.py

28
python_for_web/app.py Normal file
View File

@ -0,0 +1,28 @@
# 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', methods= ['GET','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)

View File

@ -0,0 +1,6 @@
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0

View File

@ -0,0 +1,91 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--header-bg-color: #4a7799;
--textarea-bg-color: rgb(235, 231, 231);
--body-bg-color: rgb(225, 228, 230);
--nav-link-color:#aaa;
}
body {
background: var(--body-bg-color);
margin: auto;
line-height: 1.5;
}
header {
background: var(--header-bg-color);
}
h1,
h2 {
margin: 25px;
}
.menu-container {
width: 90%;
display: flex;
justify-content: space-around;
align-items: center;
color: rgb(221, 215, 215);
padding: 25px;
}
.nav-lists {
display: flex;
}
li {
list-style: none;
}
.nav-list {
list-style: none;
margin: 0 5px;
}
.nav-link {
text-decoration: none;
font-size: 22px;
padding: 0 5px;
color: var(--nav-link-color);
}
main {
width: 90%;
margin: auto;
text-align: center;
}
.btn{
width: 150px;
height: 50px;
background: var(--header-bg-color);
color: var(--nav-link-color);
font-size: 20px;
margin:5px;
border: 1px solid var(--header-bg-color);
}
.btn:focus {
outline: 2px solid #2a70a5;
}
textarea {
padding: 20px;
outline: 1px solid var(--nav-link-color);
border: none;
font-size: 18px;
}
textarea:focus {
border: none;
outline: 2px solid #4a7799;
background: var(--textarea-bg-color);
font-size: 18px;
}

View File

@ -0,0 +1,7 @@
{% extends 'layout.html' %}
{% block content %}
<h1>About Us</h1>
<h2>{{name}}</h2>
<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>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'layout.html' %}
{% block content %}
<h1>Welcome to {{name}}</h1>
<p>You need the following technologies to build this web application:</p>
<ul>
{% for tech in techs %}
<li>{{tech}}</li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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="nav-link" href="/">30DaysOfPython</a>
</div>
<ul class="nav-lists">
<li class="nav-list"><a class="nav-link" href="{{ url_for('home') }}">Home</a></li>
<li class="nav-list"><a class="nav-link" href="{{ url_for('about') }}">About</a></li>
<li class="nav-list"><a class="nav-link" href="{{ url_for('post') }}">Text Analyzer</a></li>
</ul>
</div>
</header>
<main>
{% block content %} {% endblock %}
</main>
</body>
</html>

View File

@ -0,0 +1,9 @@
{% extends 'layout.html' %}
{% block content %}
<h1>Text Analyzer</h1>
<form action="result.html" method="POST"></form>
<textarea cols="120" rows='30' name="content"></textarea>
<br />
<input type='submit' class="btn" value="Process Text"/>
</form>
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends 'layout.html' %}
{% block content %}
<h1>Result </h1>
{% endblock %}

View File

@ -26,6 +26,10 @@
- [Reading CSV File using pandas](#reading-csv-file-using-pandas)
- [Data Exploration](#data-exploration)
- [Exercises: Day 25](#exercises-day-25)
- [📘 Day 26](#%f0%9f%93%98-day-26)
- [Python for Web](#python-for-web)
- [Flask](#flask)
- [Exercises: Day 26](#exercises-day-26)
# 📘 Day 25
## Pandas
@ -775,6 +779,389 @@ df.describe() # describe can also give statistical information from a datafrom
* Explore the data and make sense of the data
# 📘 Day 26
## Python for Web
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
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.
Follow, the following steps to get started with Flask
```sh
pip install virtualenv
```
```sh
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$
```
Now, let's create app.py file in the project directory and write the following code. The following code has flask module, os module.
The home route.
```py
# 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__':
port = int(os.environ.get("PORT", 5000)) # for deployment
# to make it work for both production and development
if port == 5000:
app.run(debug=True)
else:
app.run(port = port) # to listen to the port
```
After you run _python app.py_ check local host 5000.
Let's add additional route.
Creating about route
```py
# 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__':
port = int(os.environ.get("PORT", 5000)) # for deployment
# to make it work for both production and development
if port == 5000:
app.run(debug=True)
else:
app.run(port = port) # to listen to the 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
```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
```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
```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__':
port = int(os.environ.get("PORT", 5000)) # for deployment
# to make it work for both production and development
if port == 5000:
app.run(debug=True)
else:
app.run(port = port) # to listen to the 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.
```html
<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.
```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__)
@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', methods= ['GET','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
```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
```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
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{% if title %}
<title>30 Days of Python - {{ title}}</title>
{% else %}
<title>30 Days of Python</title>
{% endif %}
</head>
<body>
<header>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/post">Text Analyzer</a></li>
</ul>
</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
home.html
```html
{% extends 'layout.html' %} {% block content %}
<h1>Welcome to {{name}}</h1>
<p>You need the following technologies to build this web application:</p>
{% for tech in techs %}
<ul>
<li>{{tech}}</li>
</ul>
{% endfor %} {% endblock %}
```
about.html
```html
{% extends 'layout.html' %} {% block content %}
<h1>About Us</h1>
<h2>{{name}}</h2>
{% endblock %}
```
post.html
```html
{% extends 'layout.html' %} {% block content %}
<h1>Text Analyzer</h1>
<textarea cols="50" rows="10"></textarea>
<br />
<button>Process Text</button>
{% endblock %}
```
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](https://www.heroku.com/) and install the heroku [CLI](https://devcenter.heroku.com/articles/heroku-cli) for you machine.
After installing heroku write the following command
```sh
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.
```sh
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 asabeneh@gmail.com
asabeneh@Asabeneh:~$
```
Before we push our code to remote server, we need requirements
* requirements.txt
* Procfile
```sh
(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.
```sh
web: python app.py
```
Now, it is ready to be deployed. Steps to deploy the application on heroku
1. git init
2. git add .
3. git commit -m "commit message"
4. heroku create 'name of the app as one word'
5. git push heroku master
6. heroku open(to launch the deployed application)
After this step you will get an application like [this](https://thirtydaysofpython-v1.herokuapp.com/post)
## Exercises: Day 26
[<< Part 8 ](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/readme22-24.md) | [Part 10 >>](https://github.com/Asabeneh/30-Days-Of-Python/blob/master/readme28-30.md)