当前位置: 首页 > news >正文

Python Flask Web框架快速入门

Flask 入门Demo

Flask 开发环境搭建,执行如下指令:

pip install flask# 第一节: Flask 快速入门from flask import Flask
app = Flask(__name__)@app.route('/flask')
def hello_flask():return 'Hello Flask'app.run()

核心代码剖析:

flask包导入Flask类,通过实例化这个类,创建一个程序对象app。

app = Flask(__name__)

注册一个处理函数,这个函数是处理某个请求的处理函数,Flask 官方把它叫做视图函数(view funciton)。使用app.route()装饰器来为这个函数绑定对应的 URL,当用户在浏览器访问这个 URL 的时候,就会触发这个函数,获取返回值,并把返回值显示到浏览器窗口:

@app.route('/flask')
def hello_flask():return 'Hello Flask'

最后,Flask类的**run()**方法在本地开发服务器上运行应用程序。

app.run(host, port, debug, options)

所有参数都是可选的

序号

参数与描述

1

host

要监听的主机名。 默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用

2

port

默认值为5000

3

debug

默认为false。 如果设置为true,则提供调试信息

4

options

要转发到底层的Werkzeug服务器。

Flask 基础知识

Flask 入参类型

flask 支持入参数据类型,如下所示:

转换器

描述

int

整型

float

浮点型

path

接受用作目录分隔符的斜杠

string

默认,字符串

# 第二节: Flask 入参
from flask import Flask, redirectapp = Flask(__name__)# 字符串入参
@app.route('/strs/<name>')
def strs(name):return "Hello %s" % name# 浮点数入参
@app.route('/floats/<float:version>')
def floats(version):return version# 整数入参
@app.route('/ints/<int:version>')
def ints(version):return '整数为 %d' % versionapp.run(host='0.0.0.0', port=8888, debug=True)

Flask 重定向(redirect)

**url_for()**函数用于动态指定函数的URL地址。

# 第三节: Flask 重定向from flask import Flask, redirect, url_forapp = Flask(__name__)@app.route('/redicts')
def redicts():return redirect('https://www.baidu.com')@app.route('/admin')
def get_admin():return 'Hello Admin'@app.route('/guest/<guest>')
def get_guest(guest):return 'Hello %s as Guest' % guest@app.route('/user/<name>')
def hello_user(name):if name == 'admin':return redirect(url_for('get_admin'))else:return redirect(url_for('get_guest', guest=name))app.run()

Flask 支持到HTTP方法

默认情况下,Flask路由响应GET请求。但是,可以通过为route()装饰器提供方法参数来更改此首选项。

序号

方法与描述

1

GET

以未加密的形式将数据发送到服务器。最常见的方法。

2

HEAD

和GET方法相同,但没有响应体。

3

POST

用于将HTML表单数据发送到服务器。POST方法接收的数据不由服务器缓存。

4

PUT

用上传的内容替换目标资源的所有当前表示。

5

DELETE

删除由URL给出的目标资源的所有当前表示。

# 第四节: Flask 支持HTTP方法from flask import Flaskapp = Flask(__name__)@app.route('/get_request', methods=['GET'])
def get_request():return 'GET请求'@app.route('/post_request', methods=['POST'])
def post_request():return 'POST请求'@app.route('/delete_request', methods=['DELETE'])
def delete_request():return 'DELETE请求'@app.route('/put_request', methods=['PUT'])
def put_request():return 'PUT请求'@app.route('/head_request', methods=['HEAD'])
def head_request():return 'HEAD请求'app.run()

Flask 实战一:模拟用户登入

# Flask 模拟用户登入from flask import Flask, request, jsonifyapp = Flask(__name__)@app.route('/')
def index():return '欢迎来到主页'@app.route('/login', methods=['POST'])
def login():my_json = request.get_json()user = my_json.get('user')password = my_json.get('password')if user == 'admin' and password == '123456':# 前端和后端统一请求和返回的数据格式,返回json格式需要导入jsonify这个包# return jsonify({#     "token": "abcd123456",#     "birthday": "2024-04-18"# })return jsonify(token="abcd123456", birthdat="2024-04-18")app.run()

Flask 模板

在项目下创建 templates 文件夹,用于存放所有模板文件,并在目录下创建一个模板文件:login.html 文件

<html><body><form action = "http://localhost:5000/login" method = "post"><p>用户名:</p><p><input type = "text" name = "user" /></p><p>密码:</p><p><input type = "password" name = "password" /></p><p><input type = "submit" value = "submit" /></p></form></body>
</html># Flask 模拟用户登入 : 基于Templatefrom flask import Flask, request, jsonify, render_templateapp = Flask(__name__)@app.route('/')
def index():return render_template("login.html")@app.route('/login', methods=['POST'])
def login():# 由json 获取修改为表单获取user = request.form['user']password = request.form['password']if user == 'admin' and password == '123456':# 前端和后端统一请求和返回的数据格式,返回json格式需要导入jsonify这个包# return jsonify({#     "token": "abcd123456",#     "birthday": "2024-04-18"# })return jsonify(token="abcd123456", birthdat="2024-04-18")app.run()
Flask 模板文件传参

在Python代码中传入字符串,列表,字典到模板中。

from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')
def index():# 字符串my_str = 'Hello Word'# int 类型my_int = 10# 数组类型my_array = [3, 4, 2, 1, 7, 9]# 字典类型my_dict = {'name': 'zhouzhiwengang','age': 31}return render_template('variable.html',my_str=my_str,my_int=my_int,my_array=my_array,my_dict=my_dict)app.run()
Flask 模板文件之静态文件
# 第六节: Flask 模板文件之静态文件
from flask import Flask, render_templateapp = Flask(__name__)@app.route("/")
def index():return render_template("static.html")app.run(debug=True)

在项目下创建 templates 文件夹,用于存放所有模板文件,并在目录下创建一个模板文件:static.html 文件

<html><head><script type = "text/javascript"src = "{{ url_for('static', filename = 'static.js') }}" ></script></head><body><input type = "button" onclick = "sayHello()" value = "Say Hello" /></body></html>

在项目下创建 static文件夹,用于存放javascript文件或支持网页显示的CSS文件,并在目录下创建一个js文件:static.js文件

function sayHello() {alert("Python 模板文件之静态资源文件")
}

Flask Request对象

Request对象的重要属性如下所列:

  • Form- 它是一个字典对象,包含表单参数及其值的键和值对。

  • args- 解析查询字符串的内容,它是问号(?)之后的URL的一部分。

  • Cookies- 保存Cookie名称和值的字典对象。

  • files- 与上传文件有关的数据。

  • method- 当前请求方法。

    第七节: Flask Request 对象

    Request对象的重要属性如下所列:

    Form - 它是一个字典对象,包含表单参数及其值的键和值对。

    args - 解析查询字符串的内容,它是问号(?)之后的URL的一部分。

    Cookies - 保存Cookie名称和值的字典对象。

    files - 与上传文件有关的数据。

    method - 当前请求方法。

    from flask import Flask, render_template, request

    app = Flask(name)

    @app.route(‘/’)
    def student():
    return render_template(‘student.html’)

    @app.route(‘/result’, methods=[‘POST’, ‘GET’])
    def result():
    if request.method == ‘POST’:
    result = request.form
    return render_template(“result.html”, result=result)

    app.run(debug=True)

在项目下创建 templates 文件夹,用于存放所有模板文件,并在目录下创建一个模板文件:student.html /result.html文件

student.html

<html><body><form action="http://localhost:5000/result" method="POST"><p>姓名 <input type = "text" name = "Name" /></p><p>物理 <input type = "text" name = "Physics" /></p><p>化学 <input type = "text" name = "chemistry" /></p><p>数学 <input type ="text" name = "Mathematics" /></p><p><input type = "submit" value = "提交" /></p></form></body>
</html>

result.html

<html><body><table border = 1>{% for key, value in result.items() %}<tr><th> {{ key }} </th><td> {{ value }}</td></tr>{% endfor %}
</table></body>
</html>

Flask Cookie

Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。

Cookie 核心方法

设置cookie

默认有效期是临时cookie,浏览器关闭就失效,可以通过max_age设置有效期, 单位是秒

 res = make_response('set success')res.set_cookie('username', 'zhouzhiwengang', max_age=3600)

获取cookie

通过request.cookies的方式, 返回的是一个字典。

cookie = request.cookies.get('username')

删除cookie

 res = make_response('del success')res.delete_cookie('username')# 第七节: Flask Cookie 对象
from flask import Flask, make_response, request  # 注意需导入 make_responseapp = Flask(__name__)@app.route('/set_cookie')
def set_cookie():res = make_response('set success')res.set_cookie('username', 'zhouzhiwengang', max_age=3600)return res@app.route('/get_cookie')
def get_cookie():cookie = request.cookies.get('username')return cookie@app.route('/del_cookie')
def del_cookie():res = make_response('del success')res.delete_cookie('username')return resapp.run()

Flask Session

与Cookie不同,Session(会话)数据存储在服务器上。会话是客户端登录到服务器并注销服务器的时间间隔。需要在该会话中保存的数据会存储在服务器上的临时目录中。

为每个客户端的会话分配会话ID。会话数据存储在cookie的顶部,服务器以加密方式对其进行签名。对于此加密,Flask应用程序需要一个定义的SECRET_KEY

Session对象也是一个字典对象,包含会话变量和关联值的键值对。

Session核心方法

设置密钥

app.secret_key = 'abcd12345678'

设置Session会话变量

session['username'] = request.form['username']

删除Session 会话变量

 session.pop('username', None)# 第八节: Flask Session 对象from flask import Flask, session, redirect, url_for, escape, requestapp = Flask(__name__)app.secret_key = 'abcd12345678'@app.route('/')
def index():if 'username' in session:# session 会话获取值username = session['username']return '登录用户名是:' + username + '<br>' + "<b><a href = '/logout'>点击这里注销</a></b>"return "您暂未登录, <br><a href = '/login'></b>" + "点击这里登录</b></a>"@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':user = request.form['username']password = request.form['password']if user == 'admin' and password == '123456':# session 会话设值session['username'] = request.form['username']return redirect(url_for('index'))return '''<form action = "" method = "post"><p>用户名:</p><p><input type = "text" name = "username" /></p><p>密码:</p><p><input type = "password" name = "password" /></p><p><input type = "submit" value = "submit" /></p><p><input type="submit" value ="登录"/></p></form>'''@app.route('/logout')
def logout():# session 会话移除值session.pop('username', None)return redirect(url_for('index'))if __name__ == '__main__':app.run(debug=True)

Flask 错误代码

Flask类具有带有错误代码的**abort()**函数。

Flask.abort(code)

Code参数采用以下值之一:

Flask 消息反馈

Flask 模块包含**flash()**方法。它将后端处理消息传递给前端。

# 第十节: Flask 消息反馈from flask import Flask, redirect, url_for, request, render_template, flashapp = Flask(__name__)
# seesion 会话存储临时目录地址
app.secret_key = 'abcde'@app.route('/')
def index():return render_template('response.html')@app.route('/login', methods=['GET', 'POST'])
def login():error = Noneif request.method == 'POST':user = request.form['user']password = request.form['password']if user == 'admin' and password == '123456':flash('登入成功')return redirect(url_for('index'))else:# 用户验证不通过,反馈相关信息error = '非法用户名或密码,请重新登入'return render_template('login.html', error=error)if __name__ == '__main__':app.run(debug=True)

在项目下创建 templates 文件夹,用于存放所有模板文件,并在目录下创建一个模板文件: login.html /response.html文件

login.html

<html><body><form action = "http://localhost:5000/login" method = "post"><p>用户名:</p><p><input type = "text" name = "user" /></p><p>密码:</p><p><input type = "password" name = "password" /></p><p><input type = "submit" value = "submit" /></p></form>{% if error %}<p><strong>错误信息</strong>: {{ error }}</p>{% endif %}</body>
</html>

response.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Flask 消息反馈</title>
</head>
<body>{% with messages = get_flashed_messages() %}{% if messages %}{% for message in messages %}<p>{{ message }}</p>{% endfor %}{% endif %}{% endwith %}
<h3>Welcome!</h3>
<a href = "{{ url_for('login') }}">登入</a>
</body>
</html>

Flask 文件上传

在 Flask 中处理文件上传非常简单。它需要一个 HTML 表单,其 enctype 属性设置为“multipart/form-data”,将文件发布到 URL。

URL 处理程序从 request.files[] 对象中提取文件,并将其保存到所需的位置。

每个上传的文件首先会保存在服务器上的临时位置,然后将其实际保存到它的最终位置。

目标文件的名称可以是硬编码的,也可以从 request.files[file]?对象的?filename?属性中获取。但是,建议使用 secure_filename() 函数获取它的安全版本。

可以在 Flask 对象的配置设置中定义默认上传文件夹的路径和上传文件的最大大小。

app.config['UPLOAD_FOLDER'] 定义上传文件夹的路径 app.config['MAX_CONTENT_LENGTH'] 指定要上传的文件的最大大小(以字节为单位)# 第十一节: Flask 文件上传from flask import Flask, render_template, request
from werkzeug.utils import secure_filenameimport osapp = Flask(__name__)
UPLOAD_FOLDER = 'upload'
if not os.path.exists(UPLOAD_FOLDER):os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER@app.route('/upload')
def upload_file():return render_template('upload.html')@app.route('/uploader', methods=['GET', 'POST'])
def uploader():if request.method == 'POST':f = request.files['file']print(request.files)f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))return '文件上传成功'else:return render_template('upload.html')if __name__ == '__main__':app.run(debug=True)

Flask 拓展

Flask常用扩展包:

Flask-SQLalchemy:操作数据库;

Flask-script:插入脚本;

Flask-migrate:管理迁移数据库;

Flask-Session:Session存储方式指定;

Flask-WTF:表单;

Flask-Mail:邮件;

Flask-Bable:提供国际化和本地化支持,翻译;

Flask-Login:认证用户状态;

Flask-OpenID:认证;

Flask-RESTful:开发RESTAPI的工具;

Flask-Bootstrap:集成前端TwitterBootstrap框架;

Flask-Moment:本地化日期和时间;

Flask-Admin:简单而可扩展的管理接口的框架

Flask 拓展之Flask-SQLalchemy

SQLAlchemy是一个关系型数据库框架,它提供了高层的ORM和底层的原生数据库的操作。flask-sqlalchemy是一个简化了SQLAlchemy操作的flask扩展。

安装flask-sqlalchemy扩展, 执行如下指令:
pip install -U Flask-SQLAlchemypip install flask-mysqldbpip install pymysql
SQLAlchemy支持字段类型

类型名

python中类型

说明

Integer

int

普通整数,一般是32位

SmallInteger

int

取值范围小的整数,一般是16位

BigInteger

int或long

不限制精度的整数

Float

float

浮点数

Numeric

decimal.Decimal

普通整数,一般是32位

String

str

变长字符串

Text

str

变长字符串,对较长或不限长度的字符串做了优化

Unicode

unicode

变长Unicode字符串

UnicodeText

unicode

变长Unicode字符串,对较长或不限长度的字符串做了优化

Boolean

bool

布尔值

Date

datetime.date

时间

Time

datetime.datetime

日期和时间

LargeBinary

str

二进制文件

SQLAlchemy列选项

选项名

说明

primary_key

如果为True,代表表的主键

unique

如果为True,代表这列不允许出现重复的值

index

如果为True,为这列创建索引,提高查询效率

nullable

如果为True,允许有空值,如果为False,不允许有空值

default

为这列定义默认值

SQLAlchemy关系选项

选项名

说明

backref

在关系的另一模型中添加反向引用

primary join

明确指定两个模型之间使用的联结条件

uselist

如果为False,不使用列表,而使用标量值

order_by

指定关系中记录的排序方式

secondary

指定多对多中记录的排序方式

secondary join

在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件

Flask-SQLalchemy 实战之快速入门
# 第十一节: Flask 拓展之数据库(flask-sqlalchemy), 快速入门
# 导入Flask及相关扩展库
from flask import Flask
from flask_sqlalchemy import SQLAlchemy# 创建Flask应用实例
app = Flask(__name__)# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)# 定义ORM模型,表示数据库表
class Table(db.Model):__tablename__ = 'base_house'id = db.Column(db.String(255), primary_key=True)# 路由函数,查询库下所有表名,并返回
@app.route('/')
def get_tables():tables = Table.query.all()house_list = []for user in tables:user_data = {'id': user.id}house_list.append(user_data)return {'users': house_list}if __name__ == '__main__':app.run()
Flask-SQLalchemy 实战之分页查询和参数筛选
# 第十一节: Flask 拓展之数据库(flask-sqlalchemy), 分页 + 入参查询
# 导入Flask及相关扩展库
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy# 创建Flask应用实例
app = Flask(__name__)# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)# 定义ORM模型,表示数据库表
class Table(db.Model):__tablename__ = 'base_house'id = db.Column(db.String(255), primary_key=True)project_no = db.Column(db.String(255))project_name = db.Column(db.String(255))project_address = db.Column(db.String(255))# 路由函数,查询库下所有表名,并返回
@app.route('/', methods=['POST'])
def get_tables():parame_json = request.get_json()page = parame_json.get('page')size = parame_json.get('size')name = parame_json.get('name')if name:houses = Table.query.filter_by(project_name=name).paginate(page=page, per_page=size, error_out=False)else:houses = Table.query.paginate(page=page, per_page=size, error_out=False)house_list = []for house in houses:house_data = {'id': house.id,'projectNo': house.project_no,'projectName': house.project_name,'projectAddress': house.project_address}house_list.append(house_data)return jsonify({'users': house_list,'total_pages': houses.pages,'current_page': houses.page})if __name__ == '__main__':app.run()

涉及base_house 表DDL:

CREATE TABLE `base_house` (`id` varchar(64) NOT NULL,`project_no` varchar(128) DEFAULT NULL,`project_name` varchar(256) DEFAULT NULL,`project_address` varchar(256) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Flask 拓展之Flask-Login

扩展Flask-Login提供了实现用户认证需要的各类功能函数,我们将使用它来实现程序的用户认证,首先来安装它:

pip install flask-login

app.py:初始化 Flask-Login

from flask_login import LoginManagerlogin_manager = LoginManager(app)  # 实例化扩展类@login_manager.user_loader
def load_user(user_id):  # 创建用户加载回调函数,接受用户 ID 作为参数user = User.query.get(int(user_id))  # 用 ID 作为 User 模型的主键查询对应的用户return user  # 返回用户对象

Table模型类继承 Flask-Login 提供的UserMixin类:

# 定义ORM模型,表示数据库表
class Table(UserMixin, db.Model):__tablename__ = 't_admin'id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(30))userpwd = db.Column(db.String(100))# 第十二节: Flask 拓展之数据库(flask-sqlalchemy)/认证框架(flask-login), 使用用户登入并方法鉴权
from flask import Flask, request, jsonify, redirect, url_for, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user# 创建Flask应用实例
app = Flask(__name__)
# seesion 会话存储临时目录地址
app.secret_key = 'abcde1234'# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)# 初始化登录管理器
login_manager = LoginManager()
login_manager.init_app(app)# 定义ORM模型,表示数据库表
class Table(UserMixin, db.Model):__tablename__ = 't_admin'id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(30))userpwd = db.Column(db.String(100))# 加载用户的回调函数
@login_manager.user_loader
def load_user(user_id):return Table.query.get(int(user_id))# 定义登录路由
@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']user = Table.query.filter_by(username=username).first()if user and user.userpwd == password:login_user(user)return redirect(url_for('dashboard'))return render_template('auth_login.html')# 定义需要鉴权的页面
@app.route('/dashboard')
@login_required
def dashboard():return render_template('dashboard.html')# 定义登出路由
@app.route('/logout')
@login_required
def logout():logout_user()return redirect(url_for('login'))if __name__ == '__main__':app.run()

Flask 拓展之Flask-JWT-Extended

JWT简介

具体原理请参考:JSON Web Token 入门教程

JWT结构

JWT由三部分组成:

  • 头部(Header):通常包含令牌的类型(JWT)和使用的加密算法。
  • 载荷(Payload):包含有关用户或其他数据的信息。例如,用户ID、角色或其他自定义数据。
  • 签名(Signature):由头部、载荷和密钥组合而成的签名,用于验证令牌的完整性和来源可信度。
JWT生成和校验
  1. 用户登录时,服务器使用密钥签署JWT,并将其返回给客户端。
  2. 客户端在以后的请求中发送JWT作为身份验证令牌。
  3. 服务器验证JWT的签名以确保其完整性,然后使用载荷中的信息进行用户身份验证和授权。
Flask-JWT-Extended

Flask-JWT-Extended是一个Python库,用于在Flask应用程序中添加JSON Web令牌(JWT)支持。它是一个插件,可以通过安装它来扩展Flask应用程序的功能。

官网地址:Flask-JWT_Extended 官网

Flask-JWT-Extended安装
pip install Flask-JWT-Extended

实战:Flask-SQLalchemy + MySQL 8 + Flask-JWT-Extended 实现前后端分离用户认证和鉴权。

# _*_ coding : UTF-8_*_
# 开发者 : zhuozhiwengang
# 开发时间 : 2024/4/19 9:26
# 文件名称 : 19
# 开发工具 : PyCharm
# 第十二节: Flask 拓展之数据库(flask-sqlalchemy)/认证框架(flask-jwt-extend), 实现用户前后端分离认证和鉴权
from flask import Flask, request, jsonify, redirect, url_for, render_template, abort
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import (JWTManager, jwt_required, create_access_token, get_jwt_identity)# 创建Flask应用实例
app = Flask(__name__)
# 用于签名JWT的密钥
app.config['JWT_SECRET_KEY'] = 'abc123'# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)# 初始化JWT扩展
jwt = JWTManager(app)# 定义ORM模型,表示数据库表
class Table(db.Model):__tablename__ = 't_admin'id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(30))userpwd = db.Column(db.String(100))# 定义登录路由
@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']user = Table.query.filter_by(username=username).first()if user and user.userpwd == password:access_token = create_access_token(identity=username)return jsonify(access_token=access_token)else:# 用户名或密码错误abort(401)# 定义需要鉴权的页面
@app.route('/dashboard')
@jwt_required()  # 这个装饰器要求请求必须携带有效的JWT令牌
def dashboard():# 使用get_jwt_identity访问当前用户的身份current_user = get_jwt_identity()return jsonify(logged_in_as=current_user)if __name__ == '__main__':app.run()

第一种情况:输入错误用户名或密码,提示401错误代码

控制台输出信息:

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.* Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [19/Apr/2024 09:36:45] "POST /login HTTP/1.1" 401 -

第二种情况:输入正确用户名和密码,获取凭证Token

第三种情况:拼接头信息,访问受保护资源

Flask-JWT-Extended 核心代码讲解

初始化

from flask import Flask
from flask_jwt_extended import (JWTManager, jwt_required, create_access_token, get_jwt_identity)app = Flask(__name__)
# 用于签名JWT的密钥
app.config['JWT_SECRET_KEY'] = 'your-secret-key' # 初始化JWT扩展
jwt = JWTManager(app)

生成和校验

  • 定义了/login路由,用于用户登录并获取JWT令牌。在这个路由中,首先从请求中获取用户名和密码(这里是 “zzg” 和 “123456”)。如果匹配成功,就使用create_access_token函数生成JWT令牌,并返回给客户端。
  • 定义了/protected路由,它是受保护的路由,只有在请求中包含有效的JWT令牌时才能访问。这是通过@jwt_required()装饰器实现的。
    • 如果请求中没有有效的JWT令牌,访问该路由会返回未授权的响应。
    • 如果令牌有效,路由会使用get_jwt_identity()函数获取JWT中的身份信息(在示例中为用户名)然后返回一个JSON响应,显示已登录的用户
Flask-JWT-Extended 优化:设置Token有效期、刷新Token

设置Token有效期

设置JWT的过期时间是一种重要的安全措施,可以帮助确保令牌不会无限期有效,提高了应用程序的安全性。

方法一:

使用app.config['JWT_ACCESS_TOKEN_EXPIRES']来设置JWT的访问token默认过期时间为1小时。

# 设置ACCESS_TOKEN的默认过期时间为1小时
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=1)

方法二:

当使用create_access_token函数创建JWT令牌时,也可以通过传递expires_delta参数来覆盖默认的过期时间,例如:

  • 这将覆盖默认的过期时间,使得令牌在30分钟后过期。

    from datetime import timedelta

    设置ACCESS_TOKEN的默认过期时间为30分钟

    access_token = create_access_token(identity=username, expires_delta=timedelta(minutes=30))

刷新Token

认证Token与刷新Token差异

访问tokenAccess Token

刷新tokenRefresh Token

用途

用于访问受保护的资源

用于获取新的访问token

生命周期

默认为15分钟

默认为30天

显式指定生命周期

JWT_ACCESS_TOKEN_EXPIRES

JWT_REFRESH_TOKEN_EXPIRES

储存方式

在请求的头信息(Header)中的 “Authorization” 字段中

一般存储在服务器端的数据库

每个用户生成的刷新token访问token是一一对应的,

当用户登录成功后,服务器会为该用户生成一对刷新token访问token,并将它们关联到用户的身份(通常是用户的用户名或ID)。这样,每个用户都有自己唯一的刷新token访问token

刷新token用于获取新的访问token,以延长用户的会话时间。只有拥有有效的刷新token的用户才能获取新的访问token,而访问token则用于实际访问受保护的资源。

实战:Flask-SQLalchemy + MySQL 8 + Flask-JWT-Extended 实现前后端分离用户认证和鉴权。添加刷新Token和使用刷新Token鉴权。

# 第十二节: Flask 拓展之数据库(flask-sqlalchemy)/认证框架(flask-jwt-extend), 实现用户前后端分离认证和鉴权
from flask import Flask, request, jsonify, redirect, url_for, render_template, abort
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import (JWTManager, jwt_required, create_access_token, get_jwt_identity, create_refresh_token)# 创建Flask应用实例
app = Flask(__name__)
# 用于签名JWT的密钥
app.config['JWT_SECRET_KEY'] = 'abc123'# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)# 初始化JWT扩展
jwt = JWTManager(app)# 定义ORM模型,表示数据库表
class Table(db.Model):__tablename__ = 't_admin'id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(30))userpwd = db.Column(db.String(100))# 定义登录路由
@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']user = Table.query.filter_by(username=username).first()if user and user.userpwd == password:access_token = create_access_token(identity=username)refresh_token = create_refresh_token(identity=username)return jsonify(access_token=access_token, refresh_token=refresh_token)else:# 用户名或密码错误abort(401)# 使用刷新token获取新的访问token
@app.route("/refresh", methods=["POST"])
@jwt_required(refresh=True)  # 使用刷新token进行验证
def refresh():current_user = get_jwt_identity()access_token = create_access_token(identity=current_user)return jsonify(access_token=access_token)# 定义需要鉴权的页面
@app.route('/dashboard')
@jwt_required()  # 这个装饰器要求请求必须携带有效的JWT令牌
def dashboard():# 使用get_jwt_identity访问当前用户的身份current_user = get_jwt_identity()return jsonify(logged_in_as=current_user)if __name__ == '__main__':app.run()

相关截图:

Flask 拓展之flask_restful

flask_restful安装

pip install flask_restful

实战:Flask-SQLalchemy + MySQL 8 +Flask_Restful 实现Restful 接口

from flask import Flask, request, jsonify
from flask_restful import Api, Resource
from flask_sqlalchemy import SQLAlchemy# 创建Flask应用实例
app = Flask(__name__)# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@192.168.43.10/house'
db = SQLAlchemy(app)
api = Api(app)# 定义ORM模型,表示数据库表
class Table(db.Model):__tablename__ = 'base_house'id = db.Column(db.String(255), primary_key=True)project_no = db.Column(db.String(255))project_name = db.Column(db.String(255))project_address = db.Column(db.String(255))class UserAPI(Resource):def get(self, user_id):user = Table.query.get(user_id)if user:return {'id': user.id, 'projectNo': user.project_no, 'projectName': user.project_name, 'projectAddress': user.project_address}else:return {'message': 'House not found'}, 404def post(self):data = request.get_json()new_user = Table(project_no=data['projectNo'], project_name=data['projectName'], project_address=data['projectAddress'], id=data['id'])db.session.add(new_user)db.session.commit()return {'message': '创建成功'}, 201def delete(self, user_id):user = Table.query.get(user_id)if user:db.session.delete(user)db.session.commit()return {'message': '删除成功'}else:return {'message': '记录未找到'}, 404api.add_resource(UserAPI, '/user', '/user/<user_id>')if __name__ == '__main__':app.run(port=8081)

Flask 高级

待补充Flask高级内容主要涉及:Python 多线程、Python连接Redis、Python连接MongoDB、Python 连接Elasticsearch、Python MinoIO 文件服务器。

相关文章:

Python Flask Web框架快速入门

Flask 入门Demo Flask 开发环境搭建&#xff0c;执行如下指令&#xff1a; pip install flask# 第一节: Flask 快速入门from flask import Flask app Flask(__name__)app.route(/flask) def hello_flask():return Hello Flaskapp.run()核心代码剖析&#xff1a; 从flask包导…...

【java学习笔记】Set接口实现类-LinkedHashSet

一、LinkedHashSet的全面说明 &#xff08;就是把数组不同位置的链表当成一个节点然后相连&#xff09;...

阿里云ACP云计算模拟试题(附答案解析)

1、将基础设施作为服务的云计算服务类型是_____服务。 A.laas B.Paas C.SaaS D.Daas 答案&#xff1a;A 解析&#xff1a;基础设施即服务有时缩写为 IaaS&#xff0c;包含云 IT 的基本构建块&#xff0c;通常提供对联网功能、计算机&#xff08;虚拟或专用硬件&#x…...

java 缓存篇2

缓存的部署方式 单机主从哨兵集群 特性主从&#xff08;Master-Slave&#xff09;哨兵&#xff08;Sentinel&#xff09;集群&#xff08;Cluster&#xff09;数据分片不支持不支持支持&#xff0c;基于 slot 进行水平分片高可用性部分支持&#xff08;手动故障转移&#xff…...

12.11-12.12总结(约瑟夫问题 机器翻译 滑动窗口)

12.11 刷题 《算法竞赛》这本书看了很多了&#xff0c;但是题目没咋做&#xff0c;所以今天来刷一下题 P1996约瑟夫问题 还依稀记得大一的时候被约瑟夫支配的恐惧&#xff08;哭&#xff09;&#xff0c;但是现在做就感觉很简单&#xff08;虽然也敲了一会&#xff0c;今早感…...

Elasticsearch+Kibana+IK分词器+拼音分词器安装

目录 ES报错 Kibanaik分词器拼音分词器 安装都比较简单&#xff0c;可以参考这几篇博客 ES 如何在 Linux&#xff0c;MacOS 及 Windows 上进行安装 Elasticsearch 报错 ES启动报错error downloading geoip database [GeoLite2-ASN.mmdb] Kibana KIBANA的安装教程&#xff…...

2020 年“泰迪杯”数据分析职业技能大赛A 题教育平台的线上课程智能推荐策略

2020 年“泰迪杯”数据分析职业技能大赛A 题教育平台的线上课程智能推荐策略 完整代码请私聊 博主 一、 背景 近年来&#xff0c;随着互联网与通信技术的高速发展&#xff0c;学习资源的建设与共享呈现出新的发展趋势&#xff0c;各种网课、慕课、直播课等层出不穷&#xff0c…...

运维面试题

1 deployment和statefulset区别 Kubernetes (k8s) 中的 Deployment 和 StatefulSet 是两种不同类型的控制器&#xff0c;用于管理应用的生命周期&#xff0c;但它们适用于不同的应用场景。以下是它们在存储、调度顺序和网络分配方面的区别&#xff1a; 存储 Deployment: 适用…...

计算机网络之网络层超详细讲解

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络之网络层超详细讲解 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; …...

Windows桌面系统管理2:VMware Workstation使用和管理

Windows桌面系统管理0:总目录-CSDN博客 Windows桌面系统管理1:计算机硬件组成及组装-CSDN博客 Windows桌面系统管理2:VMware Workstation使用和管理 Windows桌面系统管理3:Windows 10操作系统部署与使用-CSDN博客 Windows桌面系统管理4:Windows 10操作系统运维管理-…...

深入理解 CSS 文本换行: overflow-wrap 和 word-break

前言 正常情况下&#xff0c;在固定宽度的盒子中的中文会自动换行。但是&#xff0c;当遇到非常长的英文单词或者很长的 URL 时&#xff0c;文本可能就不会自动换行&#xff0c;而会溢出所在容器。幸运的是&#xff0c;CSS 为我们提供了一些和文本换行相关的属性&#xff1b;今…...

【Linux】Ubuntu:安装系统后配置

hostname&#xff1a;更改主机名 打开终端。 使用hostnamectl命令更改主机名。 sudo hostnamectl set-hostname 新的主机名你可以使用hostnamectl 命令来验证更改是否成功&#xff1a; hostnamectlChrome&#xff1a;更换默认浏览器 以下是从 Ubuntu 中移除预装的 Snap 版 Fi…...

我们来学mysql -- MSI安装(安装篇)

主题 书接上文&#xff0c;在《探讨win安装方式》中官方推荐MSI要是把大厂的标准奉为圭臬&#xff0c;说啥认啥&#xff0c;他一翻脸&#xff0c;小丑不就是咱了再说了&#xff0c;都干到家门口了8.4版本官方文档&#xff0c;还不给他梭罗下 MSI 点击**.msi弹出MySQL Install…...

MySQL其一,概念学习,可视化软件安装以及增删改查语句

目录 MySQL 1、数据库的概念 2、数据库分类 3、MySQL的安装 4、安装过程中的问题 DataGrip的使用&#xff1a; SQLynx的使用&#xff1a; 5、编写SQL语句 6、DDL语句 7、DML 新增数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; MySQL SQL其实是一门…...

SpringCloud 题库

这篇文章是关于 SpringCloud 面试题的汇总&#xff0c;包括微服务的概念、SpringCloud 的组成及相关技术&#xff0c;如服务注册与发现、负载均衡、容错等&#xff0c;还涉及 Nacos 配置中心、服务注册表结构等原理&#xff0c;以及微服务架构中的日志采集、服务网关、相关概念…...

【ETCD】[源码阅读]深度解析 EtcdServer 的 processInternalRaftRequestOnce 方法

在分布式系统中&#xff0c;etcd 的一致性与高效性得益于其强大的 Raft 协议模块。而 processInternalRaftRequestOnce 是 etcd 服务器处理内部 Raft 请求的核心方法之一。本文将从源码角度解析这个方法的逻辑流程&#xff0c;帮助读者更好地理解 etcd 的内部实现。 方法源码 …...

数据分析与机器学习全解析

一、数据分析基础要点 &#xff08;一&#xff09;数据收集 确定数据源&#xff1a;明确是内部数据库、外部公开数据、传感器采集还是用户调研等来源&#xff0c;不同来源数据质量与获取难度各异。例如内部销售数据可直接获取&#xff0c;而市场调研数据需设计问卷并投入人力收…...

Qt 一个简单的QChart 绘图

Qt 一个简单的QChart 绘图 先上程序运行结果图&#xff1a; “sample9_1QChart.h” 文件代码如下&#xff1a; #pragma once#include <QtWidgets/QMainWindow> #include "ui_sample9_1QChart.h"#include <QtCharts> //必须这么设置 QT_CHARTS_USE_NAME…...

力扣——322. 零钱兑换

给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...

Qt之网络监测

在Qt中&#xff0c;网络监测通常涉及到检测网络连接状态、网络延迟、带宽使用情况等。Qt提供了一些类和模块来帮助开发者实现这些功能。以下是一些常用的方法和类&#xff1a; 1. 检测网络连接状态 QtNetwork模块中的QNetworkConfigurationManager类可以用来检测设备的网络连…...

抓包软件fiddler和wireshark使用手册

fiddler官方文档 Fiddler 抓包教程1 Fiddler 抓包教程2 wireshark抓包学习 2添加链接描述 ip 过滤 ip.src_host ip.dst_host ip.addr mac 过滤 eth.src eth.dst eth.addr 端口过滤 tcp.port tcp.srcport tcp.dstport 协议类型过滤 arp dhcp 规则组合 and or...

【从零开始入门unity游戏开发之——C#篇03】变量和常量

文章目录 一、变量1、什么是变量&#xff1f;2、申明变量的固定写法3、变量的类型值和引用类型的区别无符号和有符号位——表示变量所占用的内存空间的大小范围——表示变量的取值范围取值范围和存储单位的关系为什么byte的范围是 0 到 255&#xff1f;为什么 sbyte 的范围是 -…...

SpringBoot 手动实现动态切换数据源 DynamicSource (上)

大家好&#xff0c;我是此林。 在实际开发中&#xff0c;经常可能遇到在一个SpringBoot Web应用中需要访问多个数据源的情况。 下面来介绍一下多数据源的使用场景、底层原理和手动实现。 一、 多数据源经典使用场景 场景一&#xff1a;业务复杂&#xff0c;数据量过大 1. 业务…...

ERROR Error: command failed: yarnError: command failed: yarn

1、异常信息 2、解决 解决方法一&#xff1a; WinR进入命令行&#xff0c;重新安装npm(如果报镜像源问题建议镜像源也重新配置) 输入命令&#xff0c;重新安装npm/yarn #npm npm install#npm 配置镜像源 npm config set registry https://registry.npmmirror.com#npm 查看镜…...

【java】finalize方法

目录 1. 说明2. 调用过程3. 注意事项 1. 说明 1.finalize方法是Java中Object类的一个方法。2.finalize方法用于在对象被垃圾回收之前执行一些清理工作。3.当JVM&#xff08;Java虚拟机&#xff09;确定一个对象不再被引用、即将被回收时&#xff0c;会调用该对象的finalize方法…...

C++ 内存管理和模板与STL

此篇目是之后各种C库的基础 目录 内存管理 内存分布 内存管理方式 new和delete operator new 与 operator delete函数 实现原理 定位new表达式(placement-new) 模板基础 泛型编程 模板 函数模板 类模板 STL 组成部分 内存管理 内存分布 int globalVar 1; //全局变量 静…...

同一个局域网下的两台电脑实现定时或者实时拷贝数据

【亲测能用】 需求&#xff1a;从数据库服务器上将数据库备份文件*.bak&#xff0c;每天定时拷贝到局域网下另一台电脑上&#xff0c;实现异机备份。 本文中192.168.1.110是本机&#xff0c;192.168.1.130是异机&#xff08;备份机&#xff09;。需求是每天定时从192.168.1.1…...

Python毕业设计选题:基于django+vue的汽车租赁管理网站

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 用户管理 汽车品牌管理 汽车信息管理 汽车租赁管理 汽车商品信息管理 汽车租赁 购物…...

scrapy对接rabbitmq的时候使用post请求

之前做分布式爬虫的时候,都是从push url来拿到爬虫消费的链接,这里提出一个问题,假如这个请求是post请求的呢,我观察了scrapy-redis的源码,其中spider.py的代码是这样写的 1.scrapy-redis源码分析 def make_request_from_data(self, data):"""Returns a Reques…...

Netty 性能优化与调试指南

Netty 是一款高性能的网络通信框架&#xff0c;其高性能得益于良好的设计和优化。但是在实际使用中&#xff0c;如果配置或实现不当&#xff0c;可能会导致性能下降或调试困难。本文将从性能优化和调试两方面入手&#xff0c;详细讲解如何在使用 Netty 时提高应用性能和诊断问题…...

网络安全产品之认识WEB应用防火墙

随着B/S架构的广泛应用&#xff0c;Web应用的功能越来越丰富&#xff0c;蕴含着越来越有价值的信息&#xff0c;应用程序漏洞被恶意利用的可能性越来越大&#xff0c;因此成为了黑客主要的攻击目标。传统防火墙无法解析HTTP应用层的细节&#xff0c;对规则的过滤过于死板&#…...

R学习——因子

目录 1 定义因子&#xff08;factor函数&#xff09; 2因子的作用 一个数据集中的 只需要考虑可以用哪个数据来进行分类就可以了&#xff0c;可以用来分类就可以作为因子。 Cy1这个因子对应的水平level是4 6 8&#xff1a; 1 定义因子&#xff08;factor函数&#xff09; 要…...

2024 亚马逊云科技re:Invent:Werner Vogels架构哲学,大道至简 六大经验助力架构优化

在2024亚马逊云科技re:Invent全球大会第四天的主题演讲中&#xff0c;亚马逊副总裁兼CTO Dr.Werner Vogels分享了 The Way of Simplexity&#xff0c;繁简之道&#xff0c;浓缩了Werner在亚马逊20年构建架构的经验。 Werner表示&#xff0c;复杂性总是会“悄无声息”地渗透进来…...

【代码随想录day58】【C++复健】 117. 软件构建(拓扑排序);47. 参加科学大会(dijkstra(朴素版)精讲)

117. 软件构建&#xff08;拓扑排序&#xff09; 继续边看解析边做题&#xff0c;思考时的问题做个如下的总结&#xff1a; 1. 存边用什么数据结构&#xff1f; 在题目中&#xff0c;我们需要存储节点之间的依赖关系&#xff08;边信息&#xff09;。选择适合的数据结构非常重…...

单目深度估计模型 lite-mono 测试

lite-mono 使用工业数据集kitti 进行训练&#xff0c;目的使用单目摄像头实现物体深度预测&#xff0c;关于kitti数据集的介绍和下载参考 &#xff08;二&#xff09;一文带你了解KITTI数据集-CSDN博客文章浏览阅读2.7w次&#xff0c;点赞64次&#xff0c;收藏294次。文章介绍…...

JAVA基础学习笔记_网络编程

文章目录 网络编程网络编程三要素IPIPv4细节InetAddress 端口号协议 UDPUDP协议(发数据)UDP协议(接受数据)UDP聊天室单播,组播,广播 TCP中文乱码问题代码细节,三次握手和四次挥手 网络编程 计算机之间通过网络进行数据传输 软件结构 C/S,Client/Server,客户端服务器,精美但麻…...

说下JVM中一次完整的GC流程?

大家好&#xff0c;我是锋哥。今天分享关于【说下JVM中一次完整的GC流程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 说下JVM中一次完整的GC流程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中&#xff0c;垃圾回收&#xff08;GC&am…...

鸿蒙NEXT开发案例:保质期计算

【引言】 保质期计算应用是一个基于鸿蒙NEXT框架开发的数字和文本统计组件。用户可以输入商品的生产日期和保质期天数&#xff0c;应用会自动计算并展示相关信息&#xff0c;包括保质状态、剩余天数、生产日期和到期日期。 【环境准备】 • 操作系统&#xff1a;Windows 10 …...

LLM并发加速部署方案(llama.cpp、vllm、lightLLM、fastLLM)

大模型并发加速部署 解析当前应用较广的几种并发加速部署方案&#xff01; llama.cpp、vllm、lightllm、fastllm四种框架的对比&#xff1a; llama.cpp&#xff1a;基于C&#xff0c;①请求槽&#xff0c;②动态批处理&#xff0c;③CPU/GPU混合推理vllm&#xff1a;基于Pyth…...

用最小的代价解决mybatis-plus关于批量保存的性能问题

1.问题说明 问题背景说明&#xff0c;在使用达梦数据库时&#xff0c;mybatis-plus的serviceImpl.saveBatch()方法或者updateBatchById()方法的时候&#xff0c;随着数据量、属性字段的增加&#xff0c;效率越发明显的慢。 serviceImpl.saveBatch(); serviceImpl.updateBatch…...

蓝桥杯历届真题 --#递推 翻硬币(C++)

文章目录 思路完整代码结语 原题链接 思路 通过观察测试用例&#xff0c;我们猜测&#xff0c;从左到右依次对比每一个位置上的状态&#xff0c;如果不一样我们就翻一次&#xff0c;最终得到的答案即为正解。 完整代码 //这里是引入了一些常用的头文件,和一些常规操作 //第一…...

BurpSuite-8(FakeIP与爬虫审计)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;IP伪造和爬虫审计_哔哩哔哩_bilibili 一、FakeIP 1.配置环境 BurpSuite是java环境下编写的&#xff0c;而今天的插件是python编写的&#xff0c…...

JAVA8、Steam、list运用合集

Steam运用 Java Stream API为开发人员提供了一种函数式和声明式的方式来表达复杂的数据转换和操作,使代码更加简洁和富有表现力。 1、使用原始流以获得更好的性能【示例:求和】 使用 int、long 和 double 等基本类型时,请使用IntStream、LongStream 和 DoubleStream 等基本流…...

深入详解人工智能机器学习:强化学习

目录 强化学习概述 强化学习的基本概念 定义 关键组件 强化学习过程 常用算法 应用示例 示例代码 代码解释 应用场景 强化学习核心概念和底层原理 核心概念 底层原理 总结 强化学习概述 强化学习&#xff08;Reinforcement Learning, RL&#xff09;是机器学习中的…...

docker的简单使用

文章目录 docker简介docker架构镜像和容器镜像有关的常用命令容器相关常用命令 docker简介 Docker是一个开源的应用容器引擎&#xff0c;基于Go语言并遵从Apache2.0协议开源。 Docker可以让开方子打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到…...

启动的docker容器里默认运行dockerd

问题 已在Dockerfile里yum install docker 但docker run 启动容器后, docker ps等命令无法执行 ps -aux 没有dockerd 进程 临时解决 另开一个终端 docker exec -it 容器名 bash 手动启 dockerd 默认启动 分析 现在启动容器的默认命令是 /sbin/init sbin/init 是根文件系统…...

Python爬虫技术的最新发展

在互联网的海洋中&#xff0c;数据就像是一颗颗珍珠&#xff0c;而爬虫技术就是我们手中的潜水艇。2024年&#xff0c;爬虫技术有了哪些新花样&#xff1f;让我们一起潜入这个话题&#xff0c;看看最新的发展和趋势。 1. 异步爬虫&#xff1a;速度与激情 随着现代Web应用的复…...

什么是厄尔米特(Hermitian)矩阵?

厄米矩阵&#xff08;Hermitian Matrix&#xff09;定义 在数学和物理中&#xff0c;厄米矩阵是满足以下条件的复方阵&#xff1a; A A † \mathbf{A}\mathbf{A}^\dagger AA† 其中&#xff0c; A † \mathbf{A}^\dagger A†表示矩阵 A \mathbf{A} A的共轭转置&#xff0c;即…...

从零开始:Linux 环境下的 C/C++ 编译教程

个人主页&#xff1a;chian-ocean 文章专栏 前言&#xff1a; GCC&#xff08;GNU Compiler Collection&#xff09;是一个功能强大的编译器集合&#xff0c;支持多种语言&#xff0c;包括 C 和 C。其中 gcc 用于 C 语言编译&#xff0c;g 专用于 C 编译。 Linux GCC or G的安…...

Excel + Notepad + CMD 命令行批量修改文件名

注意&#xff1a;该方式为直接修改原文件的文件名&#xff0c;不会生成新文件 新建Excel文件 A列&#xff1a;固定为 renB列&#xff1a;原文件名称C列&#xff1a;修改后保存的名称B列、C列&#xff0c;需要带文件后缀&#xff0c;为txt文件就是.txt结尾&#xff0c;为png图片…...