diff --git a/content/backend/1.md b/content/backend/1.md new file mode 100644 index 0000000..7e66483 --- /dev/null +++ b/content/backend/1.md @@ -0,0 +1,6 @@ +--- +title: "后端开发" +date: 2024-11-01 +draft: false +--- +## hduyw \ No newline at end of file diff --git a/content/backend/FastAPI/2.png b/content/backend/FastAPI/2.png new file mode 100644 index 0000000..9d5ae51 Binary files /dev/null and b/content/backend/FastAPI/2.png differ diff --git a/content/backend/FastAPI/3.png b/content/backend/FastAPI/3.png new file mode 100644 index 0000000..019cd99 Binary files /dev/null and b/content/backend/FastAPI/3.png differ diff --git a/content/backend/FastAPI/Cookie.md b/content/backend/FastAPI/Cookie.md new file mode 100644 index 0000000..cd5030f --- /dev/null +++ b/content/backend/FastAPI/Cookie.md @@ -0,0 +1,42 @@ +# Cookie参数 +```python +from typing import Annotated +from fastapi import Cookie,FastAPI +app=FastAPI() +@app.get("/item/") +async def read_items(ads_id:Annotated[str|None,Cookie()]=None): + return {"ads_id":ads_id} +``` +声明Cookie参数 + +>async def read_items(ads_id:Annotated[str|None,Cookie()]=None): + +## 参数模型 +Cookie 的特性是 “浏览器自动携带、存储在本地”,数据存储在用户的浏览器里面,不能随意更改 + +```python +from typing import Annotated, Union + +from fastapi import Cookie, FastAPI +from pydantic import BaseModel + +app = FastAPI() + + +class Cookies(BaseModel): + model_config = {"extra": "forbid"} + + session_id: str + fatebook_tracker: Union[str, None] = None + googall_tracker: Union[str, None] = None + + +@app.get("/items/") +async def read_items(cookies: Annotated[Cookies, Cookie()]): + return cookies +``` +这里的 + +>model_config = {"extra": "forbid"} + +意思就是只接受指定的Cookie \ No newline at end of file diff --git a/content/backend/FastAPI/Header.md b/content/backend/FastAPI/Header.md new file mode 100644 index 0000000..4302162 --- /dev/null +++ b/content/backend/FastAPI/Header.md @@ -0,0 +1,53 @@ +# Header参数 +```python +from typing import Annotated, Union + +from fastapi import FastAPI, Header + +app = FastAPI() + + +@app.get("/items/") +async def read_items(user_agent: Annotated[Union[str, None], Header()] = None): + return {"User-Agent": user_agent} +``` +支持自动转换(大部分标准请求头用连字符分隔,即减号(-)。 + +但是 user-agent 这样的变量在 Python 中是无效的。) + +支持接收重复请求头 +```python +from typing import Annotated + +from fastapi import FastAPI, Header + +app = FastAPI() + + +@app.get("/items/") +async def read_items(x_token: Annotated[list[str] | None, Header()] = None): + return {"X-Token values": x_token} +``` +## Header参数模型 +```python +from typing import Annotated + +from fastapi import FastAPI, Header +from pydantic import BaseModel + +app = FastAPI() + + +class CommonHeaders(BaseModel): + host: str + save_data: bool + if_modified_since: str | None = None + traceparent: str | None = None + x_tag: list[str] = [] + + +@app.get("/items/") +async def read_items(headers: Annotated[CommonHeaders, Header()]): + return headers +``` +同样,与Cookie参数一样,禁止额外的Headers diff --git a/content/backend/FastAPI/basic_knowledge.md b/content/backend/FastAPI/basic_knowledge.md new file mode 100644 index 0000000..5206270 --- /dev/null +++ b/content/backend/FastAPI/basic_knowledge.md @@ -0,0 +1,126 @@ +# Internet网络知识 +## 互联网是如何工作的 +1.互联网的本质与历史 + +本质:连接全球设备的巨型网络基础设施,核心作用是实现设备间稳定通信。 + +历史:起源于 1960 年代美国军方研究项目,1980 年代发展为公共基础设施,核心工作逻辑未变。 + +2.网络搭建的核心逻辑与设备 + +简单网络:两台设备可直接连接,多设备需通过 “路由器” 集中转发信息,减少连接复杂度。 + +规模化扩展:路由器之间可互相连接,实现网络范围无限扩大。 + +跨网络连接:通过 “调制解调器” 转换信号,借助电话 / 网线等现有基础设施,再通过 “ISP(互联网服务提供商)” 连接全球网络。 + +3.电脑的 “地址系统” + +IP 地址:设备的唯一标识,由四段数字组成(如 192.0.2.172),供设备之间识别。 + +域名:IP 地址的可读别名(如google.com),解决人类记不住数字地址的问题。 + +4.互联网与 Web 的区别 + +互联网:底层基础设施,负责连接设备。 + +Web:建立在互联网上的服务,通过浏览器访问(如网站),此外邮箱、IRC 等也是互联网上的独立服务。 + +5.内联网与外联网的特点 +内联网:组织专用的封闭网络,仅内部成员可访问,用于共享资源、协作。 + +外联网:开放部分权限给外部合作方的专用网络,用于安全共享信息、协作。 + +共性:均基于互联网基础设施和协议,授权成员可异地访问。 +## 什么是互联网 +互联网没有控制中心。相反,它是一种分布式网络系统;也就是说,它不依赖于任何单独的计算机。任何计算机或硬件只要能以正确方式(例如,使用正确的网络协议)发送和接收数据,都可成为互联网的一部分。 +## HTTP概述 +### 系统组成: + +1.客户端(用户代理): +请求方 + +2.服务器:可以提供客户端想要的东西的独家或者服务器集群 + +3.代理:作用再客户端和服务器中间,例如:缓存,过滤,负载均衡 +### 基本性质 +1.简约好懂 + +2.可扩展 + +3.无状态,但有记忆效应 + +4.依赖TCP链接:要穿数据,首先需要建立TCP连接,再发出HTTP请求 +### HTTP报文 +#### 请求报文 +1.动作(操作,例如POST,GET) +2.请求内容 +3.协议版本 +4.额外要求 +5.附加信息 +#### 响应报文 +1.协议版本 +2.状态码 +3.状态说明 +4.备注 +5.实际资源 +## 浏览器工作原理 +导致Web性能的最大两个原因:1.网络延迟,2.浏览器的单线程执行 + +### DNS查询(第一次查询) + +根据个人理解相当于在我们每次从电脑上输入网址去访问某个网站时,不能直接发HTTP请求,必须要把域名对应到ip地址才可以,dns服务器就是做将域名与ip地址匹配的工作的 + +### TCP握手 + +三次握手:让两端changshijinxingtongxin + +### TLS协商 +安全输出,互联网加密 + +对称加密:就类似于有一把钥匙可以打开和关闭房子,高效,但是安全性不够强,因为这把钥匙一旦被偷,整个家就不保了 + +非对称加密:公钥和私钥,公钥公开,大家可以来加密信息,但私钥只有一把在自己手上,用来打开家门查询数据,速度慢但安全 + +TLS结合了对称与非对称加密,传输通道采用非对称加密 ,数据加密采用对称机密 +### 构建dom树 +DOM 树描述了文档的内容。 元素是第一个标签也是文档树的根节点。树反映了不同标记之间的关系和层次结构。嵌套在其他标记中的标记是子节点。DOM 节点的数量越多,构建 DOM 树所需的时间就越长。 +### 预加载 +提前缓存资源 +### 构建CSSOM树 +类似于dom树,针对css文件 + +## URL +http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2#SomewhereInTheDocument + +方案 + +>http + +表示浏览器必须使用的协议来请求资源(协议是计算机网络中交换或传输数据的一组方法) + +权威 + +>www.example.com:80 + +包括域(www.example.com)和端口(80) + +如果 Web 服务器使用 HTTP 协议的标准端口(HTTP 为 80,HTTPS 为 443)来授予对其资源的访问权限,则通常会省略端口。否则,端口是强制的。 + +路径 + +>/path/to/myfile.html + +资源路径 + +参数 + +>?key1=value&key2=value2 + +每个 Web 服务器都有自己关于参数的规则,唯一可靠的方式来知道特定 Web 服务器是否处理参数是通过询问 Web 服务器所有者。 + +## 域名 +包括顶级域名和标签 + + + diff --git a/content/backend/FastAPI/class.md b/content/backend/FastAPI/class.md new file mode 100644 index 0000000..6e6845f --- /dev/null +++ b/content/backend/FastAPI/class.md @@ -0,0 +1,84 @@ +# 面向对象 +```python +class Student(object): + def __init__(self, name, score): + self.name = name + self.score = score + + def print_score(self): + print('%s: %s' % (self.name, self.score)) +``` +若想将这里代码中的name,score变成private,只需在其名称前加两个下划线 +```python +class Student(object): + def __init__(self, name, score): + self.__name = name + self.__score = score + + def print_score(self): + print('%s: %s' % (self.__name, self.__score)) +``` +在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。 +```python +>>> bart = Student('Bart Simpson', 59) +>>> bart.get_name() +'Bart Simpson' +>>> bart.__name = 'New Name' # 设置__name变量! +>>> bart.__name +'New Name' +``` +表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。 +# 继承和多态(类比c++) +```python +class Animal(object): + def run(self): + print('Animal is running...') +class Dog(Animal): + pass + +class Cat(Animal): + pass +dog = Dog() +dog.run() + +cat = Cat() +cat.run() +``` +>Animal is running... +> +>Animal is running... + +以上为继承,即子类可以继承父类的方法deng +```python +class Dog(Animal): + def run(self): + print('Dog is running...') + + def eat(self): + print('Eating meat...') +``` +>Dog is running... +> +>Cat is running... + +当子类中的一些方法与父类重名,则会覆盖父类原来的方法,此为多态 + +有些需要注意的点是: +__xxx__的属性和方法在python帐都是有特殊用途的,比如__len__方法是返回长度 +```python +>>>len('abc') +3 +>>>'abc'.__len__() +3 +``` +如果自己创建的类,也想用len,需要自己写一个__len__()方法 + +hasattr(obj,'x')#判断obj对象中是否有x对象 + +setattr(obj,'y',19)#对obj对象设置一个新的属性,设初值为19 + +getattr(obj,'y')#获取属性‘y' + +getattr(obj,'z',404)#获取属性'z',如果不存在,返回默认值404 + +isinstance(h,husky)判断h是否是husky类 diff --git a/content/backend/FastAPI/image-1.png b/content/backend/FastAPI/image-1.png new file mode 100644 index 0000000..7736888 Binary files /dev/null and b/content/backend/FastAPI/image-1.png differ diff --git a/content/backend/FastAPI/image-2.png b/content/backend/FastAPI/image-2.png new file mode 100644 index 0000000..756ba5b Binary files /dev/null and b/content/backend/FastAPI/image-2.png differ diff --git a/content/backend/FastAPI/image-3.png b/content/backend/FastAPI/image-3.png new file mode 100644 index 0000000..1fb338d Binary files /dev/null and b/content/backend/FastAPI/image-3.png differ diff --git a/content/backend/FastAPI/image-4.png b/content/backend/FastAPI/image-4.png new file mode 100644 index 0000000..b3f8e90 Binary files /dev/null and b/content/backend/FastAPI/image-4.png differ diff --git a/content/backend/FastAPI/image-5.png b/content/backend/FastAPI/image-5.png new file mode 100644 index 0000000..d16101c Binary files /dev/null and b/content/backend/FastAPI/image-5.png differ diff --git a/content/backend/FastAPI/image-6.png b/content/backend/FastAPI/image-6.png new file mode 100644 index 0000000..78441a2 Binary files /dev/null and b/content/backend/FastAPI/image-6.png differ diff --git a/content/backend/FastAPI/image.png b/content/backend/FastAPI/image.png new file mode 100644 index 0000000..7736888 Binary files /dev/null and b/content/backend/FastAPI/image.png differ diff --git a/content/backend/FastAPI/path_params_numeric_validation.md b/content/backend/FastAPI/path_params_numeric_validation.md new file mode 100644 index 0000000..4ec31a8 --- /dev/null +++ b/content/backend/FastAPI/path_params_numeric_validation.md @@ -0,0 +1,38 @@ +# 路径参数和数值校验 +引入Path(由fastapi提供) +![alt text](image-6.png) +## 声明元数据 +>item_id: Annotated[int, Path(title="The ID of the item to get")], + +Annotated(typing提供):一个打包工具,把参数的数据类型和校验规则绑在一起,结构如下 + +Annotated[基础类型, 附加信息1, 附加信息2, ...] + +基础类型:数据类型 + +附加信息就是校验规则,注释等 + +## 按需对参数进行排序 + +如果将带有「默认值」的参数放在没有「默认值」的参数之前,Python 将会报错。 + +但是可以对其重新排序,并将不带默认值的值(查询参数 q)放到最前面。 + +对 FastAPI 来说这无关紧要。它将通过参数的名称、类型和默认值声明(Query、Path 等)来检测参数,而不在乎参数的顺序。 +## 数值校验 +ge:大于等于 + +gt:大于 + +lt:小于 + +le:小于等于 + +>async def read_items( +> +> item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str +> +>): + +加入附加条件ge=1,item_id必须为大于等于1的整数。(*ps:这里的路径参数本身就是必选参数,q因为没有默认值所以也为必选参数*) + diff --git a/content/backend/FastAPI/request_body_advanced_usage.md b/content/backend/FastAPI/request_body_advanced_usage.md new file mode 100644 index 0000000..38f8bc3 --- /dev/null +++ b/content/backend/FastAPI/request_body_advanced_usage.md @@ -0,0 +1,140 @@ +# 请求体的更高级用法 +## 多个参数 +### 混合使用path,query和请求体参数 +```python +from typing import Annotated, Union + +from fastapi import FastAPI, Path +from pydantic import BaseModel + +app = FastAPI() + + +class Item(BaseModel): + name: str + description: Union[str, None] = None + price: float + tax: Union[float, None] = None + + +@app.put("/items/{item_id}") +async def update_item( + item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)], + q: Union[str, None] = None, + item: Union[Item, None] = None, +): + results = {"item_id": item_id} + if q: + results.update({"q": q}) + if item: + results.update({"item": item}) + return results +``` +### 多个请求体参数 +```python +@app.put("/items/{item_id}") +async def update_item(item_id: int, item: Item, user: User): + results = {"item_id": item_id, "item": item, "user": user} + return results +``` + +### 请求体中的单一值 +有时想加入一个请求体,但是它是一个单一值,会被fastapi默认为查询参数,可以使用Body让fastapi把它看作为请求体 + +```python +@app.put("/items/{item_id}") +async def update_item( + item_id: int, item: Item, user: User, importance: Annotated[int, Body()] +): + results = {"item_id": item_id, "item": item, "user": user, "importance": importance} + return results +``` +在这种情况下,fastapi将期望像这样的请求体: +{ + "item": { + "name": "Foo", + "description": "The pretender", + "price": 42.0, + "tax": 3.2 + }, + "user": { + "username": "dave", + "full_name": "Dave Grohl" + }, + "importance": 5 +} +### 多个请求体参数和查询参数 + +由于默认情况下单一值被解释为查询参数,因此不必显式地添加 Query,你可以仅执行以下操作 + +>q: str = None + +### 嵌入单个请求体参数 +也就是将这种期望 +```json +{ + "name": "Foo", + "description": "The pretender", + "price": 42.0, + "tax": 3.2 +} +``` +转变成这种 +```json +{ + "item": { + "name": "Foo", + "description": "The pretender", + "price": 42.0, + "tax": 3.2 + } +} +``` + +也就是说多显示一个键,可以使用Body(embed=True) + +可以将代码中 + +>async def update_item(item_id: int, item: Item) + +转变为 + +>async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]) + +## 字段 +导入Field(Pydantic提供) +```python +from typing import Annotated, Union + +from fastapi import Body, FastAPI +from pydantic import BaseModel, Field + +app = FastAPI() + + +class Item(BaseModel): + name: str + description: Union[str, None] = Field( + default=None, title="The description of the item", max_length=300 + ) + price: float = Field(gt=0, description="The price must be greater than zero") + tax: Union[float, None] = None + + +@app.put("/items/{item_id}") +async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]): + results = {"item_id": item_id, "item": item} + return results +``` +与Query,Path,Body的工作方式相同,参数也相同,只不过Field作用在pydantic内部 + + + + + + + + + + + diff --git a/content/backend/FastAPI/requirement.md b/content/backend/FastAPI/requirement.md new file mode 100644 index 0000000..f7bf510 --- /dev/null +++ b/content/backend/FastAPI/requirement.md @@ -0,0 +1,62 @@ +--- +title: "后端开发" +date: 2024-11-01 +draft: false +--- + +# 请求体 +请求体是客户端发送给API的数据,响应体是API发送给客户提的数据。 +![alt text](image-5.png) + +## 导入Pydantic的BaseModel + +>from pydantic import BaseModel + +## 创建数据模型,把数据模型声明为BaseModel的类 + +>class Item(BaseModel): +> +>name:str +> +>description:str|None=None +> +>price:float +> +>tax:fioat|None=None + +这里的description和tax都含有默认值None,所以他俩是可选的 + +## 声明请求体参数 +>async def create_item(item: Item): + +## 请求体+路径参数 +>@app.put("/items/{item_id}") +> +>async def update_item(item_id: int, item: Item): +> +> return {"item_id": item_id, **item.dict()} + +*FastAPI 能识别与路径参数匹配的函数参数,还能识别从请求体中获取的类型为 Pydantic 模型的函数参数。* +## 请求体+路径参数+查询参数 +>@app.put("/items/{item_id}") +> +>async def update_item(item_id: int, item: Item, q: str | None = None): +> +> result = {"item_id": item_id, **item.dict()} +> +> if q: +> +> result.update({"q": q}) +> +> return result + +函数参数按如下规则进行识别: + +路径中声明了相同参数的参数,是路径参数 + +类型是(int、float、str、bool 等)单类型参数,是查询参数 + +类型是 Pydantic 模型的参数,是请求体 + +**这里+一点自己的小理解,请求体可以看作操作对象,路径参数就是告诉我们在哪里找到它,查询参数可以看作一些附加的操作,上面的代码可以理解为将item_id,请求体Item和q组合为一个新的字典** + diff --git a/content/backend/FastAPI/rout.md b/content/backend/FastAPI/rout.md new file mode 100644 index 0000000..6eea705 --- /dev/null +++ b/content/backend/FastAPI/rout.md @@ -0,0 +1,73 @@ +--- +title: "后端开发" +date: 2024-11-09 +draft: false +--- + +# Fast API +## 安装 +终端输入: +>pip install fastapi +> +>pip install "uvicorn[standard]" +## 创建main.py +![alt text](2.png) +运行(终端) +>uvicorn main:app --reload + +*注意* + +若出现无法解析FastAPI,请检查是否安装在指定的python版本上 + +运行后若终端出现error,请ctrl+s保存 + +继续加入新的指令,下列代码加入了一个put指令,对应的交互式API也会同步(#后为新加入的代码) +![alt text](3.png) + +### 创建FastAPI实例 +>app=FastAPI() + +### 操作 +POST:创建数据 + +GET:读取数据 + +PUT:更新数据 + +DELETE:删除数据 + +>@app.get("/") + +这行代码告诉api请求路径为/,操作为get,它的名字叫做装饰器,放在函数上方 + +>async def root() +> +>def root() + +带有async的为异步代码,提高效率,两个都是正确的函数代码 + +>return {"messadge":"Hello World"} + +return返回内容 +## 路径参数 +### 预设值 +![alt text](image-1.png) +简单来说,这里的enum就是给你了一个选项,你只能从我给你的选项里面选择,可以规避一些输入的错误 +### 路径转换器 +![alt text](image-2.png) +本例中,参数名为 file_path,结尾部分的 :path 说明该参数应匹配路径。可以把他当作万能地址匹配器 + +*比如* + +没有 :path 情况下 + +匹配:/files/hello.txt + +不匹配:/files/folder/hello.txt(因为中间有斜杠 /,即包含路径) + +但是如果有:path + +以上两种路径都可匹配 + + + diff --git a/content/backend/FastAPI/value.md b/content/backend/FastAPI/value.md new file mode 100644 index 0000000..feaa415 --- /dev/null +++ b/content/backend/FastAPI/value.md @@ -0,0 +1,80 @@ +--- +title: "后端开发" +date: 2024-11-11 +draft: false +--- + +# 查询参数 +![alt text](image-3.png) +## 默认值 +上例用 skip=0 和 limit=10 设定默认值,可以在URL中自己设定,也可以使用默认值 +## 可选参数 +同理,把默认值设为 None 即可声明可选的查询参数 +## 查询参数类型转换 +![alt text](image-4.png) +这里的short取的是bool类型,默认值为False + +在这里,访问http://127.0.0.1:8000/items/foo?short=1(True/true/yes)等各种类型,函数接受的short参数都是bool类型True。 + +## 多个路径和查询参数 +FastAPI 可以识别同时声明的多个路径参数和查询参数,通过参数名进行检测 +## 必选查询参数 +对于不是路径参数的参数: + +如果只想把参数设为可选,但又不想指定参数的值,则要把默认值设为 None。 + +如果要把查询参数设置为必选,就不要声明默认值 +>from fastapi import FastAPI +> +>app = FastAPI() +> +>@app.get("/items/{item_id}") +> +>async def read_user_item(item_id: str, needy: str): +> +> item = {"item_id": item_id, "needy": needy} +> +> return item + +这里的needy就是必选查询参数 + +因此,在浏览器中打开URL时,路径必须为http://127.0.0.1:8000/items/foo-item?needy=sooooneedy + + +## 查询参数和字符串校验 +引入Query(由fastapi提供) +>async def read_items(q: Union[List[str], None] = None): + +>async def read_items(q: Union[List[str], None] = Query(default=None, min_length=2, min_items=1)) + +Query()明确表明这个参数为查询参数,并且保证参数格式对,fastapi可自动校验,Union只能控制参数的类型及默认值,若想规定参数值就是None,是一个必须参数,可以如下: + +>async def read_items(q: Union[str, None] = Query(min_length=3)): + +因此,当你在使用 Query 且需要声明一个值是必需的时,只需不声明默认参数. +## 具有默认值的查询参数列表 +>async def read_items(q: List[str] = Query(default=["foo", "bar"])): + +这相当于让q为以["foo", "bar"]列表为默认参数 +## 别名参数 +加入想查询的参数并不是一个有效的python变量名称,此时可以用alias参数声明别名 + +>async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")): +## 弃用参数 +如果有些参数想弃用,可以在Query中加入deprecated=True + +**通用的校验和元数据: + +alias +title +description +deprecated +特定于字符串的校验: + +min_length +max_length +regex** + + + + diff --git "a/content/backend/FastAPI/\344\270\255\351\227\264\344\273\266.md" "b/content/backend/FastAPI/\344\270\255\351\227\264\344\273\266.md" new file mode 100644 index 0000000..4fe84f0 --- /dev/null +++ "b/content/backend/FastAPI/\344\270\255\351\227\264\344\273\266.md" @@ -0,0 +1,62 @@ +# 中间件 + +中间件是一个函数,他在每个请求被特定的路径操作处理之前,以及在每个响应之后工作 + +目的是简化,中间件包括请求和响应,请求和响应不一定都存在 + +设计中间件 + +```python +import uvicorn +from fastapi import FastAPI,Request + + +app=FastAPI() + +@app.middleware("http") +async def m2(request:Request,call_next): + #请求代码块 + print("m2 request") + reponse=await call_next(request) + + + #响应代码块 + print("m1 reponse") + return reponse + + + +@app.middleware("http") +async def m1(request:Request,call_next): + #请求代码块 + print("m1 request") + reponse=call_next(request) + + + #响应代码块 + print("m1 reponse") + return reponse + +#下面的先执行 + + + +@app.get("/user") +def get_user(): + return { + "user":"current user" + } + + +@app.get("/item/{item_id}") +def get_item(item_id:int): + return { + "item_id":item_id + } + + + +if __name__=='__main__': + uvicorn.run('main:app',host='127.0.0.1',port=8020,reload=Ture) + +``` \ No newline at end of file