--- tags: Web, Class --- # 1091 Flask網頁程式設計 [Johnson](https://hackmd.io/Zl7v3jqpScShlAjRr4-FnQ?both) [Joycelyn](https://hackmd.io/uY_00dLnT0q_tmffAJe7ZQ?both) [Build Your 1st Python Web App With Flask](https://medium.com/bhavaniravi/build-your-1st-python-web-app-with-flask-b039d11f101c) [TOC] ## 09/15 ### Why Flask - Web frameworks - Django - Pyramid - Flask - microframework - 容易擴充(designed to be extended) ### Background - Python - function - module - package - decorator - object-oriented programming - exception & diagnosing issue - HTML,JavaScript... - BASH on Linux ### Start #### Creating the Application Directory ```shell= $ git clone https://github.com/miguelgrinberg/flasky.git $ cd flasky $ git checkout 1a ``` ### Virtual Environment(VE) - What is VE? - **A copy of the Python interpreter into which you can install packages privately.** - Ensure that applications have access only to the packages that each project use. - The global interpreter serves only as a source from which more VEs can be created. #### Creat VE - creat a directory to load ==Python==(had better use ==version 3.7==) ```shell= $cd flasky $python --version $python3 -m venv myvenv //a common convention to call it myvenv ``` > If there is no activate file in venv/bin: > > apt-get install python3-venv - View VEs you have activated ```shell= $view venv/bin/activate ``` >Just named in linux or mac, in windows use 'venv/Scripts/avtivate' - Activate the VE you created ```shell= $source venv/bin/activate //activate ``` - Then you will enter this VE, install ==flask== and test ```shell= (venv)$pip list //list packages installed in the VE (venv)$pip install --upgrade pip (venv)$pip install flask (venv)$python -c 'import flask' //test if flask is installed (venv)$deactivate //out ``` - Run the Web server(see $flask run --help) ```shell= $cd flasky $git checkout 2a (venv)$export FLASK_APP=hello.py (venv)$flask run --host lilina.csie.ncnu.edu.tw --port 10714 ``` > --host can be replaced with -h > --port can be replaced with -p > $ flask run -h 10.XX.XX.X(use IP address)why? - Type http://lilina.csie.ncnu.edu.tw:10714 to the web I created - 每次修改過hellopy後 - 強制reset, checkout新版 ``` $git reset --hard ``` > - restore ``` $git restore hello.py ``` ## 9/22 - client---> web server --WSGI--> application instance ```python= from flask import Flask #Flask:Class app = Flask(__name__) #__name__:An object of class ``` >print(\_name_) >python -c 'import a' ### Decorator - change the behavior of a function - view functions ```python= def hello(): print("Hello") message = hello print(message.__name__, hello.__name__) message() ``` - python裡面的物件使用 ```python= dir(string) ``` - 指向function的pointer ```python= def hello(): print("Hello") message = hello message() ``` ``` >> Hello #the output of message() is same as hello() ``` - Usage of decorator ```python= def name(): print("Alice") def hello(func): def inner(): print("Hello, ", end = '') func() return inner #待編 def ``` - Syntactic Sugar - simpler syntax to do the same task ```python= @hello def f(): print("Carol") ``` - Arguments in Wrappers - Positional mapping ```python= ``` > *arg: 當function傳進來時得到的參數可為任意數量,因為不知道有幾個 > [tuple, list, and dictionary](http://sthurlow.com/python/lesson06/) > Tuple' values can't be changed:減少複雜性,較不佔記憶體,處理時間短 > 物件是否immutable ### Dynamic Component in a route - strings by default - it can also be : ``` /user/<int:id> ``` - local have not commit ```shell= #git reset --hard ``` #### checkout 2b - run the server and use a browser to: - observe the log massage on the server ### Templates - 可套用的樣板 #### Example hello.py ```python= from flask import Flask, render_template from flask_bootstrap import Bootstrap app = Flask(__name__) @app.route('/') def index(): content = '<h1>Hello World!</h1>' return content @app.route('/') def index(): content = '<h1>Hello World!</h1>' return render_template('name.html') ``` ### 繼承 ```python= {% extends ".html" %} {% block title %} New title {% endblock %} ``` ## 10/06 Templates ### review - Syntactic Sugar - apply the decorator to function ### template - 樣板,像是古騰堡印刷術 - 相比以冗長的function附加在main,利用樣板 - Rendering templates ``` from flask import render.template ``` #### multi-line strings ```htmlmixed= html = ``` blablabla``` ``` #### macro 巨集 ```cpp= #define pi 3.14 #define max(x,y) (x>y ? x:y) ``` - 與define function不同,macro需用==三元運算==表示 - - 查看:compile only, 在main中將macro內容展開 ```shell= $gcc -c a.c //creat object file called a.o $g++ a.o -o b $gcc -E a.c //expend ``` #### ```python= ``` ## 10/13 ### git - Not necessarily GitHub - Remote repository - Local repository - Action: ==push==(to remote), ==pull==(from remote) #### prepare a remote repositpry - On any Unix host ```shell= git init --bare /Git/Group06/HW01.git ``` - Then on a client(open the directory you want to clone in it) ```shell= git clone host:/Git/Group06/HW01.git ``` - If the port number you use is not 22, modify the file **~/.ssh/config** ``` Host gitlab Hostname gitlab.ncnu.org User ncnu Port 7476 ``` - Connect ```shell= .ssh> ssh gitlab ``` - A client has already several commits ```shell= git remote add origin host:/Git/Group06/HW01.git git push origin master ``` - Other partners must merge that guy's commit before pushing the file ```shell= git clone gitlab:/Git/Group06/HW01.git git pull origin master git remote show git log --oneline vi filename //modify the file... git push ``` - that guy want to get what you had modified ```shell= git pull //fetch+merge ``` ### Review:redirect ```python= ``` ## 10/20 - html forms - input type ### Web Forms #### Request Method - GET ```html= <FORM ACTION="add_get.php"> X:<input type="text" name="X"><BR> Y:<input type="text" name="Y"><BR> <input type= "submit"> </FORM> ``` >All variable names and values are displayed in the URL. > The maximum length of the URL is **limited to about 2000 characters**. ```php= <?php $X = $_GET['X']; $Y = $_GET['Y']; echo $X,"+",$Y,"=",$X+$Y ?> ``` - POST ```html= <FORM ACTION="add_get.php" METHOD="POST"> X:<input type="text" name="X"><BR> Y:<input type="text" name="Y"><BR> <input type= "submit"> </FORM> ``` >Add ==METHOD="POST"== ```php= <?php $X = $_POST['X']; $Y = $_POST['Y']; echo $X,"+",$Y,"=",$X+$Y ?> ``` #### Flask: request.args for GET method - GET ```python= from flask import request @app.route('/') def index(): doc=#html return doc ``` - POST - Information are shown in urls with GET, not safe. ```html= <FORM METHOD=POST ACTION=add> <INPUT TYPE=TEXT NAME=a> <INPUT TYPE=TEXT NAME=b> <INPUT TYPE=SUBMIT> ``` #### select/option ```html= <select name="xxxx"> <option value="1998">1998</option> <option value="2020">2020</option> </select> ``` #### Input type in html: date ## 10/27 ### WTF ``` pip install WTF ``` - Flask-WTF does not need to be initialized at the application level - Only expects the application to have secret key - CSRF attack ```python= app=Flask(_name_) app.config['secret_key']='hard to huess string' ``` ### Form Classes - Each web form --> a class - inherits from FlaskForm ```python= from wtforms import StringField,SubmitField from wtforms.validators import DataRequired app=Flask(_name_) app.config['secret_key']='hard to guess string' class NameForm(FlaskForm): name = StringField('What is your name?',validators =[DataRequired()]) submit = SubmitField('Submit') ``` #### WTForms Validators [guide1](https://hackersandslackers.com/flask-wtforms-forms/) [guide2](https://wtforms.readthedocs.io/en/2.3.x/crash_course/) - form.name.label ## 11/03 ### macro - When the item ### Databases - sqlite - py37-sqlite3 - ORM - Flask-SQLAlchemy ## 11/10 ```python= mylist = infile.readlines() ``` ### Database system - if the data size is large ```python= SELECT id,name FROM users WHERE name = 'David'; ``` ### LAMP - Linux - Apache - MySQL - PHP ![](https://i.imgur.com/sEwKmuf.jpg) #### SQLite - 嵌入式系統的資料庫首選 - Only need two files: header file ==sqlite3.h== and source code ==sqlite3.c== > lynx: linux瀏覽器 > scp,pscp ```shell= sqlite3 name.db sqlite> .mode csv sqlite> .import download.csv Tablename sqlite> .tables sqlite> .databases sqlite> SELECT * FROM Tablename; sqlite> SELECT COUNT(*) FROM Tablename; sqlite> .schema Tablename sqlite> DROP TABLE Tablename; sqlite> ALTER TABLE Tablename RENAME TO Newname; sqlite> SELECT * FROM Tablename WHERE Columnname == 'XXXX' BETWEEN ** AND ** LIKE 'XXX%' SUM(Columnname) ORDER BY Columnname GROUP BY Columnname ``` > vi 小教室 > :6/24s/TEXT/INTEGER ### Steps of modify the data type of a field 1. export table contents ```shell= ``` 2. empty the table ```shell= ``` 3. dump the schema to a text file ```shell= ``` 4. modify the schema ```shell= ``` 5. re-create the table ```shell= ``` #### GROUP BY ## 01/05 ### A word bout documentstion - PEP 8 - 縮排空四格 - 換行 ```python= a = ( b + c + d - e ) ``` - Docstring