[Produced by Xinghai] flask (4) three-party tool use

  1. The soul of learning is the commune, and the goal of learning is people’s self-government.
  2. Learning is the non-violent revolutionary method of social reform.
  3. Learning is the civilized way for people to fight against the expropriation of capital.
  4. Learning failed, just like the Paris Commune failed. But it pointed out the right direction for successful social reform in the future.
  5. The logic of learning is not complicated. In a word, the quantity of knowledge must basically match the value of knowledge.
  6. Managing learning is not complicated either, it just requires that the amount of learning fluctuates stably within the minimum positive range.
  7. Of course, this is very difficult to manage.
  8. First, we must have a lot of early accumulation. For example, knowledge reserves, knowledge monetization capabilities, knowledge acquisition methods, etc.
  9. Second, we must strictly control the abuse of knowledge. The abuse of knowledge must ensure that the quantity of knowledge does not deviate from the value of knowledge.
  10. Third, we must establish strong equalization measures to cope with the impact of external uncertainties.
  11. In short, if we must stand firm and establish the subjectivity of the people, we must be able to manage knowledge well.
  12. Finally, I once again pay tribute to Chen Yun and other proletarian revolutionaries of the older generation.
During development, you need to manually restart the Flask server every time you change the Flask project code. In order to improve development efficiency, you can use Flask’s auto-reload function to enable the Flask server to automatically detect code changes and restart automatically.

The specific implementation method is as follows:
In the entry file of the Flask project, import the run_simple function in the werkzeug.serving module
Werkzeug is a WSGI tool library for Python that can be used to build web applications.

from werkzeug.serving import run_simple

Use the run_simple function to start the Flask server, and set use_reloader=True to enable automatic reloading:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)
from werkzeug.wrappers import Request, Response
 
@Request.application
def application(request):
    return Response('Hello world')
 
if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 5000, application)

Use the @Request.application decorator to convert the application function into a WSGI application. and then use
The run_simple function runs the application locally on port 5000.

def run_simple(hostname, port, application, use_reloader=False,
               use_debugger=False, use_evalex=True,
               extra_files=None, reloader_interval=1, threaded=False,
               processes=1, request_handler=None, static_files=None,
               passthrough_errors=False, ssl_context=None):
    # This method is relatively short, but the comments are very detailed. Due to space issues, the comments in the source code are omitted.
    if use_debugger:
        from werkzeug.debug import DebuggedApplication
        application = DebuggedApplication(application, use_evalex)
    if static_files:
        from werkzeug.wsgi import SharedDataMiddleware
        application = SharedDataMiddleware(application, static_files)

    def inner():
        make_server(hostname, port, application, threaded,
                    processes, request_handler,
                    passthrough_errors, ssl_context).serve_forever()

    if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        display_hostname = hostname != '*' and hostname or 'localhost'
        if ':' in display_hostname:
            display_hostname = '[%s]' % display_hostname
        _log('info', ' * Running on %s://%s:%d/', ssl_context is None
             and 'http' or 'https', display_hostname, port)
    if use_reloader:
        # Create and destroy a socket so that any exceptions are raised before
        # we spawn a separate Python interpreter and lose this ability.
        test_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()
        run_with_reloader(inner, extra_files, reloader_interval)
    else:
        inner()

Template rendering

Although jinja2 is a separate library, since flask depends on jinja2, it does not need to be installed separately.

 from flask import render_template

use

 @app.route('/template')
 def template(): # put application's code here
     // render
     return render_template('demo.html')

dynamic rendering
Or use jinja2’s render_template
Associated with {{ blog_id }} in HTML through blog_id

 @app.route('/template/blog/<blog_id>')
 def template(blog_id): # put application's code here
     return render_template('demo.html', blog_id=blog_id)
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <title>Title</title>
   </head>
   <body>
     <a href="www.baidu.com">Baidu</a>
     <div class="header">This is the blog {<!-- -->{ blog_id }}</div>
   </body>
 </html>

Support other types of parameter passing

 @app.route('/template/blog/<blog_id>')
 def template(blog_id): # put application's code here
     uesr = User('lijiajun', '[email protected]')
     person = {<!-- -->
         'username': 'zhangsan',
         'email': 'zhangsan's email'
     }
     return render_template('demo.html', blog_id=blog_id, user=uesr, person=person)

demo.html

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <title>Title</title>
   </head>
   <body>
     <a href="www.baidu.com">Baidu</a>
     <div class="header">This is the blog {<!-- -->{ blog_id }}</div>
     <div>{<!-- -->{ user }}</div>
     <div>{<!-- -->{ user.username }}</div>
     <div>{<!-- -->{ user.email }}</div>
     <div>{<!-- -->{ person.username }}</div>
     <div>{<!-- -->{ user.email }}</div>
   </body>
 </html>

Use filters
Just use the pipe symbol |.

{{ user.email | length }}

Custom filters

 def filter(value):
     return value.upper()
 ?
 ?
 # Add filter
 app.add_template_filter(filter, 'filter')
 <div>{<!-- -->{<!-- --> user.email | filter }}</div>

jinja2 statements

<div>
    {% if age > 18 %} can enter {% endif %} {% if age < 18 %} cannot enter {% endif %}
</div>
<div>
    {% for foo in age %}?
    {% endfor %}?
</div>

Component passing parameters

demo.html

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <title>test</title>
   </head>
   <body>
     <div>
       {% extends 'component.html' %} {% block content %} I passed the content {%
       endblock %} {% block title %} I passed the title {% endblock %}
     </div>
   </body>
 </html>

component.html

 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <title>This is a component</title>
   </head>
   <body>
     This is a component {% block title %}{% endblock %} {% block content %}{% endblock
     %}
   </body>
 </html>

Load images

 <body>
     <div>
         <img src='{<!-- -->{ url_for("static",filename="image.png") }}' alt="" />
     </div>
 </body>

Load CSS file

 <head>
     <meta charset="UTF-8" />
     <title>test</title>
     <link rel="stylesheet" href='{<!-- -->{ url_for("static",filename="demo.css") }}' />
 </head>

Load Js file

 <script src='{<!-- -->{ url_for("static",filename="demo.js")}}'></script>

flask connects to database

 pip install pymysql

We will not use this package directly to operate the database, because we need to write native SQL statements. It is best to use ORM.
So we need the next one:

 pip install flask-sqlalchemy

sqlalchemy provides us with ORM technology, which allows us to operate the database like ordinary objects.
This requires additional installation because flask does not have this dependency.

from flask_sqlalchemy import SQLAlchemy

Create a SQLAlchemy instance object, name it db, pass the flask instance object app as a parameter to SQLAlchemy, connect db and app, and call its related functions

db = SQLAlchemy(app)

Use gunicorn to start flask

gunicorn app:app -c gunicorn.conf.py > gun.log 2> & amp;1 & amp;

1. Gunicorn is a widely used high-performance Python WSGI HTTP Server based on unix systems. Gateway service used to parse HTTP requests.
This is usually between a reverse proxy (such as nginx), or a load balancer (such as AWS ELB) and a web application (such as Django or Flask).
Its operating model is based on the pre-fork worker model, which supports eventlets and greenlets.

2. Characteristics of gunicorn
Its features: 1. Compatible with most Python web frameworks;
2. Simple and easy to use;
3. Lightweight resource consumption;
4. Currently, gunicorn can only run in Linux environment and does not support Windows platform.

gunicorn -w 5 -b 0.0.0.0:6000 main:app

Explain the meaning of the parameters:

-w: indicates the number of worker processes
-b: access address and port
main: flask starts python file name
app: Flask object name created in the script

from flask import Flask

app = Flask(__name__)


@app.route('/',methods=['GET'])
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=6000)

You can also start based on a file

gunicorn -c config.py main:app
cat config.py
# Whether to enable debug mode
debug=True
# address
bind = "0.0.0.0:6000"
#Number of worker processes
workers = 2
#Number of worker threads
threads = 2
# overtime time
timeout=600
# Output log level
loglevel = 'debug'
# Store log path
pidfile = "log/gunicorn.pid"
# Store log path
accesslog = "log/access.log"
# Store log path
errorlog = "log/debug.log"
# In gunicorn + apscheduler scenario, solve the problem of repeated execution of scheduled tasks by multiple workers.
preload_app = True
-c CONFIG: CONFIG, the path of the configuration file, started through the configuration file; used in production environment;

-b ADDRESS: ADDRESS, ip plus port, bound to the running host;

-w INT, --workers INT: The number of worker processes used to process, a positive integer, the default is 1;

-k STRTING, --worker-class STRTING: The working mode to be used, the default is sync asynchronous, you can download eventlet and gevent and specify

--threads INT: Number of worker threads to handle requests, use the specified number of threads to run each worker. It is a positive integer and defaults to 1.

--worker-connections INT: The maximum number of concurrent clients. By default, this value is 1000.

--backlog int: Maximum number of pending connections, i.e. the number of clients waiting to be serviced. The default is 2048, generally not modified;

-p FILE, --pid FILE: Set the file name of the pid file. If not set, the pid file will not be created.


--access-logfile FILE: Access log directory to be written

--access-logformat STRING: Access log format to be written

--error-logfile FILE, --log-file FILE: File directory to write error logs.

--log-level LEVEL: Error log output level.


--limit-request-line INT: The maximum size of the number of lines in the HTTP request header. This parameter is used to limit the allowed size of the HTTP request line. By default, this value is 4094. The value is a number from 0 to 8190.

--limit-request-fields INT: Limit the number of request header fields in HTTP requests. This field is used to limit the number of request header fields to prevent DDOS attacks. By default, this value is 100 and this value cannot exceed 32768.

--limit-request-field-size INT: Limit the size of the request header in the HTTP request. By default, this value is 8190 bytes. The value is an integer or 0. When the value is 0, it means that there will be no limit on the request header size.


-t INT, --timeout INT: After this many seconds the job will be killed and restarted. Generally set to 30 seconds;

--daemon: Whether to start as a daemon process, the default is false;

--chdir: Switch directories before loading the application;

--graceful-timeout INT: By default, this value is 30. Jobs that are still alive after the timeout (starting from receiving the restart signal) will be forcibly killed; generally use the default;

--keep-alive INT: Number of seconds to wait for requests on a keep-alive connection, the default value is 2. Generally set between 1 and 5 seconds.

--reload: Default is False. This setup is for development and will cause the job to be restarted whenever a change is made to the application.

--spew: Print every statement executed by the server, default False. This choice is atomic, that is, either all is printed or none is printed;

--check-config: Display the current configuration. The default value is False, which is displayed.

-e ENV, --env ENV: Set environment variables;