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

Python WSGI 与 Web 开发框架

目录

文章目录

  • 目录
  • WSGI
    • WSGI 的工作原理
      • environ 参数
      • start_resposne 参数
    • WSGI 的中间件
  • WSGI Web 开发框架
  • OpenStack 中的应用案例
    • 进程入口
    • WSGI Application 加载
      • Paste/PasteDeploy
      • Routes
      • WebOb
    • WSGI Server 启动

WSGI

WSGI(Web Server Gateway Interface,Web 服务器网关接口)是一个 Python Web Application 和 Web Server 之间的标准交互接口规范,定义了 Web Application 如何集成到不同的 Web Server(e.g. Apache、Nginx 等)、或高并发的网络框架(e.g. Eventlet)中的交互标准,包括调用接口函数、请求和响应的数据结构以及环境变量等等,使得它们能够协同工作。类似于 Java 的 Servlet。

WSGI 的核心思想就是将 Web Application 和 Web Server 进行解耦,在解耦之后,还可以在它们两者之间再加入一个 “中间层" 来完成灵活的功能组合:

  • WSGI Server:本质是一个 HTTP 服务器,提供 HTTP 协议的处理,例如:IP、Port、虚拟主机等。HTTP Request 首先到达 WSGI Server,然后再被转发到 WSGI Middleware 或 WSGI Application。
  • WSGI Middleware:作为一个中间层,可以在传递 HTTP Request 到 WSGI Application 的过程中完成一系列可组合的预先处理。例如:身份验证、日志记录等。
  • WSGI Application:是 Web Application 的核心业务实现,可以使用不同的 Web 框架(e.g. Flask、Django 等)进行开发,根据功能需求提供多样的 API 资源类型和处理逻辑。

通过这样的解耦,使得开发者可以选用理想的 Web 框架进行开发而无需关注 Web Server 的实现细节,同时也能够将这些 Web Application 部署到不同类型的 Web Server 上运行,例如:在 Apache 上安装 wsgi_mod 模块、在 Nginx 上安装 uWSGI 模块以支持 WSGI 规范。定义这些规范的目的是为了定义统一的标准,提升程序的可移植性。

WSGI 的工作原理

从 WSGI Server 的角度看,它首先需要知道如何调用 WSGI Application,并将 HTTP Request 传递给它,然后再从 Application 处接收到返回的 HTTP Response,再最终返回给 Client。

所以 WSGI 规范为 Server 和 Application 之间的交互定义了一个唯一且统一的 application() 接口,并由 Application 实现、由 Server 调用。接口的原型如下:

def application(environ, start_response):pass

Application 通常会以 Python Module 或 app 实例对象的方式来提供这个 application() 接口。以 web.py 框架为例,它本身是一个 Python Module 实现了 application(),可以被 Server 导入并调用。application() 作为 Application 的唯一入口,所以 Server 会将所有 HTTP Requests 都调用这个接口来进行处理。

import weburls = ('/.*', 'hello',
)class hello(object):def GET(self):return "Hello, world."app = web.application(urls, globals()).wsgifunc()

environ 参数

environ(环境参数)是一个 Dict 类型对象,用于存放下列数据:

  1. HTTP Request 信息;
  2. CGI(通用网管接口规范)环境变量信息;
  3. WSGI 环境变量信息;
  4. OS 环境变量信息;
  5. Server 环境变量信息。

其中,CGI 环境变量信息包括:

  • SERVER_NAME 和 SERVER_PORT:HTTP Request 的 URL 中的 Hostname 和 Port。
  • PATH_INFO(URL 路径信息):HTTP Request 的 URL 中核心的 API Resource 路径信息。
  • QUERY_STRING(查询字符串): HTTP Request 的 URL 中可能会包含查询字符串,使用 ? 号标识。
  • SCRIPT_NAME(脚本名称):HTTP Request 的 URL 中可能会包含一些脚本的名称。
  • REQUEST_METHOD(请求方法):HTTP Request 的 Methods,包括:GET、POST、PUT、DELETE 等;
  • CONTENT_TYPE:HTTP Headers 中的 content-type 信息。
  • CONTENT_LENGTH:HTTP Headers 中的 content-length 信息。
  • SERVER_PROTOCOL:Server 的 HTTP 协议版本信息。

WSGI 环境变量信息包括:

  • wsgi.version:WSGI 规范的版本;
  • wsgi.url_scheme:HTTP 或 HTTPS;
  • wsgi.input:一个类文件的输入流,Application 通过这个获取 HTTP Request Body;
  • wsgi.errors: 一个类文件的输出流,当 Application 出错时,可以将错误信息写入这里;
  • wsgi.multithread:当 Application 可能被多个线程同时调用时,这个值需要为 True;
  • wsgi.multiprocess: 当 Application 对象可能被多个进程同时调用时,这个值需要为 True;
  • wsgi.run_once:当 Server 期望 Application 在进程的生命周期内只被调用一次时,该值需要为 True。

start_resposne 参数

start_resposne(回调函数参数)指向一个 Server 实现的回调函数,Application 通过这个回调函数返回 HTTP Response 给 Server。

WSGI 规范定义了这个由 Server 实现的回调函数可以接受 2 个必选参数和 1 个可选参数:

start_resposne(status, resposne_headers, exc_info=None)
  • status:必选,String 类型,返回 HTTP Response Status Code;
  • resposne_headers:必选,Dict 类型,返回 HTTP Response Headers;
  • exc_info:可选,返回可能的 HTTP Response Error Message 或 Body 信息。
def application(environ, start_response):status = '200 OK'response_headers = [('Content-type', 'text/plain')]start_response(status, response_headers)return ['hello, world']

WSGI 的中间件

如下图所示,WSGI Middleware 本身兼具了 WSGI Applicant 和 WSGI Server 的角色。因此它可以在两端之间起协调作用,经过不同的 Middleware,便拥有了不同的功能,例如:URL 路由转发、身份权限认证。

  1. Server 收到 HTTP Request 后,生成 environ_s,并且定义了 start_response_s 回调函数。
  2. Server 调用 Middleware 的 application(),传递 environ_s 和 start_response_s。
  3. Middleware 根据 environ_s 执行业务逻辑,生成 environ_m,并且定义了 start_response_m 回调函数。
  4. Middleware 再调用 Application 的 application(),传递 environ_m 和 start_response_m。
  5. Application 的 application() 处理完成后,调用 start_response_m 并且返回结果给 Middleware。Middleware 将结果存放在 result_m 中。
  6. Middleware 处理 result_m,然后生成 result_s,接着调用 start_response_s 返回结果 result_s 给 Server。
  7. Server 获取到 result_s 后封装 HTTP Response 返回给 Client。

这里写图片描述

WSGI Web 开发框架

Paste + PasteDeploy + Routes + WebOb 是一个常见的 WSGI Web 开发框架。

  • Paste:是一个 WSGI 工具库,用于处理 Python WSGI Application 和 WSGI Server 之间的通信标准,同时提供了许多 WSGI Middleware 组件,用于处理 Request 和 Response,包括:会话管理,身份验证等等。满足 WSGI 规范的解耦架构设计。

  • PasteDeploy:是 Paste 的一个用于加载 WSGI Application 到 WSGI Server 的插件模块,支持通过 api-paste.ini 配置文件的方式和机制来定义与管理 WSGI Middleware 和 WSGI Application 在 Web Server 上的部署形态。通过 api-paste.ini 配置文件,开发者可以通过可插拔的方式来组装一个 Web Application。

  • Routes:是一个基于 URL 的 HTTP Request 路由分发库,用于将不同的 HTTP URLs/Methods(API Resources)与 API Controllers/Functions(资源表现层状态转移控制器)映射起来,实现将 HTTP Request 转发到对应的 Functions 进行处理并返回。

  • WebOb:是一个将 HTTP 协议中的 Request 和 Response 标准进行 Python Object 封装的库。以 Python Object 的风格和形式提供了对 Request URL、Request Header、Request Body、Request Filter & Query Parameter 以及 Response Header、Response Status Codes、Response Message、Response Body 的操作方式。此外,WebOb 还提供了一些简便的方法来处理 Cookie、会话管理、文件上传等常见的 Web 功能。

Paste + PasteDeploy + Routes + WebOb 能够开发符合 WSGI 的 Web Application。但该框架的弊端是实现复杂,代码量大,所以在 OpenStack 中只有 Neutron 等几个初始项目在使用。后来的新项目都采用了更简单高效的 Pecan 框架。

OpenStack 中的应用案例

NOTE:下文中以早期的 neutron-icehouse-eol 版本的代码来进行说明,介绍 Neutron Server 启动 API Service(Web Application)的流程。

进程入口

# /Users/fanguiju/workspace/neutron-icehouse-eol/setup.cfg
[entry_points]
console_scripts =
......neutron-server = neutron.server:main# /Users/fanguiju/workspace/neutron-icehouse-eol/neutron/server/__init__.py# 实例化 API Serviceneutron_api = service.serve_wsgi(service.NeutronApiService)
......# 实例化 RPC Workerneutron_rpc = service.serve_rpc()

WSGI Application 加载

# /Users/fanguiju/workspace/neutron-icehouse-eol/neutron/common/config.py
def load_paste_app(app_name):"""Builds and returns a WSGI app from a paste config file.:param app_name: Name of the application to load:raises ConfigFilesNotFoundError when config file cannot be located:raises RuntimeError when application cannot be loaded from config file"""config_path = cfg.CONF.find_file(cfg.CONF.api_paste_config)......app = deploy.loadapp("config:%s" % config_path, name=app_name)

Paste/PasteDeploy

此时,PasteDeploy 通过 api-paste.ini 文件来配置 WSGI Middleware 和 WSGI Application 的组合。

Neutron 的 api-paste.ini 文件如下:

# /Users/fanguiju/workspace/neutron-icehouse-eol/etc/api-paste.ini[composite:neutron]
use = egg:Paste#urlmap
/: neutronversions
/v2.0: neutronapi_v2_0[composite:neutronapi_v2_0]
use = call:neutron.auth:pipeline_factory
noauth = request_id catch_errors extensions neutronapiapp_v2_0
keystone = request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0[filter:request_id]
paste.filter_factory = neutron.openstack.common.middleware.request_id:RequestIdMiddleware.factory[filter:catch_errors]
paste.filter_factory = neutron.openstack.common.middleware.catch_errors:CatchErrorsMiddleware.factory[filter:keystonecontext]
paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory[filter:extensions]
paste.filter_factory = neutron.api.extensions:plugin_aware_extension_middleware_factory[app:neutronversions]
paste.app_factory = neutron.api.versions:Versions.factory[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory

入口是 composite Section,用于将 HTTP Request URL 分发到指定的 Middleware 和 Application。

  • use:指定了根据 URL 分发 Request 的方式。
  • egg:Paste#urlmap:表示使用 paste/urlmap.py 模块来根据 URL 分发 Request。
  • /v2.0、/v3、/:作为传递给 urlmap_factory() 函数进行 Request 分发的实参。urlmap_factory() 返回下一个 composite Section 或 app Section。

这里以 /v2.0 为例,urlmap_factory() 返回了 neutronapi_v2_0 composite Section,它包含了一个 Middleware Pipeline。Pipeline 用于把一系列 Middleware 和最终的 Application 串联起来,并遵守以下 2 点要求:

  1. 最后一个名字对应的 Section,一定要是一个 app 类型的。
  2. 非最后一个名字对应的 Sections,一定要是一个 filter 类型的。

在 filter 和 app Section 中定义了 paste.filter_factory 实际的入口函数。

Routes

Routes 的常规用法是首先构建一个 Mapper 实例对象,然后调用 Mapper 对象的 connect() 或 collection() 方法把相应的 URL、HTTP Method 映射到一个 Controller 的某个 Action 上。

Controller 是一个自定义的类实例,每一种 API Resource 都实现了一个 Controller,内含了多个与 HTTP Methods 对应的 Actions 成员方法,例如:list、show、create、update、delete 等。

通过 Paste/PasteDeploy 的配置处理之后进入到 neutronapiapp_v2_0 Application 的 factory() 函数,Paste 最终会调用它。在 APIRouter 类的实例化过程中会完成 Routes Mapper 的映射工作。

class APIRouter(wsgi.Router):@classmethoddef factory(cls, global_config, **local_config):return cls(**local_config)def __init__(self, **local_config):mapper = routes_mapper.Mapper()plugin = manager.NeutronManager.get_plugin()  # Core Pluginext_mgr = extensions.PluginAwareExtensionManager.get_instance()  # Service Pluginsext_mgr.extend_resources("2.0", attributes.RESOURCE_ATTRIBUTE_MAP)col_kwargs = dict(collection_actions=COLLECTION_ACTIONS,  # 集合操作类型:index、createmember_actions=MEMBER_ACTIONS)  # 成员操作类型:show、update、deletedef _map_resource(collection, resource, params, parent=None):allow_bulk = cfg.CONF.allow_bulkallow_pagination = cfg.CONF.allow_paginationallow_sorting = cfg.CONF.allow_sortingcontroller = base.create_resource(collection, resource, plugin, params, allow_bulk=allow_bulk,parent=parent, allow_pagination=allow_pagination,allow_sorting=allow_sorting)path_prefix = Noneif parent:path_prefix = "/%s/{%s_id}/%s" % (parent['collection_name'],parent['member_name'],collection)mapper_kwargs = dict(controller=controller,requirements=REQUIREMENTS,path_prefix=path_prefix,**col_kwargs)return mapper.collection(collection, resource,**mapper_kwargs)# 顶级资源mapper.connect('index', '/', controller=Index(RESOURCES))for resource in RESOURCES:_map_resource(RESOURCES[resource], resource,attributes.RESOURCE_ATTRIBUTE_MAP.get(RESOURCES[resource], dict()))for resource in SUB_RESOURCES:_map_resource(SUB_RESOURCES[resource]['collection_name'], resource,attributes.RESOURCE_ATTRIBUTE_MAP.get(SUB_RESOURCES[resource]['collection_name'],dict()),SUB_RESOURCES[resource]['parent'])# Certain policy checks require that the extensions are loaded# and the RESOURCE_ATTRIBUTE_MAP populated before they can be# properly initialized. This can only be claimed with certainty# once this point in the code has been reached. In the event# that the policies have been initialized before this point,# calling reset will cause the next policy check to# re-initialize with all of the required data in place.policy.reset()super(APIRouter, self).__init__(mapper)

WebOb

WebOb 有 3 个重要的对象:

  1. webob.Request:对 HTTP Request 中的 environ 参数进行封装。
  2. webob.Response:对 HTTP Response 的所有元素进行封装。
  3. webob.exc:对 HTTP Error Code 和 Msg 进行封装。

此外,WebOb 还提供了一个 webob.dec.wsgify 装饰器,以便我们可以不使用原始的 WSGI 参数传递和返回格式,而全部使用 WebOb 替代。

@wsgify
def myfunc(req):return webob.Response('Hey!')

WSGI 原始调用方式

app_iter = myfunc(environ, start_response)

WebOb 调用方式

resp = myfunc(req)

WSGI Server 启动

# /Users/fanguiju/workspace/neutron-icehouse-eol/neutron/service.pydef _run_wsgi(app_name):......server = wsgi.Server("Neutron")server.start(app, cfg.CONF.bind_port, cfg.CONF.bind_host,workers=cfg.CONF.api_workers)

相关文章:

Python WSGI 与 Web 开发框架

目录 文章目录 目录WSGIWSGI 的工作原理environ 参数start_resposne 参数 WSGI 的中间件 WSGI Web 开发框架OpenStack 中的应用案例进程入口WSGI Application 加载Paste/PasteDeployRoutesWebOb WSGI Server 启动 WSGI WSGI(Web Server Gateway Interface&#xff…...

[洛谷]P6464 [传智杯 #2 决赛] 传送门

看到数据范围&#xff1a;n<100&#xff0c;嗯......脑子闪过&#xff1a;还在想什么呢&#xff01;Floyd啊。哈哈哈 思路&#xff1a; 详细注释&#xff1a; 话不多说&#xff0c;上ACcode&#xff01;: #include<bits/stdc.h> using namespace std; #define int lo…...

Http协议和RestTemplate协议有什么区别?

目录 一、功能不同 二、技术不同 三、使用场景不同 四、总结 RestTemplate 是一个 Spring 框架提供的用于发送 HTTP请求的客户端工具&#xff0c;它封装了 Java 原生的 HTTP 客户端库&#xff0c;并提供了一组简洁易用的 API 来发送 HTTP 请求和处理响应。而 HTTP&#xff…...

基于SpringBoot+微信小程序的医院预约叫号小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 该项目是基于uniappWe…...

springboot整合RabbitMQ 消费端处理数据

pom 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>写一个rabbitmq配置文件 import org.springframework.amqp.core.Binding; import org.springframewo…...

计算机中CPU、内存、缓存的关系

CPU&#xff08;Central Processing Unit&#xff0c;中央处理器&#xff09; 内存&#xff08;Random Access Memory&#xff0c;随机存取存储器&#xff09; 缓存&#xff08;Cache&#xff09; CPU、内存和缓存之间有着密切的关系&#xff0c;它们共同构成了计算机系统的核…...

【Linux实验】构造一个简单的 shell

一、实验目的 l 用 C/C++构造一个简单的 shell; l 理解 shell 程序的功能; l 学会 shell 的使用;...

【电路原理学习笔记】第2章:电压、电流和电阻:2.6 电路

第2章&#xff1a;电压、电流和电阻 2.6 电路 2.6.1 电流的方向 电流方向有两种说法&#xff0c;一种按电子流动方向&#xff0c;另一种是传统的认为从正极流出到负极&#xff0c;这本教材采用传统电流方法。&#xff08;事传统派&#xff0c;维新派输了&#xff0c;1&#…...

基于深度学习的人脸检测技术

用到环境 1、pycharm community edition 2022.3.2 2、Python 3.10 整篇内容都已上传至我的csdn资源中&#xff0c;想用的请移步。 流程 多任务级联卷积神经网络(Multi-task Cascaded Convolutional Networks, MTCNN)算法进行人脸检测 普通人脸检测 单人人脸检测 图1 单人人…...

【linux kernel】一文总结linux内核通知链

文章目录 1、通知链简介2、通知链的类型3、原理分析和API&#xff08;1&#xff09;注销通知器&#xff08;2&#xff09;注销通知器&#xff08;3&#xff09;通知链的通知 4、实例代码&#xff08;1&#xff09;定义一个通知链&#xff08;2&#xff09;实现观察者模块&#…...

kafka入门,Kafka 副本(十三)

Kafka副本 副本基本信息 1&#xff09;Kafka副本作用&#xff0c;提高数据可靠性 2&#xff09;Kafka默认副本1个&#xff0c;生产环境一般配置2个&#xff0c;保证数据可靠性&#xff0c;太多副本会增加磁盘存储空间&#xff0c;增加网络上数据传输&#xff0c;降低效率 3&a…...

利用PPT制作简单的矢量图

1.用PPT画一个图形&#xff08;可以多个图&#xff09; 2.鼠标圈住图形 3.利用 Ctrl G 组合图形&#xff0c;再用 Ctrl C 复制 4.打开word—粘贴—选择性粘贴—图片&#xff08;增强性图元文件&#xff09; 确认即可。...

18-Linux 常用命令

目录 1.ls PS&#xff1a;FinalShell设置背景和字体 2.pwd 3.cd PS&#xff1a;认识 Linux 目录结构——Linux 是一个树形目录结构 PS&#xff1a;绝对路径 vs 相对路径 PS&#xff1a;使用 tab 键补全 PS&#xff1a;使用 ctrl c 重新输入 4.touch PS&#xff1a;L…...

2024考研408-计算机组成原理第六章-总线学习笔记

文章目录 前言初识总线一、总线概述1.1、总线的概述1.1.1、认识总线1.1.2、设计总线需要的特性1.1.3、总线的分类①按照数据传输格式分&#xff08;串行、并行&#xff09;②按照总线功能连接的总线&#xff08;片内总线、系统总线、通信总线&#xff09;③按照时序控制方式&am…...

uni_app 微信小程序 苹果手机 边框显示不全

![在这里插入图片描述](https://img-blog.csdnimg.cn/3a4c4ab1a146444c84c72d360a057c01.png 解决方案&#xff1a; 原因&#xff1a;是因为我们在设置边框的时候设置的rpx &#xff0c;自适应会自动换算px, 两者之间的比例一般都是1.5-2之间&#xff0c;对于边框 border 来说…...

vue 访问第三方 跨域, 配置vue.config.js

目录 0 config 文件被修改 一个要重启vscode 配置文件才会生效 1 第一种 (有两种写法) 1.1 配置vue.config.js 1.2 axios 使用 1.3 终端打印 2 第二种方法 --> 错误 --> 没有运行成功 2.1 配置vue.config.js --> 就是api 不被设置成 替换为 / 2.2 axios 使用…...

使用gradio库的File模块实现文件上传和展示

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…...

网络安全进阶学习第四课——SSRF服务器请求伪造

文章目录 一、什么是SSRF&#xff1f;二、SSRF成因三、SSRF简析四、PHP存在SSRF的风险函数五、后台源码获取方式六、SSRF危害七、SSRF漏洞挖掘从WEB功能上寻找&#xff0c;从URL关键字中寻找 八、SSRF具体利用ssrf常利用的相关协议PHP伪协议读取文件端口扫描 九、SSRF存在的必要…...

js处理扁平数组和树结构相互转换

一、将扁平的数据转为树形结构 在 js中&#xff0c;可以使用递归算法将扁平的数据转换为树形结构。 扁平数据通常是一个带有 parentId 属性的数组&#xff0c;而树形结构通常是一个带有 children 属性的对象。 1、方法一 下面是一个简单的例子&#xff0c;演示如何将扁平数…...

Spark弹性分布式数据集

1. Spark RDD是什么 RDD&#xff08;Resilient Distributed Dataset&#xff0c;弹性分布式数据集&#xff09;是一个不可变的分布式对象集合&#xff0c;是Spark中最基本的数据抽象。在代码中RDD是一个抽象类&#xff0c;代表一个弹性的、不可变、可分区、里面的元素可并行计…...

ffmpeg学习记录

1、对图片进行裁剪 ffmpeg -i input.jpg -vf cropiw/3:ih:20:0 caijian.jpg PS&#xff1a; crop100:100:12:34 相同效果: cropw100:h100:x12:y34 2、视频增加文字水印 使用drawtext滤镜进行增加水印 参数 类型 说明 text 字符串 文字 textfile 字符串 文字文件 …...

ChatGPT:为教育创新提供五大机遇

随着智能技术的不断发展&#xff0c;ChatGPT在教育场景中的创新价值可能比我们能够意识到的还要多。比如它可以自动处理作业、在线答疑&#xff0c;可以辅助语言学习、实时沟通&#xff0c;甚至还可以用于评估诊断、科学研究。国内外关于利用ChatGPT实现教育创新的场景描绘已经…...

Educational Codeforces Round 151 (Rated for Div. 2)

Edu 151 A. Forbidden Integer 题意&#xff1a; 你有[1, k]内除了 x x x的整数&#xff0c;每个数可以拿多次&#xff0c;问 ∑ n \sum n ∑n是否可行并构造 思路&#xff1a; 有1必能构造&#xff0c;否则假如没有1&#xff0c;假如有2, 3必定能构造出大于等于2的所有数&…...

【AI机器学习入门与实战】机器学习算法都有哪些分类?

&#x1f44d;【AI机器学习入门与实战】目录 &#x1f36d;基础篇 &#x1f525; 第一篇&#xff1a;【AI机器学习入门与实战】AI 人工智能介绍 &#x1f525; 第二篇&#xff1a;【AI机器学习入门与实战】机器学习核心概念理解 &#x1f525; 第三篇&#xff1a;【AI机器学习入…...

React之hooks

Hooks函数 1.useState()&#xff1a;状态钩子。纯函数组件没有状态&#xff0c;用于为函数组件引入state状态, 并进行状态数据的读写操作。 const [state, setState] useState(initialValue); // state&#xff1a;初始的状态属性&#xff0c;指向状态当前值&#xff0c;类似…...

1.监控分布式--zabbix

文章目录 监控分布式-zabbix、prometheus概念工作原理功能组件部署zabbix安装Nginx和PHP环境部署数据库编码安装zabbix编译安装zabbix server客户端安装zabbix agent服务 监控分布式-zabbix、prometheus 利用一个优秀的监控软件&#xff0c;我们可以: 通过一个友好的界面进行…...

java stream 多个集合去重取交集

文章目录 背景案例代码 背景 原因是需要从表里查多个集合list&#xff0c;然后取多个集合得交集&#xff0c;并且元素是对象&#xff0c;所以使用了下面的方式&#xff0c;当然方式有很多种&#xff0c;仅供参考。 案例 下面提供了一段多个集合join取交集的例子&#xff0c;…...

给LLM装上知识:从LangChain+LLM的本地知识库问答到LLM与知识图谱的结合

第一部分 什么是LangChain&#xff1a;连接本地知识库与LLM的桥梁 作为一个 LLM 应用框架&#xff0c;LangChain 支持调用多种不同模型&#xff0c;提供相对统一、便捷的操作接口&#xff0c;让模型即插即用&#xff0c;这是其GitHub地址&#xff0c;其架构如下图所示 (点此查…...

视频与AI,与进程交互(二) pytorch 极简训练自己的数据集并识别

目标学习任务 检测出已经分割出的图像的分类 2 使用pytorch pytorch 非常简单就可以做到训练和加载 2.1 准备数据 如上图所示&#xff0c;用来训练的文件放在了train中&#xff0c;验证的文件放在val中&#xff0c;train.txt 和 val.txt 分别放文件名称和分类类别&#xff…...

LLM - 第2版 ChatGLM2-6B (General Language Model) 的工程配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131445696 ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优…...