mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-22 06:58:17 +01:00
bugfixing actor, sensor controller. New dashboard api
This commit is contained in:
parent
8ecedee363
commit
b1b9025886
4367 changed files with 1710789 additions and 143 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
BIN
cbpi/.DS_Store
vendored
Normal file
BIN
cbpi/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -141,6 +141,7 @@ def remove(package_name):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Welcome to CraftBeerPi 4')
|
parser = argparse.ArgumentParser(description='Welcome to CraftBeerPi 4')
|
||||||
parser.add_argument("action", type=str, help="start,stop,restart,setup,plugins")
|
parser.add_argument("action", type=str, help="start,stop,restart,setup,plugins")
|
||||||
parser.add_argument("--name", type=str, help="Plugin name")
|
parser.add_argument("--name", type=str, help="Plugin name")
|
||||||
|
|
|
@ -4,7 +4,7 @@ version: 4.0.1_alpha
|
||||||
|
|
||||||
#: /myext
|
#: /myext
|
||||||
|
|
||||||
port: 8080
|
port: 8000
|
||||||
|
|
||||||
username: cbpi
|
username: cbpi
|
||||||
password: 123
|
password: 123
|
||||||
|
|
|
@ -38,12 +38,12 @@ CREATE TABLE IF NOT EXISTS kettle
|
||||||
(
|
(
|
||||||
id INTEGER PRIMARY KEY NOT NULL,
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
name VARCHAR(80),
|
name VARCHAR(80),
|
||||||
sensor VARCHAR(80),
|
sensor INTEGER,
|
||||||
heater VARCHAR(10),
|
heater INTEGER,
|
||||||
automatic VARCHAR(255),
|
automatic VARCHAR(255),
|
||||||
logic VARCHAR(50),
|
logic VARCHAR(50),
|
||||||
config VARCHAR(1000),
|
config VARCHAR(1000),
|
||||||
agitator VARCHAR(10),
|
agitator INTEGER,
|
||||||
target_temp INTEGER,
|
target_temp INTEGER,
|
||||||
height INTEGER,
|
height INTEGER,
|
||||||
diameter INTEGER
|
diameter INTEGER
|
||||||
|
|
|
@ -40,17 +40,13 @@ class ActorController(CRUDController):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if actor.type in self.types:
|
if actor.type in self.types:
|
||||||
|
|
||||||
cfg = actor.config.copy()
|
cfg = actor.config.copy()
|
||||||
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
||||||
clazz = self.types[actor.type]["class"];
|
clazz = self.types[actor.type]["class"];
|
||||||
self.cache[actor.id].instance = clazz(**cfg)
|
self.cache[actor.id].instance = clazz(**cfg)
|
||||||
self.cache[actor.id].instance.init()
|
self.cache[actor.id].instance.init()
|
||||||
|
|
||||||
|
|
||||||
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
||||||
|
@ -149,12 +145,11 @@ class ActorController(CRUDController):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def _pre_delete_callback(self, actor_id):
|
async def _pre_delete_callback(self, actor_id):
|
||||||
|
if hasattr(self.cache[int(actor_id)], "instance") and self.cache[int(actor_id)].instance is not None:
|
||||||
if self.cache[int(actor_id)].instance is not None:
|
|
||||||
await self._stop_actor(self.cache[int(actor_id)])
|
await self._stop_actor(self.cache[int(actor_id)])
|
||||||
|
|
||||||
async def _pre_update_callback(self, actor):
|
async def _pre_update_callback(self, actor):
|
||||||
if actor.instance is not None:
|
if hasattr(actor, "instance") and actor.instance is not None:
|
||||||
await self._stop_actor(actor)
|
await self._stop_actor(actor)
|
||||||
|
|
||||||
async def _post_update_callback(self, actor):
|
async def _post_update_callback(self, actor):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
import json
|
||||||
from cbpi.controller.crud_controller import CRUDController
|
from cbpi.controller.crud_controller import CRUDController
|
||||||
from cbpi.database.model import DashboardModel, DashboardContentModel
|
from cbpi.database.model import DashboardModel, DashboardContentModel
|
||||||
|
|
||||||
|
@ -20,16 +20,20 @@ class DashboardController(CRUDController):
|
||||||
return dict(items=self.cache)
|
return dict(items=self.cache)
|
||||||
|
|
||||||
async def get_content(self, dashboard_id):
|
async def get_content(self, dashboard_id):
|
||||||
return await DashboardContentModel.get_by_dashboard_id(dashboard_id)
|
with open('./config/dashboard/cbpi_dashboard_%s.json' % dashboard_id) as json_file:
|
||||||
|
data = json.load(json_file)
|
||||||
|
return data
|
||||||
|
|
||||||
async def add_content(self, data):
|
async def add_content(self, dashboard_id, data):
|
||||||
return await DashboardContentModel.insert(**data)
|
with open('./config/dashboard/cbpi_dashboard_%s.json' % dashboard_id, 'w') as outfile:
|
||||||
|
json.dump(data, outfile, indent=4, sort_keys=True)
|
||||||
|
print(data)
|
||||||
|
return {"status": "OK"}
|
||||||
|
|
||||||
async def delete_content(self, content_id):
|
async def delete_content(self, content_id):
|
||||||
await DashboardContentModel.delete(content_id)
|
await DashboardContentModel.delete(content_id)
|
||||||
|
|
||||||
async def move_content(self,content_id, x, y):
|
|
||||||
await DashboardContentModel.update_coordinates(content_id, x, y)
|
|
||||||
|
|
||||||
async def delete_dashboard(self, dashboard_id):
|
async def delete_dashboard(self, dashboard_id):
|
||||||
await DashboardContentModel.delete_by_dashboard_id(dashboard_id)
|
await DashboardContentModel.delete_by_dashboard_id(dashboard_id)
|
||||||
|
|
|
@ -168,7 +168,6 @@ class KettleController(CRUDController):
|
||||||
raise SensorException("Sensor not defined for kettle id %s" % id)
|
raise SensorException("Sensor not defined for kettle id %s" % id)
|
||||||
|
|
||||||
sensor_id = kettle.sensor
|
sensor_id = kettle.sensor
|
||||||
|
|
||||||
return await self.cbpi.sensor.get_value(sensor_id)
|
return await self.cbpi.sensor.get_value(sensor_id)
|
||||||
|
|
||||||
@on_event(topic="kettle/+/targettemp")
|
@on_event(topic="kettle/+/targettemp")
|
||||||
|
|
|
@ -72,12 +72,12 @@ class SensorController(CRUDController):
|
||||||
async def _pre_delete_callback(self, sensor_id):
|
async def _pre_delete_callback(self, sensor_id):
|
||||||
if int(sensor_id) not in self.cache:
|
if int(sensor_id) not in self.cache:
|
||||||
return
|
return
|
||||||
if self.cache[int(sensor_id)].instance is not None:
|
if hasattr(self.cache[int(sensor_id)], "instance") and self.cache[int(sensor_id)].instance is not None:
|
||||||
await self.stop_sensor(self.cache[int(sensor_id)])
|
await self.stop_sensor(self.cache[int(sensor_id)])
|
||||||
|
|
||||||
async def _pre_update_callback(self, sensor):
|
async def _pre_update_callback(self, sensor):
|
||||||
|
|
||||||
if sensor.instance is not None:
|
if hasattr(sensor, "instance") and sensor.instance is not None:
|
||||||
await self.stop_sensor(sensor)
|
await self.stop_sensor(sensor)
|
||||||
|
|
||||||
async def _post_update_callback(self, sensor):
|
async def _post_update_callback(self, sensor):
|
||||||
|
|
|
@ -141,6 +141,7 @@ class CraftBeerPi():
|
||||||
self.register_on_startup(obj)
|
self.register_on_startup(obj)
|
||||||
|
|
||||||
def register_http_endpoints(self, obj, url_prefix=None, static=None):
|
def register_http_endpoints(self, obj, url_prefix=None, static=None):
|
||||||
|
|
||||||
|
|
||||||
if url_prefix is None:
|
if url_prefix is None:
|
||||||
logger.debug("URL Prefix is None for %s. No endpoints will be registered. Please set / explicit if you want to add it to the root path" % obj)
|
logger.debug("URL Prefix is None for %s. No endpoints will be registered. Please set / explicit if you want to add it to the root path" % obj)
|
||||||
|
@ -173,16 +174,16 @@ class CraftBeerPi():
|
||||||
}
|
}
|
||||||
switcher[http_method]()
|
switcher[http_method]()
|
||||||
|
|
||||||
|
print("URL PREFIX", url_prefix)
|
||||||
if url_prefix != "/":
|
if url_prefix != "/":
|
||||||
logger.debug("URL Prefix: %s " % (url_prefix,))
|
logger.debug("URL Prefix: %s " % (url_prefix,))
|
||||||
sub = web.Application()
|
sub = web.Application()
|
||||||
sub.add_routes(routes)
|
sub.add_routes(routes)
|
||||||
if static is not None:
|
if static is not None:
|
||||||
sub.add_routes([web.static('/static', static, show_index=False)])
|
sub.add_routes([web.static('/static', static, show_index=True)])
|
||||||
self.app.add_subapp(url_prefix, sub)
|
self.app.add_subapp(url_prefix, sub)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
self.app.add_routes(routes)
|
self.app.add_routes(routes)
|
||||||
|
|
||||||
def _swagger_setup(self):
|
def _swagger_setup(self):
|
||||||
|
@ -195,6 +196,7 @@ class CraftBeerPi():
|
||||||
This is the api for CraftBeerPi
|
This is the api for CraftBeerPi
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
print("SWAGGER.......")
|
||||||
setup_swagger(self.app,
|
setup_swagger(self.app,
|
||||||
description=long_description,
|
description=long_description,
|
||||||
title=self.static_config.get("name", "CraftBeerPi"),
|
title=self.static_config.get("name", "CraftBeerPi"),
|
||||||
|
@ -227,12 +229,14 @@ class CraftBeerPi():
|
||||||
def _setup_http_index(self):
|
def _setup_http_index(self):
|
||||||
async def http_index(request):
|
async def http_index(request):
|
||||||
url = self.config.static.get("index_url")
|
url = self.config.static.get("index_url")
|
||||||
|
|
||||||
if url is not None:
|
if url is not None:
|
||||||
|
|
||||||
raise web.HTTPFound(url)
|
raise web.HTTPFound(url)
|
||||||
else:
|
else:
|
||||||
return web.Response(text="Hello from CraftbeerPi!")
|
return web.Response(text="Hello from CraftbeerPi!")
|
||||||
|
|
||||||
|
|
||||||
self.app.add_routes([web.get('/', http_index), web.static('/static', os.path.join(os.path.dirname(__file__),"static"), show_index=True)])
|
self.app.add_routes([web.get('/', http_index), web.static('/static', os.path.join(os.path.dirname(__file__),"static"), show_index=True)])
|
||||||
|
|
||||||
async def init_serivces(self):
|
async def init_serivces(self):
|
||||||
|
@ -258,4 +262,4 @@ class CraftBeerPi():
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
web.run_app(self.init_serivces(), port=self.static_config.get("port", 8080))
|
web.run_app(self.init_serivces(), port=self.static_config.get("port", 2202))
|
||||||
|
|
|
@ -146,9 +146,9 @@ class DBModel(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def update(cls, **kwargs):
|
async def update(cls, **kwargs):
|
||||||
|
print("UPDATE")
|
||||||
async with aiosqlite.connect(DATABASE_FILE) as db:
|
async with aiosqlite.connect(DATABASE_FILE) as db:
|
||||||
query = 'UPDATE %s SET %s WHERE %s = ?' % (cls.__table_name__, ', '.join("'%s' = ?" % str(x) for x in cls.__fields__), cls.__priamry_key__)
|
query = 'UPDATE %s SET %s WHERE %s = ?' % (cls.__table_name__, ', '.join("'%s' = ?" % str(x) for x in cls.__fields__), cls.__priamry_key__)
|
||||||
|
|
||||||
data = ()
|
data = ()
|
||||||
for f in cls.__fields__:
|
for f in cls.__fields__:
|
||||||
if f in cls.__json_fields__:
|
if f in cls.__json_fields__:
|
||||||
|
@ -157,6 +157,7 @@ class DBModel(object):
|
||||||
data = data + (kwargs.get(f),)
|
data = data + (kwargs.get(f),)
|
||||||
|
|
||||||
data = data + (kwargs.get(cls.__priamry_key__),)
|
data = data + (kwargs.get(cls.__priamry_key__),)
|
||||||
|
print(query)
|
||||||
cursor = await db.execute(query, data)
|
cursor = await db.execute(query, data)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
return cls(kwargs)
|
return cls(kwargs)
|
||||||
|
|
|
@ -121,6 +121,8 @@ class ActorHttpEndpoints(HttpCrudEndpoints):
|
||||||
"200":
|
"200":
|
||||||
description: successful operation
|
description: successful operation
|
||||||
"""
|
"""
|
||||||
|
print(".........")
|
||||||
|
print(request)
|
||||||
return await super().http_update(request)
|
return await super().http_update(request)
|
||||||
|
|
||||||
@request_mapping(path="/{id}", method="DELETE", auth_required=False)
|
@request_mapping(path="/{id}", method="DELETE", auth_required=False)
|
||||||
|
|
|
@ -39,8 +39,6 @@ class HttpCrudEndpoints():
|
||||||
async def http_update(self, request):
|
async def http_update(self, request):
|
||||||
id = int(request.match_info['id'])
|
id = int(request.match_info['id'])
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
|
|
||||||
|
|
||||||
obj = await self.controller.update(id, data)
|
obj = await self.controller.update(id, data)
|
||||||
return web.json_response(obj, dumps=json_dumps)
|
return web.json_response(obj, dumps=json_dumps)
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,8 @@ class DashBoardHttpEndpoints(HttpCrudEndpoints):
|
||||||
description: successful operation
|
description: successful operation
|
||||||
"""
|
"""
|
||||||
dashboard_id = int(request.match_info['id'])
|
dashboard_id = int(request.match_info['id'])
|
||||||
|
|
||||||
|
|
||||||
return web.json_response(await self.cbpi.dashboard.get_content(dashboard_id), dumps=json_dumps)
|
return web.json_response(await self.cbpi.dashboard.get_content(dashboard_id), dumps=json_dumps)
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,100 +167,15 @@ class DashBoardHttpEndpoints(HttpCrudEndpoints):
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
element_id:
|
elements:
|
||||||
type: string
|
type: array
|
||||||
type:
|
pathes:
|
||||||
type: string
|
type: array
|
||||||
x:
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
y:
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
config:
|
|
||||||
type: object
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: successful operation
|
description: successful operation
|
||||||
"""
|
"""
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
|
dashboard_id = int(request.match_info['id'])
|
||||||
data["dbid"] = int(request.match_info['id'])
|
await self.cbpi.dashboard.add_content(dashboard_id, data)
|
||||||
return web.json_response(await self.cbpi.dashboard.add_content(data), dumps=json_dumps)
|
|
||||||
|
|
||||||
|
|
||||||
@request_mapping(path="/{id:\d+}/content/{content_id:\d+}", method="DELETE", auth_required=False)
|
|
||||||
async def delete_content(self, request):
|
|
||||||
"""
|
|
||||||
---
|
|
||||||
description: Delete Dashboard Content
|
|
||||||
tags:
|
|
||||||
- Dashboard
|
|
||||||
parameters:
|
|
||||||
- name: "id"
|
|
||||||
in: "path"
|
|
||||||
description: "Dashboard ID"
|
|
||||||
required: true
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
- name: "content_id"
|
|
||||||
in: "path"
|
|
||||||
description: "Dashboard Content ID"
|
|
||||||
required: true
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
responses:
|
|
||||||
"204":
|
|
||||||
description: successful operation
|
|
||||||
"""
|
|
||||||
content_id = int(request.match_info['content_id'])
|
|
||||||
|
|
||||||
await self.cbpi.dashboard.delete_content(content_id)
|
|
||||||
return web.Response(status=204)
|
return web.Response(status=204)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@request_mapping(path="/{id:\d+}/content/{content_id:\d+}/move", method="POST", auth_required=False)
|
|
||||||
async def move_content(self,request):
|
|
||||||
"""
|
|
||||||
---
|
|
||||||
description: Get Dashboard Content
|
|
||||||
tags:
|
|
||||||
- Dashboard
|
|
||||||
parameters:
|
|
||||||
- name: "id"
|
|
||||||
in: "path"
|
|
||||||
description: "Dashboard ID"
|
|
||||||
required: true
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
- name: "content_id"
|
|
||||||
in: "path"
|
|
||||||
description: "Content ID"
|
|
||||||
required: true
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
- name: body
|
|
||||||
in: body
|
|
||||||
description: Dashboard Content
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
x:
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
y:
|
|
||||||
type: "integer"
|
|
||||||
format: "int64"
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: successful operation
|
|
||||||
"""
|
|
||||||
data = await request.json()
|
|
||||||
schema = Schema({"id": int, "x": int, "y": int})
|
|
||||||
schema(data)
|
|
||||||
content_id = int(request.match_info['content_id'])
|
|
||||||
|
|
||||||
return web.json_response(await self.cbpi.dashboard.move_content(content_id,data["x"], data["y"]), dumps=json_dumps)
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from cbpi.api import *
|
from cbpi.api import *
|
||||||
|
|
||||||
|
|
||||||
from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
|
from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
|
||||||
auth = False
|
auth = False
|
||||||
|
|
||||||
|
|
||||||
class KettleHttpEndpoints(HttpCrudEndpoints):
|
class KettleHttpEndpoints(HttpCrudEndpoints):
|
||||||
|
|
||||||
@request_mapping(path="/types", auth_required=False)
|
@request_mapping(path="/types", auth_required=False)
|
||||||
async def get_types(self, request):
|
async def get_types(self, request):
|
||||||
return await super().get_types(request)
|
return await super().get_types(request)
|
||||||
|
@ -153,6 +153,7 @@ class KettleHttpEndpoints(HttpCrudEndpoints):
|
||||||
self.controller = cbpi.kettle
|
self.controller = cbpi.kettle
|
||||||
self.cbpi.register(self, "/kettle")
|
self.cbpi.register(self, "/kettle")
|
||||||
|
|
||||||
|
|
||||||
@request_mapping(path="/{id:\d+}/automatic", method="POST", auth_required=False)
|
@request_mapping(path="/{id:\d+}/automatic", method="POST", auth_required=False)
|
||||||
async def http_automatic(self, request):
|
async def http_automatic(self, request):
|
||||||
"""
|
"""
|
||||||
|
@ -325,4 +326,3 @@ class KettleHttpEndpoints(HttpCrudEndpoints):
|
||||||
temp = await self.controller.get_temp(kettle_id)
|
temp = await self.controller.get_temp(kettle_id)
|
||||||
|
|
||||||
return web.Response(status=204)
|
return web.Response(status=204)
|
||||||
|
|
||||||
|
|
13
cbpi/sample.py
Normal file
13
cbpi/sample.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
async def handle(request):
|
||||||
|
name = request.match_info.get('name', "Anonymous")
|
||||||
|
text = "Hello, " + name
|
||||||
|
return web.Response(text=text)
|
||||||
|
|
||||||
|
app = web.Application()
|
||||||
|
app.add_routes([web.get('/', handle),
|
||||||
|
web.get('/{name}', handle)])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
web.run_app(app, port="8000")
|
|
@ -36,17 +36,26 @@ class CBPiWebSocket:
|
||||||
self.cbpi.app.loop.create_task(send_data(ws, data))
|
self.cbpi.app.loop.create_task(send_data(ws, data))
|
||||||
|
|
||||||
async def websocket_handler(self, request):
|
async def websocket_handler(self, request):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ws = web.WebSocketResponse()
|
ws = web.WebSocketResponse()
|
||||||
await ws.prepare(request)
|
await ws.prepare(request)
|
||||||
|
print(ws)
|
||||||
self._clients.add(ws)
|
self._clients.add(ws)
|
||||||
peername = request.transport.get_extra_info('peername')
|
try:
|
||||||
if peername is not None:
|
peername = request.transport.get_extra_info('peername')
|
||||||
host, port = peername
|
if peername is not None:
|
||||||
else:
|
print(peername)
|
||||||
host, port = "Unknowen"
|
host = peername[0]
|
||||||
|
port = peername[1]
|
||||||
self.logger.info("Client Connected - Host: %s Port: %s - client count: %s " % (host, port, len(self._clients)))
|
else:
|
||||||
|
host, port = "Unknowen"
|
||||||
|
self.logger.info("Client Connected - Host: %s Port: %s - client count: %s " % (host, port, len(self._clients)))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await ws.send_json(data=dict(topic="connection/success"))
|
await ws.send_json(data=dict(topic="connection/success"))
|
||||||
async for msg in ws:
|
async for msg in ws:
|
||||||
|
@ -76,4 +85,5 @@ class CBPiWebSocket:
|
||||||
|
|
||||||
self.logger.info("Web Socket Close")
|
self.logger.info("Web Socket Close")
|
||||||
|
|
||||||
return ws
|
return ws
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name: CraftBeerPi
|
name: CraftBeerPi
|
||||||
version: 4.0
|
version: 4.0
|
||||||
|
|
||||||
index_url: /ui/static/index.html
|
index_url: /cbpi_ui/static/index.html
|
||||||
|
|
||||||
port: 8080
|
port: 8080
|
||||||
|
|
||||||
|
|
196
config/dashboard/cbpi_dashboard_1.json
Normal file
196
config/dashboard/cbpi_dashboard_1.json
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
{
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"id": "8bf7b72b-76e8-4c7a-86da-23f211d1942b",
|
||||||
|
"name": "Kettle",
|
||||||
|
"props": {
|
||||||
|
"heigth": "150",
|
||||||
|
"width": "100"
|
||||||
|
},
|
||||||
|
"type": "Kettle",
|
||||||
|
"x": 200,
|
||||||
|
"y": 115
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "78e5fe5a-6db8-4bd6-ba18-e67469cb1a0f",
|
||||||
|
"name": "Kettle",
|
||||||
|
"props": {
|
||||||
|
"heigth": "150",
|
||||||
|
"width": "100"
|
||||||
|
},
|
||||||
|
"type": "Kettle",
|
||||||
|
"x": 610,
|
||||||
|
"y": 115
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0f45b8b5-8ebd-41b2-9bd2-a957f655b84c",
|
||||||
|
"name": "Kettle",
|
||||||
|
"props": {
|
||||||
|
"heigth": "150",
|
||||||
|
"width": "100"
|
||||||
|
},
|
||||||
|
"type": "Kettle",
|
||||||
|
"x": 410,
|
||||||
|
"y": 115
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9d7d8ebf-ffad-4e35-96db-23d5b7f9c11c",
|
||||||
|
"name": "Sensor Data",
|
||||||
|
"props": {
|
||||||
|
"sensor": 1,
|
||||||
|
"unit": "\u00b0"
|
||||||
|
},
|
||||||
|
"type": "Sensor",
|
||||||
|
"x": 240,
|
||||||
|
"y": 230
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "97331778-eca2-4e35-b94b-3337763a372c",
|
||||||
|
"name": "Sensor Data",
|
||||||
|
"props": {
|
||||||
|
"sensor": 1,
|
||||||
|
"unit": "\u00b0"
|
||||||
|
},
|
||||||
|
"type": "Sensor",
|
||||||
|
"x": 450,
|
||||||
|
"y": 230
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f20b7ed4-cdc8-46c2-a01a-ac0c0eab3801",
|
||||||
|
"name": "Sensor Data",
|
||||||
|
"props": {
|
||||||
|
"sensor": 1,
|
||||||
|
"unit": "\u00b0"
|
||||||
|
},
|
||||||
|
"type": "Sensor",
|
||||||
|
"x": 655,
|
||||||
|
"y": 230
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "03eec665-ab3f-423b-bfb7-6faea856937b",
|
||||||
|
"name": "MashTun",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 205,
|
||||||
|
"y": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9912ec53-71c7-4499-a1df-6466a4c02607",
|
||||||
|
"name": "Hot Liqour Tank",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 415,
|
||||||
|
"y": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4df11ebf-a8c9-4dc1-af8e-b6566bda0137",
|
||||||
|
"name": "Boil",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 615,
|
||||||
|
"y": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e51ca9a8-e911-42ea-ba19-ca21cfed72ce",
|
||||||
|
"name": "Current Temp",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 220,
|
||||||
|
"y": 215
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6eb1d953-c579-4417-89ef-55cb472517a5",
|
||||||
|
"name": "Current Temp",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 435,
|
||||||
|
"y": 215
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ad3087a4-5b8f-4ade-b665-4b2acbbaecc2",
|
||||||
|
"name": "Current Temp",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "10"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 635,
|
||||||
|
"y": 215
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "891eac86-3d81-4438-b9c4-65035c71e52f",
|
||||||
|
"name": "CraftBeerPi v4.0",
|
||||||
|
"props": {
|
||||||
|
"color": "#fff",
|
||||||
|
"size": "30"
|
||||||
|
},
|
||||||
|
"type": "Text",
|
||||||
|
"x": 200,
|
||||||
|
"y": 65
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pathes": [
|
||||||
|
{
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
670,
|
||||||
|
260
|
||||||
|
],
|
||||||
|
[
|
||||||
|
670,
|
||||||
|
305
|
||||||
|
],
|
||||||
|
[
|
||||||
|
265,
|
||||||
|
305
|
||||||
|
],
|
||||||
|
[
|
||||||
|
265,
|
||||||
|
260
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"id": "74b4bf4d-3bb8-44d8-a50b-f27c915f6218"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
305,
|
||||||
|
230
|
||||||
|
],
|
||||||
|
[
|
||||||
|
410,
|
||||||
|
230
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"id": "c967d63c-7ec5-42b9-bbc3-e0d85b420670"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
410,
|
||||||
|
145
|
||||||
|
],
|
||||||
|
[
|
||||||
|
300,
|
||||||
|
145
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"id": "e5498af8-3086-4bee-b35b-085a13bbd2b2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,6 @@
|
||||||
{}
|
cbpi4-ui-plugin:
|
||||||
|
installation_date: '2021-01-06 16:03:31'
|
||||||
|
version: '0.0.2'
|
||||||
|
cbpi4-ui:
|
||||||
|
installation_date: '2021-01-06 16:03:31'
|
||||||
|
version: '0.0.1'
|
BIN
craftbeerpi.db
BIN
craftbeerpi.db
Binary file not shown.
|
@ -1,12 +1,12 @@
|
||||||
pandas
|
pandas
|
||||||
aiohttp==3.4.4
|
aiohttp>=3.4.4
|
||||||
aiohttp-auth==0.1.1
|
aiohttp-auth>=0.1.1
|
||||||
aiohttp-route-decorator==0.1.4
|
aiohttp-route-decorator>=0.1.4
|
||||||
aiohttp-security==0.4.0
|
aiohttp-security>=0.4.0
|
||||||
aiohttp-session==2.7.0
|
aiohttp-session>=2.7.0
|
||||||
aiohttp-swagger==1.0.5
|
aiohttp-swagger>=1.0.5
|
||||||
aiojobs==0.2.2
|
aiojobs>=0.2.2
|
||||||
aiosqlite==0.7.0
|
aiosqlite>=0.7.0
|
||||||
cryptography==2.3.1
|
cryptography>=2.3.1
|
||||||
voluptuous==0.11.5
|
voluptuous>=0.11.5
|
||||||
pyfiglet==0.7.6
|
pyfiglet>=0.7.6
|
40
requirements2.txt
Normal file
40
requirements2.txt
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
aiohttp==3.7.3
|
||||||
|
aiohttp-auth==0.1.1
|
||||||
|
aiohttp-route-decorator==0.1.4
|
||||||
|
aiohttp-security==0.4.0
|
||||||
|
aiohttp-session==2.9.0
|
||||||
|
aiohttp-swagger==1.0.15
|
||||||
|
aiojobs==0.3.0
|
||||||
|
aiosqlite==0.16.0
|
||||||
|
asn1crypto==1.4.0
|
||||||
|
astroid==2.4.2
|
||||||
|
async-timeout==3.0.1
|
||||||
|
attrs==20.3.0
|
||||||
|
certifi==2020.12.5
|
||||||
|
cffi==1.14.4
|
||||||
|
chardet==3.0.4
|
||||||
|
cryptography==3.3.1
|
||||||
|
idna==2.10
|
||||||
|
isort==5.7.0
|
||||||
|
Jinja2==2.11.2
|
||||||
|
lazy-object-proxy==1.4.3
|
||||||
|
MarkupSafe==1.1.1
|
||||||
|
mccabe==0.6.1
|
||||||
|
multidict==4.7.6
|
||||||
|
numpy==1.19.4
|
||||||
|
pandas==1.2.0
|
||||||
|
pycparser==2.20
|
||||||
|
pyfiglet==0.8.post1
|
||||||
|
pylint==2.6.0
|
||||||
|
python-dateutil==2.8.1
|
||||||
|
pytz==2020.5
|
||||||
|
PyYAML==5.3.1
|
||||||
|
requests==2.25.1
|
||||||
|
six==1.15.0
|
||||||
|
ticket-auth==0.1.4
|
||||||
|
toml==0.10.2
|
||||||
|
typing-extensions==3.7.4.3
|
||||||
|
urllib3==1.26.2
|
||||||
|
voluptuous==0.12.1
|
||||||
|
wrapt==1.12.1
|
||||||
|
yarl==1.6.3
|
241
venv/bin/Activate.ps1
Normal file
241
venv/bin/Activate.ps1
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Activate a Python virtual environment for the current PowerShell session.
|
||||||
|
|
||||||
|
.Description
|
||||||
|
Pushes the python executable for a virtual environment to the front of the
|
||||||
|
$Env:PATH environment variable and sets the prompt to signify that you are
|
||||||
|
in a Python virtual environment. Makes use of the command line switches as
|
||||||
|
well as the `pyvenv.cfg` file values present in the virtual environment.
|
||||||
|
|
||||||
|
.Parameter VenvDir
|
||||||
|
Path to the directory that contains the virtual environment to activate. The
|
||||||
|
default value for this is the parent of the directory that the Activate.ps1
|
||||||
|
script is located within.
|
||||||
|
|
||||||
|
.Parameter Prompt
|
||||||
|
The prompt prefix to display when this virtual environment is activated. By
|
||||||
|
default, this prompt is the name of the virtual environment folder (VenvDir)
|
||||||
|
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -Verbose
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||||
|
and shows extra information about the activation as it executes.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
||||||
|
Activates the Python virtual environment located in the specified location.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Activate.ps1 -Prompt "MyPython"
|
||||||
|
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||||
|
and prefixes the current prompt with the specified string (surrounded in
|
||||||
|
parentheses) while the virtual environment is active.
|
||||||
|
|
||||||
|
.Notes
|
||||||
|
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
||||||
|
execution policy for the user. You can do this by issuing the following PowerShell
|
||||||
|
command:
|
||||||
|
|
||||||
|
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
|
||||||
|
For more information on Execution Policies:
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=135170
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[String]
|
||||||
|
$VenvDir,
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[String]
|
||||||
|
$Prompt
|
||||||
|
)
|
||||||
|
|
||||||
|
<# Function declarations --------------------------------------------------- #>
|
||||||
|
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Remove all shell session elements added by the Activate script, including the
|
||||||
|
addition of the virtual environment's Python executable from the beginning of
|
||||||
|
the PATH variable.
|
||||||
|
|
||||||
|
.Parameter NonDestructive
|
||||||
|
If present, do not remove this function from the global namespace for the
|
||||||
|
session.
|
||||||
|
|
||||||
|
#>
|
||||||
|
function global:deactivate ([switch]$NonDestructive) {
|
||||||
|
# Revert to original values
|
||||||
|
|
||||||
|
# The prior prompt:
|
||||||
|
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
||||||
|
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
||||||
|
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
||||||
|
}
|
||||||
|
|
||||||
|
# The prior PYTHONHOME:
|
||||||
|
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
||||||
|
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
||||||
|
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
}
|
||||||
|
|
||||||
|
# The prior PATH:
|
||||||
|
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
||||||
|
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
||||||
|
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just remove the VIRTUAL_ENV altogether:
|
||||||
|
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
||||||
|
Remove-Item -Path env:VIRTUAL_ENV
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
||||||
|
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
||||||
|
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
# Leave deactivate function in the global namespace if requested:
|
||||||
|
if (-not $NonDestructive) {
|
||||||
|
Remove-Item -Path function:deactivate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
.Description
|
||||||
|
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
||||||
|
given folder, and returns them in a map.
|
||||||
|
|
||||||
|
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
||||||
|
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
||||||
|
then it is considered a `key = value` line. The left hand string is the key,
|
||||||
|
the right hand is the value.
|
||||||
|
|
||||||
|
If the value starts with a `'` or a `"` then the first and last character is
|
||||||
|
stripped from the value before being captured.
|
||||||
|
|
||||||
|
.Parameter ConfigDir
|
||||||
|
Path to the directory that contains the `pyvenv.cfg` file.
|
||||||
|
#>
|
||||||
|
function Get-PyVenvConfig(
|
||||||
|
[String]
|
||||||
|
$ConfigDir
|
||||||
|
) {
|
||||||
|
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
||||||
|
|
||||||
|
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
||||||
|
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
||||||
|
|
||||||
|
# An empty map will be returned if no config file is found.
|
||||||
|
$pyvenvConfig = @{ }
|
||||||
|
|
||||||
|
if ($pyvenvConfigPath) {
|
||||||
|
|
||||||
|
Write-Verbose "File exists, parse `key = value` lines"
|
||||||
|
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
||||||
|
|
||||||
|
$pyvenvConfigContent | ForEach-Object {
|
||||||
|
$keyval = $PSItem -split "\s*=\s*", 2
|
||||||
|
if ($keyval[0] -and $keyval[1]) {
|
||||||
|
$val = $keyval[1]
|
||||||
|
|
||||||
|
# Remove extraneous quotations around a string value.
|
||||||
|
if ("'""".Contains($val.Substring(0, 1))) {
|
||||||
|
$val = $val.Substring(1, $val.Length - 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
$pyvenvConfig[$keyval[0]] = $val
|
||||||
|
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pyvenvConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<# Begin Activate script --------------------------------------------------- #>
|
||||||
|
|
||||||
|
# Determine the containing directory of this script
|
||||||
|
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$VenvExecDir = Get-Item -Path $VenvExecPath
|
||||||
|
|
||||||
|
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
||||||
|
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
||||||
|
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
||||||
|
|
||||||
|
# Set values required in priority: CmdLine, ConfigFile, Default
|
||||||
|
# First, get the location of the virtual environment, it might not be
|
||||||
|
# VenvExecDir if specified on the command line.
|
||||||
|
if ($VenvDir) {
|
||||||
|
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
||||||
|
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
||||||
|
Write-Verbose "VenvDir=$VenvDir"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Next, read the `pyvenv.cfg` file to determine any required value such
|
||||||
|
# as `prompt`.
|
||||||
|
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
||||||
|
|
||||||
|
# Next, set the prompt from the command line, or the config file, or
|
||||||
|
# just use the name of the virtual environment folder.
|
||||||
|
if ($Prompt) {
|
||||||
|
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
||||||
|
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
||||||
|
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
||||||
|
$Prompt = $pyvenvCfg['prompt'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)"
|
||||||
|
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
||||||
|
$Prompt = Split-Path -Path $venvDir -Leaf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Verbose "Prompt = '$Prompt'"
|
||||||
|
Write-Verbose "VenvDir='$VenvDir'"
|
||||||
|
|
||||||
|
# Deactivate any currently active virtual environment, but leave the
|
||||||
|
# deactivate function in place.
|
||||||
|
deactivate -nondestructive
|
||||||
|
|
||||||
|
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
||||||
|
# that there is an activated venv.
|
||||||
|
$env:VIRTUAL_ENV = $VenvDir
|
||||||
|
|
||||||
|
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||||
|
|
||||||
|
Write-Verbose "Setting prompt to '$Prompt'"
|
||||||
|
|
||||||
|
# Set the prompt to include the env name
|
||||||
|
# Make sure _OLD_VIRTUAL_PROMPT is global
|
||||||
|
function global:_OLD_VIRTUAL_PROMPT { "" }
|
||||||
|
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
||||||
|
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
||||||
|
|
||||||
|
function global:prompt {
|
||||||
|
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
||||||
|
_OLD_VIRTUAL_PROMPT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clear PYTHONHOME
|
||||||
|
if (Test-Path -Path Env:PYTHONHOME) {
|
||||||
|
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
Remove-Item -Path Env:PYTHONHOME
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the venv to the PATH
|
||||||
|
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
||||||
|
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
76
venv/bin/activate
Normal file
76
venv/bin/activate
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# This file must be used with "source bin/activate" *from bash*
|
||||||
|
# you cannot run it directly
|
||||||
|
|
||||||
|
deactivate () {
|
||||||
|
# reset old environment variables
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
||||||
|
PATH="${_OLD_VIRTUAL_PATH:-}"
|
||||||
|
export PATH
|
||||||
|
unset _OLD_VIRTUAL_PATH
|
||||||
|
fi
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
||||||
|
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
||||||
|
export PYTHONHOME
|
||||||
|
unset _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
||||||
|
hash -r
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
||||||
|
PS1="${_OLD_VIRTUAL_PS1:-}"
|
||||||
|
export PS1
|
||||||
|
unset _OLD_VIRTUAL_PS1
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset VIRTUAL_ENV
|
||||||
|
if [ ! "${1:-}" = "nondestructive" ] ; then
|
||||||
|
# Self destruct!
|
||||||
|
unset -f deactivate
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# unset irrelevant variables
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
VIRTUAL_ENV="/Users/manuelfritsch/Documents/git/cbpi4/venv"
|
||||||
|
export VIRTUAL_ENV
|
||||||
|
|
||||||
|
_OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# unset PYTHONHOME if set
|
||||||
|
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
||||||
|
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
||||||
|
if [ -n "${PYTHONHOME:-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
||||||
|
unset PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PS1="${PS1:-}"
|
||||||
|
if [ "x(venv) " != x ] ; then
|
||||||
|
PS1="(venv) ${PS1:-}"
|
||||||
|
else
|
||||||
|
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
|
||||||
|
# special case for Aspen magic directories
|
||||||
|
# see https://aspen.io/
|
||||||
|
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
|
||||||
|
else
|
||||||
|
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
export PS1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
||||||
|
hash -r
|
||||||
|
fi
|
37
venv/bin/activate.csh
Normal file
37
venv/bin/activate.csh
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||||
|
# You cannot run it directly.
|
||||||
|
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||||
|
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
|
||||||
|
|
||||||
|
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate'
|
||||||
|
|
||||||
|
# Unset irrelevant variables.
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
setenv VIRTUAL_ENV "/Users/manuelfritsch/Documents/git/cbpi4/venv"
|
||||||
|
|
||||||
|
set _OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
|
|
||||||
|
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||||
|
|
||||||
|
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
|
||||||
|
if ("venv" != "") then
|
||||||
|
set env_name = "venv"
|
||||||
|
else
|
||||||
|
if (`basename "VIRTUAL_ENV"` == "__") then
|
||||||
|
# special case for Aspen magic directories
|
||||||
|
# see https://aspen.io/
|
||||||
|
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
|
||||||
|
else
|
||||||
|
set env_name = `basename "$VIRTUAL_ENV"`
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
set prompt = "[$env_name] $prompt"
|
||||||
|
unset env_name
|
||||||
|
endif
|
||||||
|
|
||||||
|
alias pydoc python -m pydoc
|
||||||
|
|
||||||
|
rehash
|
75
venv/bin/activate.fish
Normal file
75
venv/bin/activate.fish
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
|
||||||
|
# you cannot run it directly
|
||||||
|
|
||||||
|
function deactivate -d "Exit virtualenv and return to normal shell environment"
|
||||||
|
# reset old environment variables
|
||||||
|
if test -n "$_OLD_VIRTUAL_PATH"
|
||||||
|
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||||
|
set -e _OLD_VIRTUAL_PATH
|
||||||
|
end
|
||||||
|
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||||
|
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||||
|
functions -e fish_prompt
|
||||||
|
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||||
|
functions -c _old_fish_prompt fish_prompt
|
||||||
|
functions -e _old_fish_prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
set -e VIRTUAL_ENV
|
||||||
|
if test "$argv[1]" != "nondestructive"
|
||||||
|
# Self destruct!
|
||||||
|
functions -e deactivate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# unset irrelevant variables
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
set -gx VIRTUAL_ENV "/Users/manuelfritsch/Documents/git/cbpi4/venv"
|
||||||
|
|
||||||
|
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||||
|
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
|
||||||
|
|
||||||
|
# unset PYTHONHOME if set
|
||||||
|
if set -q PYTHONHOME
|
||||||
|
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||||
|
set -e PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||||
|
# fish uses a function instead of an env var to generate the prompt.
|
||||||
|
|
||||||
|
# save the current fish_prompt function as the function _old_fish_prompt
|
||||||
|
functions -c fish_prompt _old_fish_prompt
|
||||||
|
|
||||||
|
# with the original prompt function renamed, we can override with our own.
|
||||||
|
function fish_prompt
|
||||||
|
# Save the return status of the last command
|
||||||
|
set -l old_status $status
|
||||||
|
|
||||||
|
# Prompt override?
|
||||||
|
if test -n "(venv) "
|
||||||
|
printf "%s%s" "(venv) " (set_color normal)
|
||||||
|
else
|
||||||
|
# ...Otherwise, prepend env
|
||||||
|
set -l _checkbase (basename "$VIRTUAL_ENV")
|
||||||
|
if test $_checkbase = "__"
|
||||||
|
# special case for Aspen magic directories
|
||||||
|
# see https://aspen.io/
|
||||||
|
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
|
||||||
|
else
|
||||||
|
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Restore the return status of the previous command.
|
||||||
|
echo "exit $old_status" | .
|
||||||
|
_old_fish_prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||||
|
end
|
33
venv/bin/autopep8
Executable file
33
venv/bin/autopep8
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# EASY-INSTALL-ENTRY-SCRIPT: 'autopep8==1.5.4','console_scripts','autopep8'
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# for compatibility with easy_install; see #2198
|
||||||
|
__requires__ = 'autopep8==1.5.4'
|
||||||
|
|
||||||
|
try:
|
||||||
|
from importlib.metadata import distribution
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
from importlib_metadata import distribution
|
||||||
|
except ImportError:
|
||||||
|
from pkg_resources import load_entry_point
|
||||||
|
|
||||||
|
|
||||||
|
def importlib_load_entry_point(spec, group, name):
|
||||||
|
dist_name, _, _ = spec.partition('==')
|
||||||
|
matches = (
|
||||||
|
entry_point
|
||||||
|
for entry_point in distribution(dist_name).entry_points
|
||||||
|
if entry_point.group == group and entry_point.name == name
|
||||||
|
)
|
||||||
|
return next(matches).load()
|
||||||
|
|
||||||
|
|
||||||
|
globals().setdefault('load_entry_point', importlib_load_entry_point)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(load_entry_point('autopep8==1.5.4', 'console_scripts', 'autopep8')())
|
8
venv/bin/chardetect
Executable file
8
venv/bin/chardetect
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from chardet.cli.chardetect import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/easy_install
Executable file
8
venv/bin/easy_install
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/easy_install-3.8
Executable file
8
venv/bin/easy_install-3.8
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/epylint
Executable file
8
venv/bin/epylint
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pylint import run_epylint
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(run_epylint())
|
8
venv/bin/f2py
Executable file
8
venv/bin/f2py
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from numpy.f2py.f2py2e import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/f2py3
Executable file
8
venv/bin/f2py3
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from numpy.f2py.f2py2e import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/f2py3.8
Executable file
8
venv/bin/f2py3.8
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from numpy.f2py.f2py2e import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/isort
Executable file
8
venv/bin/isort
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from isort.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/isort-identify-imports
Executable file
8
venv/bin/isort-identify-imports
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from isort.main import identify_imports_main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(identify_imports_main())
|
8
venv/bin/pip
Executable file
8
venv/bin/pip
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/pip3
Executable file
8
venv/bin/pip3
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/pip3.8
Executable file
8
venv/bin/pip3.8
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/pycodestyle
Executable file
8
venv/bin/pycodestyle
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pycodestyle import _main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(_main())
|
8
venv/bin/pyfiglet
Executable file
8
venv/bin/pyfiglet
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pyfiglet import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
8
venv/bin/pylint
Executable file
8
venv/bin/pylint
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pylint import run_pylint
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(run_pylint())
|
8
venv/bin/pyreverse
Executable file
8
venv/bin/pyreverse
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pylint import run_pyreverse
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(run_pyreverse())
|
1
venv/bin/python
Symbolic link
1
venv/bin/python
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
python3
|
1
venv/bin/python3
Symbolic link
1
venv/bin/python3
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/Library/Frameworks/Python.framework/Versions/3.8/bin/python3
|
8
venv/bin/symilar
Executable file
8
venv/bin/symilar
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/Users/manuelfritsch/Documents/git/cbpi4/venv/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pylint import run_symilar
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(run_symilar())
|
|
@ -0,0 +1 @@
|
||||||
|
pip
|
|
@ -0,0 +1,28 @@
|
||||||
|
Copyright 2007 Pallets
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,106 @@
|
||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: Jinja2
|
||||||
|
Version: 2.11.2
|
||||||
|
Summary: A very fast and expressive template engine.
|
||||||
|
Home-page: https://palletsprojects.com/p/jinja/
|
||||||
|
Author: Armin Ronacher
|
||||||
|
Author-email: armin.ronacher@active-4.com
|
||||||
|
Maintainer: Pallets
|
||||||
|
Maintainer-email: contact@palletsprojects.com
|
||||||
|
License: BSD-3-Clause
|
||||||
|
Project-URL: Documentation, https://jinja.palletsprojects.com/
|
||||||
|
Project-URL: Code, https://github.com/pallets/jinja
|
||||||
|
Project-URL: Issue tracker, https://github.com/pallets/jinja/issues
|
||||||
|
Platform: UNKNOWN
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Environment :: Web Environment
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: License :: OSI Approved :: BSD License
|
||||||
|
Classifier: Operating System :: OS Independent
|
||||||
|
Classifier: Programming Language :: Python
|
||||||
|
Classifier: Programming Language :: Python :: 2
|
||||||
|
Classifier: Programming Language :: Python :: 2.7
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3.5
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Programming Language :: Python :: 3.8
|
||||||
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||||
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||||
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||||
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||||
|
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||||
|
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
|
||||||
|
Description-Content-Type: text/x-rst
|
||||||
|
Requires-Dist: MarkupSafe (>=0.23)
|
||||||
|
Provides-Extra: i18n
|
||||||
|
Requires-Dist: Babel (>=0.8) ; extra == 'i18n'
|
||||||
|
|
||||||
|
Jinja
|
||||||
|
=====
|
||||||
|
|
||||||
|
Jinja is a fast, expressive, extensible templating engine. Special
|
||||||
|
placeholders in the template allow writing code similar to Python
|
||||||
|
syntax. Then the template is passed data to render the final document.
|
||||||
|
|
||||||
|
It includes:
|
||||||
|
|
||||||
|
- Template inheritance and inclusion.
|
||||||
|
- Define and import macros within templates.
|
||||||
|
- HTML templates can use autoescaping to prevent XSS from untrusted
|
||||||
|
user input.
|
||||||
|
- A sandboxed environment can safely render untrusted templates.
|
||||||
|
- AsyncIO support for generating templates and calling async
|
||||||
|
functions.
|
||||||
|
- I18N support with Babel.
|
||||||
|
- Templates are compiled to optimized Python code just-in-time and
|
||||||
|
cached, or can be compiled ahead-of-time.
|
||||||
|
- Exceptions point to the correct line in templates to make debugging
|
||||||
|
easier.
|
||||||
|
- Extensible filters, tests, functions, and even syntax.
|
||||||
|
|
||||||
|
Jinja's philosophy is that while application logic belongs in Python if
|
||||||
|
possible, it shouldn't make the template designer's job difficult by
|
||||||
|
restricting functionality too much.
|
||||||
|
|
||||||
|
|
||||||
|
Installing
|
||||||
|
----------
|
||||||
|
|
||||||
|
Install and update using `pip`_:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ pip install -U Jinja2
|
||||||
|
|
||||||
|
.. _pip: https://pip.pypa.io/en/stable/quickstart/
|
||||||
|
|
||||||
|
|
||||||
|
In A Nutshell
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}Members{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<ul>
|
||||||
|
{% for user in users %}
|
||||||
|
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
Links
|
||||||
|
-----
|
||||||
|
|
||||||
|
- Website: https://palletsprojects.com/p/jinja/
|
||||||
|
- Documentation: https://jinja.palletsprojects.com/
|
||||||
|
- Releases: https://pypi.org/project/Jinja2/
|
||||||
|
- Code: https://github.com/pallets/jinja
|
||||||
|
- Issue tracker: https://github.com/pallets/jinja/issues
|
||||||
|
- Test status: https://dev.azure.com/pallets/jinja/_build
|
||||||
|
- Official chat: https://discord.gg/t6rrQZH
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
Jinja2-2.11.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||||
|
Jinja2-2.11.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
|
||||||
|
Jinja2-2.11.2.dist-info/METADATA,sha256=5ZHRZoIRAMHsJPnqhlJ622_dRPsYePYJ-9EH4-Ry7yI,3535
|
||||||
|
Jinja2-2.11.2.dist-info/RECORD,,
|
||||||
|
Jinja2-2.11.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
|
||||||
|
Jinja2-2.11.2.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61
|
||||||
|
Jinja2-2.11.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7
|
||||||
|
jinja2/__init__.py,sha256=0QCM_jKKDM10yzSdHRVV4mQbCbDqf0GN0GirAqibn9Y,1549
|
||||||
|
jinja2/__pycache__/__init__.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/_compat.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/_identifier.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/asyncfilters.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/asyncsupport.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/bccache.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/compiler.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/constants.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/debug.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/defaults.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/environment.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/exceptions.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/ext.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/filters.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/idtracking.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/lexer.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/loaders.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/meta.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/nativetypes.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/nodes.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/optimizer.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/parser.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/runtime.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/sandbox.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/tests.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/utils.cpython-38.pyc,,
|
||||||
|
jinja2/__pycache__/visitor.cpython-38.pyc,,
|
||||||
|
jinja2/_compat.py,sha256=B6Se8HjnXVpzz9-vfHejn-DV2NjaVK-Iewupc5kKlu8,3191
|
||||||
|
jinja2/_identifier.py,sha256=EdgGJKi7O1yvr4yFlvqPNEqV6M1qHyQr8Gt8GmVTKVM,1775
|
||||||
|
jinja2/asyncfilters.py,sha256=XJtYXTxFvcJ5xwk6SaDL4S0oNnT0wPYvXBCSzc482fI,4250
|
||||||
|
jinja2/asyncsupport.py,sha256=ZBFsDLuq3Gtji3Ia87lcyuDbqaHZJRdtShZcqwpFnSQ,7209
|
||||||
|
jinja2/bccache.py,sha256=3Pmp4jo65M9FQuIxdxoDBbEDFwe4acDMQf77nEJfrHA,12139
|
||||||
|
jinja2/compiler.py,sha256=Ta9W1Lit542wItAHXlDcg0sEOsFDMirCdlFPHAurg4o,66284
|
||||||
|
jinja2/constants.py,sha256=RR1sTzNzUmKco6aZicw4JpQpJGCuPuqm1h1YmCNUEFY,1458
|
||||||
|
jinja2/debug.py,sha256=neR7GIGGjZH3_ILJGVUYy3eLQCCaWJMXOb7o0kGInWc,8529
|
||||||
|
jinja2/defaults.py,sha256=85B6YUUCyWPSdrSeVhcqFVuu_bHUAQXeey--FIwSeVQ,1126
|
||||||
|
jinja2/environment.py,sha256=XDSLKc4SqNLMOwTSq3TbWEyA5WyXfuLuVD0wAVjEFwM,50629
|
||||||
|
jinja2/exceptions.py,sha256=VjNLawcmf2ODffqVMCQK1cRmvFaUfQWF4u8ouP3QPcE,5425
|
||||||
|
jinja2/ext.py,sha256=AtwL5O5enT_L3HR9-oBvhGyUTdGoyaqG_ICtnR_EVd4,26441
|
||||||
|
jinja2/filters.py,sha256=_RpPgAlgIj7ExvyDzcHAC3B36cocfWK-1TEketbNeM0,41415
|
||||||
|
jinja2/idtracking.py,sha256=J3O4VHsrbf3wzwiBc7Cro26kHb6_5kbULeIOzocchIU,9211
|
||||||
|
jinja2/lexer.py,sha256=nUFLRKhhKmmEWkLI65nQePgcQs7qsRdjVYZETMt_v0g,30331
|
||||||
|
jinja2/loaders.py,sha256=C-fST_dmFjgWkp0ZuCkrgICAoOsoSIF28wfAFink0oU,17666
|
||||||
|
jinja2/meta.py,sha256=QjyYhfNRD3QCXjBJpiPl9KgkEkGXJbAkCUq4-Ur10EQ,4131
|
||||||
|
jinja2/nativetypes.py,sha256=Ul__gtVw4xH-0qvUvnCNHedQeNDwmEuyLJztzzSPeRg,2753
|
||||||
|
jinja2/nodes.py,sha256=Mk1oJPVgIjnQw9WOqILvcu3rLepcFZ0ahxQm2mbwDwc,31095
|
||||||
|
jinja2/optimizer.py,sha256=gQLlMYzvQhluhzmAIFA1tXS0cwgWYOjprN-gTRcHVsc,1457
|
||||||
|
jinja2/parser.py,sha256=fcfdqePNTNyvosIvczbytVA332qpsURvYnCGcjDHSkA,35660
|
||||||
|
jinja2/runtime.py,sha256=0y-BRyIEZ9ltByL2Id6GpHe1oDRQAwNeQvI0SKobNMw,30618
|
||||||
|
jinja2/sandbox.py,sha256=knayyUvXsZ-F0mk15mO2-ehK9gsw04UhB8td-iUOtLc,17127
|
||||||
|
jinja2/tests.py,sha256=iO_Y-9Vo60zrVe1lMpSl5sKHqAxe2leZHC08OoZ8K24,4799
|
||||||
|
jinja2/utils.py,sha256=OoVMlQe9S2-lWT6jJbTu9tDuDvGNyWUhHDcE51i5_Do,22522
|
||||||
|
jinja2/visitor.py,sha256=DUHupl0a4PGp7nxRtZFttUzAi1ccxzqc2hzetPYUz8U,3240
|
|
@ -0,0 +1,6 @@
|
||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: bdist_wheel (0.34.2)
|
||||||
|
Root-Is-Purelib: true
|
||||||
|
Tag: py2-none-any
|
||||||
|
Tag: py3-none-any
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[babel.extractors]
|
||||||
|
jinja2 = jinja2.ext:babel_extract [i18n]
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
jinja2
|
|
@ -0,0 +1 @@
|
||||||
|
pip
|
|
@ -0,0 +1,28 @@
|
||||||
|
Copyright 2010 Pallets
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,105 @@
|
||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: MarkupSafe
|
||||||
|
Version: 1.1.1
|
||||||
|
Summary: Safely add untrusted strings to HTML/XML markup.
|
||||||
|
Home-page: https://palletsprojects.com/p/markupsafe/
|
||||||
|
Author: Armin Ronacher
|
||||||
|
Author-email: armin.ronacher@active-4.com
|
||||||
|
Maintainer: The Pallets Team
|
||||||
|
Maintainer-email: contact@palletsprojects.com
|
||||||
|
License: BSD-3-Clause
|
||||||
|
Project-URL: Documentation, https://markupsafe.palletsprojects.com/
|
||||||
|
Project-URL: Code, https://github.com/pallets/markupsafe
|
||||||
|
Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
|
||||||
|
Platform: UNKNOWN
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Environment :: Web Environment
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: License :: OSI Approved :: BSD License
|
||||||
|
Classifier: Operating System :: OS Independent
|
||||||
|
Classifier: Programming Language :: Python
|
||||||
|
Classifier: Programming Language :: Python :: 2
|
||||||
|
Classifier: Programming Language :: Python :: 2.7
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3.4
|
||||||
|
Classifier: Programming Language :: Python :: 3.5
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||||
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||||
|
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||||
|
Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
|
||||||
|
Description-Content-Type: text/x-rst
|
||||||
|
|
||||||
|
MarkupSafe
|
||||||
|
==========
|
||||||
|
|
||||||
|
MarkupSafe implements a text object that escapes characters so it is
|
||||||
|
safe to use in HTML and XML. Characters that have special meanings are
|
||||||
|
replaced so that they display as the actual characters. This mitigates
|
||||||
|
injection attacks, meaning untrusted user input can safely be displayed
|
||||||
|
on a page.
|
||||||
|
|
||||||
|
|
||||||
|
Installing
|
||||||
|
----------
|
||||||
|
|
||||||
|
Install and update using `pip`_:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
pip install -U MarkupSafe
|
||||||
|
|
||||||
|
.. _pip: https://pip.pypa.io/en/stable/quickstart/
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: pycon
|
||||||
|
|
||||||
|
>>> from markupsafe import Markup, escape
|
||||||
|
>>> # escape replaces special characters and wraps in Markup
|
||||||
|
>>> escape('<script>alert(document.cookie);</script>')
|
||||||
|
Markup(u'<script>alert(document.cookie);</script>')
|
||||||
|
>>> # wrap in Markup to mark text "safe" and prevent escaping
|
||||||
|
>>> Markup('<strong>Hello</strong>')
|
||||||
|
Markup('<strong>hello</strong>')
|
||||||
|
>>> escape(Markup('<strong>Hello</strong>'))
|
||||||
|
Markup('<strong>hello</strong>')
|
||||||
|
>>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
|
||||||
|
>>> # methods and operators escape their arguments
|
||||||
|
>>> template = Markup("Hello <em>%s</em>")
|
||||||
|
>>> template % '"World"'
|
||||||
|
Markup('Hello <em>"World"</em>')
|
||||||
|
|
||||||
|
|
||||||
|
Donate
|
||||||
|
------
|
||||||
|
|
||||||
|
The Pallets organization develops and supports MarkupSafe and other
|
||||||
|
libraries that use it. In order to grow the community of contributors
|
||||||
|
and users, and allow the maintainers to devote more time to the
|
||||||
|
projects, `please donate today`_.
|
||||||
|
|
||||||
|
.. _please donate today: https://palletsprojects.com/donate
|
||||||
|
|
||||||
|
|
||||||
|
Links
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Website: https://palletsprojects.com/p/markupsafe/
|
||||||
|
* Documentation: https://markupsafe.palletsprojects.com/
|
||||||
|
* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
|
||||||
|
* Releases: https://pypi.org/project/MarkupSafe/
|
||||||
|
* Code: https://github.com/pallets/markupsafe
|
||||||
|
* Issue tracker: https://github.com/pallets/markupsafe/issues
|
||||||
|
* Test status:
|
||||||
|
|
||||||
|
* Linux, Mac: https://travis-ci.org/pallets/markupsafe
|
||||||
|
* Windows: https://ci.appveyor.com/project/pallets/markupsafe
|
||||||
|
|
||||||
|
* Test coverage: https://codecov.io/gh/pallets/markupsafe
|
||||||
|
* Official chat: https://discord.gg/t6rrQZH
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
MarkupSafe-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||||
|
MarkupSafe-1.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
|
||||||
|
MarkupSafe-1.1.1.dist-info/METADATA,sha256=IFCP4hCNGjXJgMoSvdjPiKDLAMUTTWoxKXQsQvmyMNU,3653
|
||||||
|
MarkupSafe-1.1.1.dist-info/RECORD,,
|
||||||
|
MarkupSafe-1.1.1.dist-info/WHEEL,sha256=Q2jwauV7SdXlb20cz-bh9vn-BQ4tlA1IGNkj_GWnse8,109
|
||||||
|
MarkupSafe-1.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
|
||||||
|
markupsafe/__init__.py,sha256=oTblO5f9KFM-pvnq9bB0HgElnqkJyqHnFN1Nx2NIvnY,10126
|
||||||
|
markupsafe/__pycache__/__init__.cpython-38.pyc,,
|
||||||
|
markupsafe/__pycache__/_compat.cpython-38.pyc,,
|
||||||
|
markupsafe/__pycache__/_constants.cpython-38.pyc,,
|
||||||
|
markupsafe/__pycache__/_native.cpython-38.pyc,,
|
||||||
|
markupsafe/_compat.py,sha256=uEW1ybxEjfxIiuTbRRaJpHsPFf4yQUMMKaPgYEC5XbU,558
|
||||||
|
markupsafe/_constants.py,sha256=zo2ajfScG-l1Sb_52EP3MlDCqO7Y1BVHUXXKRsVDRNk,4690
|
||||||
|
markupsafe/_native.py,sha256=d-8S_zzYt2y512xYcuSxq0NeG2DUUvG80wVdTn-4KI8,1873
|
||||||
|
markupsafe/_speedups.c,sha256=k0fzEIK3CP6MmMqeY0ob43TP90mVN0DTyn7BAl3RqSg,9884
|
||||||
|
markupsafe/_speedups.cpython-38-darwin.so,sha256=X3mbW9ZrEJiuX0l5D69_hOpCXJkeTmPdhuiCHy5iCZc,14744
|
|
@ -0,0 +1,5 @@
|
||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: bdist_wheel (0.33.6)
|
||||||
|
Root-Is-Purelib: false
|
||||||
|
Tag: cp38-cp38-macosx_10_9_x86_64
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
markupsafe
|
|
@ -0,0 +1,39 @@
|
||||||
|
Metadata-Version: 1.2
|
||||||
|
Name: PyYAML
|
||||||
|
Version: 5.3.1
|
||||||
|
Summary: YAML parser and emitter for Python
|
||||||
|
Home-page: https://github.com/yaml/pyyaml
|
||||||
|
Author: Kirill Simonov
|
||||||
|
Author-email: xi@resolvent.net
|
||||||
|
License: MIT
|
||||||
|
Download-URL: https://pypi.org/project/PyYAML/
|
||||||
|
Description: YAML is a data serialization format designed for human readability
|
||||||
|
and interaction with scripting languages. PyYAML is a YAML parser
|
||||||
|
and emitter for Python.
|
||||||
|
|
||||||
|
PyYAML features a complete YAML 1.1 parser, Unicode support, pickle
|
||||||
|
support, capable extension API, and sensible error messages. PyYAML
|
||||||
|
supports standard YAML tags and provides Python-specific tags that
|
||||||
|
allow to represent an arbitrary Python object.
|
||||||
|
|
||||||
|
PyYAML is applicable for a broad range of tasks from complex
|
||||||
|
configuration files to object serialization and persistence.
|
||||||
|
Platform: Any
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: License :: OSI Approved :: MIT License
|
||||||
|
Classifier: Operating System :: OS Independent
|
||||||
|
Classifier: Programming Language :: Cython
|
||||||
|
Classifier: Programming Language :: Python
|
||||||
|
Classifier: Programming Language :: Python :: 2
|
||||||
|
Classifier: Programming Language :: Python :: 2.7
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3.5
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Programming Language :: Python :: 3.8
|
||||||
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||||
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||||
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||||
|
Classifier: Topic :: Text Processing :: Markup
|
||||||
|
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
|
|
@ -0,0 +1,29 @@
|
||||||
|
LICENSE
|
||||||
|
README
|
||||||
|
setup.cfg
|
||||||
|
setup.py
|
||||||
|
ext/_yaml.c
|
||||||
|
ext/_yaml.h
|
||||||
|
ext/_yaml.pxd
|
||||||
|
ext/_yaml.pyx
|
||||||
|
lib3/PyYAML.egg-info/PKG-INFO
|
||||||
|
lib3/PyYAML.egg-info/SOURCES.txt
|
||||||
|
lib3/PyYAML.egg-info/dependency_links.txt
|
||||||
|
lib3/PyYAML.egg-info/top_level.txt
|
||||||
|
lib3/yaml/__init__.py
|
||||||
|
lib3/yaml/composer.py
|
||||||
|
lib3/yaml/constructor.py
|
||||||
|
lib3/yaml/cyaml.py
|
||||||
|
lib3/yaml/dumper.py
|
||||||
|
lib3/yaml/emitter.py
|
||||||
|
lib3/yaml/error.py
|
||||||
|
lib3/yaml/events.py
|
||||||
|
lib3/yaml/loader.py
|
||||||
|
lib3/yaml/nodes.py
|
||||||
|
lib3/yaml/parser.py
|
||||||
|
lib3/yaml/reader.py
|
||||||
|
lib3/yaml/representer.py
|
||||||
|
lib3/yaml/resolver.py
|
||||||
|
lib3/yaml/scanner.py
|
||||||
|
lib3/yaml/serializer.py
|
||||||
|
lib3/yaml/tokens.py
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
../yaml/__init__.py
|
||||||
|
../yaml/__pycache__/__init__.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/composer.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/constructor.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/cyaml.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/dumper.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/emitter.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/error.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/events.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/loader.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/nodes.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/parser.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/reader.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/representer.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/resolver.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/scanner.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/serializer.cpython-38.pyc
|
||||||
|
../yaml/__pycache__/tokens.cpython-38.pyc
|
||||||
|
../yaml/composer.py
|
||||||
|
../yaml/constructor.py
|
||||||
|
../yaml/cyaml.py
|
||||||
|
../yaml/dumper.py
|
||||||
|
../yaml/emitter.py
|
||||||
|
../yaml/error.py
|
||||||
|
../yaml/events.py
|
||||||
|
../yaml/loader.py
|
||||||
|
../yaml/nodes.py
|
||||||
|
../yaml/parser.py
|
||||||
|
../yaml/reader.py
|
||||||
|
../yaml/representer.py
|
||||||
|
../yaml/resolver.py
|
||||||
|
../yaml/scanner.py
|
||||||
|
../yaml/serializer.py
|
||||||
|
../yaml/tokens.py
|
||||||
|
PKG-INFO
|
||||||
|
SOURCES.txt
|
||||||
|
dependency_links.txt
|
||||||
|
top_level.txt
|
|
@ -0,0 +1,2 @@
|
||||||
|
_yaml
|
||||||
|
yaml
|
BIN
venv/lib/python3.8/site-packages/_cffi_backend.cpython-38-darwin.so
Executable file
BIN
venv/lib/python3.8/site-packages/_cffi_backend.cpython-38-darwin.so
Executable file
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
pip
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2013-2020 aiohttp maintainers
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,936 @@
|
||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: aiohttp
|
||||||
|
Version: 3.7.3
|
||||||
|
Summary: Async http client/server framework (asyncio)
|
||||||
|
Home-page: https://github.com/aio-libs/aiohttp
|
||||||
|
Author: Nikolay Kim
|
||||||
|
Author-email: fafhrd91@gmail.com
|
||||||
|
Maintainer: Nikolay Kim <fafhrd91@gmail.com>, Andrew Svetlov <andrew.svetlov@gmail.com>
|
||||||
|
Maintainer-email: aio-libs@googlegroups.com
|
||||||
|
License: Apache 2
|
||||||
|
Project-URL: Chat: Gitter, https://gitter.im/aio-libs/Lobby
|
||||||
|
Project-URL: CI: Azure Pipelines, https://dev.azure.com/aio-libs/aiohttp/_build
|
||||||
|
Project-URL: Coverage: codecov, https://codecov.io/github/aio-libs/aiohttp
|
||||||
|
Project-URL: Docs: RTD, https://docs.aiohttp.org
|
||||||
|
Project-URL: GitHub: issues, https://github.com/aio-libs/aiohttp/issues
|
||||||
|
Project-URL: GitHub: repo, https://github.com/aio-libs/aiohttp
|
||||||
|
Platform: UNKNOWN
|
||||||
|
Classifier: License :: OSI Approved :: Apache Software License
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: Programming Language :: Python
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Programming Language :: Python :: 3.8
|
||||||
|
Classifier: Programming Language :: Python :: 3.9
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Operating System :: POSIX
|
||||||
|
Classifier: Operating System :: MacOS :: MacOS X
|
||||||
|
Classifier: Operating System :: Microsoft :: Windows
|
||||||
|
Classifier: Topic :: Internet :: WWW/HTTP
|
||||||
|
Classifier: Framework :: AsyncIO
|
||||||
|
Requires-Python: >=3.6
|
||||||
|
Requires-Dist: attrs (>=17.3.0)
|
||||||
|
Requires-Dist: chardet (<4.0,>=2.0)
|
||||||
|
Requires-Dist: multidict (<7.0,>=4.5)
|
||||||
|
Requires-Dist: async-timeout (<4.0,>=3.0)
|
||||||
|
Requires-Dist: yarl (<2.0,>=1.0)
|
||||||
|
Requires-Dist: typing-extensions (>=3.6.5)
|
||||||
|
Requires-Dist: idna-ssl (>=1.0) ; python_version < "3.7"
|
||||||
|
Provides-Extra: speedups
|
||||||
|
Requires-Dist: aiodns ; extra == 'speedups'
|
||||||
|
Requires-Dist: brotlipy ; extra == 'speedups'
|
||||||
|
Requires-Dist: cchardet ; extra == 'speedups'
|
||||||
|
|
||||||
|
==================================
|
||||||
|
Async http client/server framework
|
||||||
|
==================================
|
||||||
|
|
||||||
|
.. image:: https://raw.githubusercontent.com/aio-libs/aiohttp/master/docs/_static/aiohttp-icon-128x128.png
|
||||||
|
:height: 64px
|
||||||
|
:width: 64px
|
||||||
|
:alt: aiohttp logo
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
|
.. image:: https://github.com/aio-libs/aiohttp/workflows/CI/badge.svg
|
||||||
|
:target: https://github.com/aio-libs/aiohttp/actions?query=workflow%3ACI
|
||||||
|
:alt: GitHub Actions status for master branch
|
||||||
|
|
||||||
|
.. image:: https://codecov.io/gh/aio-libs/aiohttp/branch/master/graph/badge.svg
|
||||||
|
:target: https://codecov.io/gh/aio-libs/aiohttp
|
||||||
|
:alt: codecov.io status for master branch
|
||||||
|
|
||||||
|
.. image:: https://badge.fury.io/py/aiohttp.svg
|
||||||
|
:target: https://pypi.org/project/aiohttp
|
||||||
|
:alt: Latest PyPI package version
|
||||||
|
|
||||||
|
.. image:: https://readthedocs.org/projects/aiohttp/badge/?version=latest
|
||||||
|
:target: https://docs.aiohttp.org/
|
||||||
|
:alt: Latest Read The Docs
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/discourse/status?server=https%3A%2F%2Faio-libs.discourse.group
|
||||||
|
:target: https://aio-libs.discourse.group
|
||||||
|
:alt: Discourse status
|
||||||
|
|
||||||
|
.. image:: https://badges.gitter.im/Join%20Chat.svg
|
||||||
|
:target: https://gitter.im/aio-libs/Lobby
|
||||||
|
:alt: Chat on Gitter
|
||||||
|
|
||||||
|
|
||||||
|
Key Features
|
||||||
|
============
|
||||||
|
|
||||||
|
- Supports both client and server side of HTTP protocol.
|
||||||
|
- Supports both client and server Web-Sockets out-of-the-box and avoids
|
||||||
|
Callback Hell.
|
||||||
|
- Provides Web-server with middlewares and plugable routing.
|
||||||
|
|
||||||
|
|
||||||
|
Getting started
|
||||||
|
===============
|
||||||
|
|
||||||
|
Client
|
||||||
|
------
|
||||||
|
|
||||||
|
To get something from the web:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get('http://python.org') as response:
|
||||||
|
|
||||||
|
print("Status:", response.status)
|
||||||
|
print("Content-type:", response.headers['content-type'])
|
||||||
|
|
||||||
|
html = await response.text()
|
||||||
|
print("Body:", html[:15], "...")
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.run_until_complete(main())
|
||||||
|
|
||||||
|
This prints:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
Status: 200
|
||||||
|
Content-type: text/html; charset=utf-8
|
||||||
|
Body: <!doctype html> ...
|
||||||
|
|
||||||
|
Coming from `requests <https://requests.readthedocs.io/>`_ ? Read `why we need so many lines <https://aiohttp.readthedocs.io/en/latest/http_request_lifecycle.html>`_.
|
||||||
|
|
||||||
|
Server
|
||||||
|
------
|
||||||
|
|
||||||
|
An example using a simple server:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# examples/server_simple.py
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
async def handle(request):
|
||||||
|
name = request.match_info.get('name', "Anonymous")
|
||||||
|
text = "Hello, " + name
|
||||||
|
return web.Response(text=text)
|
||||||
|
|
||||||
|
async def wshandle(request):
|
||||||
|
ws = web.WebSocketResponse()
|
||||||
|
await ws.prepare(request)
|
||||||
|
|
||||||
|
async for msg in ws:
|
||||||
|
if msg.type == web.WSMsgType.text:
|
||||||
|
await ws.send_str("Hello, {}".format(msg.data))
|
||||||
|
elif msg.type == web.WSMsgType.binary:
|
||||||
|
await ws.send_bytes(msg.data)
|
||||||
|
elif msg.type == web.WSMsgType.close:
|
||||||
|
break
|
||||||
|
|
||||||
|
return ws
|
||||||
|
|
||||||
|
|
||||||
|
app = web.Application()
|
||||||
|
app.add_routes([web.get('/', handle),
|
||||||
|
web.get('/echo', wshandle),
|
||||||
|
web.get('/{name}', handle)])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
web.run_app(app)
|
||||||
|
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
=============
|
||||||
|
|
||||||
|
https://aiohttp.readthedocs.io/
|
||||||
|
|
||||||
|
|
||||||
|
Demos
|
||||||
|
=====
|
||||||
|
|
||||||
|
https://github.com/aio-libs/aiohttp-demos
|
||||||
|
|
||||||
|
|
||||||
|
External links
|
||||||
|
==============
|
||||||
|
|
||||||
|
* `Third party libraries
|
||||||
|
<http://aiohttp.readthedocs.io/en/latest/third_party.html>`_
|
||||||
|
* `Built with aiohttp
|
||||||
|
<http://aiohttp.readthedocs.io/en/latest/built_with.html>`_
|
||||||
|
* `Powered by aiohttp
|
||||||
|
<http://aiohttp.readthedocs.io/en/latest/powered_by.html>`_
|
||||||
|
|
||||||
|
Feel free to make a Pull Request for adding your link to these pages!
|
||||||
|
|
||||||
|
|
||||||
|
Communication channels
|
||||||
|
======================
|
||||||
|
|
||||||
|
*aio-libs discourse group*: https://aio-libs.discourse.group
|
||||||
|
|
||||||
|
*gitter chat* https://gitter.im/aio-libs/Lobby
|
||||||
|
|
||||||
|
We support `Stack Overflow
|
||||||
|
<https://stackoverflow.com/questions/tagged/aiohttp>`_.
|
||||||
|
Please add *aiohttp* tag to your question there.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
- Python >= 3.6
|
||||||
|
- async-timeout_
|
||||||
|
- attrs_
|
||||||
|
- chardet_
|
||||||
|
- multidict_
|
||||||
|
- yarl_
|
||||||
|
|
||||||
|
Optionally you may install the cChardet_ and aiodns_ libraries (highly
|
||||||
|
recommended for sake of speed).
|
||||||
|
|
||||||
|
.. _chardet: https://pypi.python.org/pypi/chardet
|
||||||
|
.. _aiodns: https://pypi.python.org/pypi/aiodns
|
||||||
|
.. _attrs: https://github.com/python-attrs/attrs
|
||||||
|
.. _multidict: https://pypi.python.org/pypi/multidict
|
||||||
|
.. _yarl: https://pypi.python.org/pypi/yarl
|
||||||
|
.. _async-timeout: https://pypi.python.org/pypi/async_timeout
|
||||||
|
.. _cChardet: https://pypi.python.org/pypi/cchardet
|
||||||
|
|
||||||
|
License
|
||||||
|
=======
|
||||||
|
|
||||||
|
``aiohttp`` is offered under the Apache 2 license.
|
||||||
|
|
||||||
|
|
||||||
|
Keepsafe
|
||||||
|
========
|
||||||
|
|
||||||
|
The aiohttp community would like to thank Keepsafe
|
||||||
|
(https://www.getkeepsafe.com) for its support in the early days of
|
||||||
|
the project.
|
||||||
|
|
||||||
|
|
||||||
|
Source code
|
||||||
|
===========
|
||||||
|
|
||||||
|
The latest developer version is available in a GitHub repository:
|
||||||
|
https://github.com/aio-libs/aiohttp
|
||||||
|
|
||||||
|
Benchmarks
|
||||||
|
==========
|
||||||
|
|
||||||
|
If you are interested in efficiency, the AsyncIO community maintains a
|
||||||
|
list of benchmarks on the official wiki:
|
||||||
|
https://github.com/python/asyncio/wiki/Benchmarks
|
||||||
|
|
||||||
|
=========
|
||||||
|
Changelog
|
||||||
|
=========
|
||||||
|
|
||||||
|
..
|
||||||
|
You should *NOT* be adding new change log entries to this file, this
|
||||||
|
file is managed by towncrier. You *may* edit previous change logs to
|
||||||
|
fix problems like typo corrections or such.
|
||||||
|
To add a new change log entry, please see
|
||||||
|
https://pip.pypa.io/en/latest/development/#adding-a-news-entry
|
||||||
|
we named the news folder "changes".
|
||||||
|
|
||||||
|
WARNING: Don't drop the next directive!
|
||||||
|
|
||||||
|
.. towncrier release notes start
|
||||||
|
|
||||||
|
3.7.3 (2020-11-18)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Use Brotli instead of brotlipy
|
||||||
|
`#3803 <https://github.com/aio-libs/aiohttp/issues/3803>`_
|
||||||
|
- Made exceptions pickleable. Also changed the repr of some exceptions.
|
||||||
|
`#4077 <https://github.com/aio-libs/aiohttp/issues/4077>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Raise a ClientResponseError instead of an AssertionError for a blank
|
||||||
|
HTTP Reason Phrase.
|
||||||
|
`#3532 <https://github.com/aio-libs/aiohttp/issues/3532>`_
|
||||||
|
- Fix ``web_middlewares.normalize_path_middleware`` behavior for patch without slash.
|
||||||
|
`#3669 <https://github.com/aio-libs/aiohttp/issues/3669>`_
|
||||||
|
- Fix overshadowing of overlapped sub-applications prefixes.
|
||||||
|
`#3701 <https://github.com/aio-libs/aiohttp/issues/3701>`_
|
||||||
|
- Make `BaseConnector.close()` a coroutine and wait until the client closes all connections. Drop deprecated "with Connector():" syntax.
|
||||||
|
`#3736 <https://github.com/aio-libs/aiohttp/issues/3736>`_
|
||||||
|
- Reset the ``sock_read`` timeout each time data is received for a ``aiohttp.client`` response.
|
||||||
|
`#3808 <https://github.com/aio-libs/aiohttp/issues/3808>`_
|
||||||
|
- Fixed type annotation for add_view method of UrlDispatcher to accept any subclass of View
|
||||||
|
`#3880 <https://github.com/aio-libs/aiohttp/issues/3880>`_
|
||||||
|
- Fixed querying the address families from DNS that the current host supports.
|
||||||
|
`#5156 <https://github.com/aio-libs/aiohttp/issues/5156>`_
|
||||||
|
- Change return type of MultipartReader.__aiter__() and BodyPartReader.__aiter__() to AsyncIterator.
|
||||||
|
`#5163 <https://github.com/aio-libs/aiohttp/issues/5163>`_
|
||||||
|
- Provide x86 Windows wheels.
|
||||||
|
`#5230 <https://github.com/aio-libs/aiohttp/issues/5230>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Add documentation for ``aiohttp.web.FileResponse``.
|
||||||
|
`#3958 <https://github.com/aio-libs/aiohttp/issues/3958>`_
|
||||||
|
- Removed deprecation warning in tracing example docs
|
||||||
|
`#3964 <https://github.com/aio-libs/aiohttp/issues/3964>`_
|
||||||
|
- Fixed wrong "Usage" docstring of ``aiohttp.client.request``.
|
||||||
|
`#4603 <https://github.com/aio-libs/aiohttp/issues/4603>`_
|
||||||
|
- Add aiohttp-pydantic to third party libraries
|
||||||
|
`#5228 <https://github.com/aio-libs/aiohttp/issues/5228>`_
|
||||||
|
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
- `#4102 <https://github.com/aio-libs/aiohttp/issues/4102>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.7.2 (2020-10-27)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fixed static files handling for loops without ``.sendfile()`` support
|
||||||
|
`#5149 <https://github.com/aio-libs/aiohttp/issues/5149>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.7.1 (2020-10-25)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fixed a type error caused by the conditional import of `Protocol`.
|
||||||
|
`#5111 <https://github.com/aio-libs/aiohttp/issues/5111>`_
|
||||||
|
- Server doesn't send Content-Length for 1xx or 204
|
||||||
|
`#4901 <https://github.com/aio-libs/aiohttp/issues/4901>`_
|
||||||
|
- Fix run_app typing
|
||||||
|
`#4957 <https://github.com/aio-libs/aiohttp/issues/4957>`_
|
||||||
|
- Always require ``typing_extensions`` library.
|
||||||
|
`#5107 <https://github.com/aio-libs/aiohttp/issues/5107>`_
|
||||||
|
- Fix a variable-shadowing bug causing `ThreadedResolver.resolve` to
|
||||||
|
return the resolved IP as the ``hostname`` in each record, which prevented
|
||||||
|
validation of HTTPS connections.
|
||||||
|
`#5110 <https://github.com/aio-libs/aiohttp/issues/5110>`_
|
||||||
|
- Added annotations to all public attributes.
|
||||||
|
`#5115 <https://github.com/aio-libs/aiohttp/issues/5115>`_
|
||||||
|
- Fix flaky test_when_timeout_smaller_second
|
||||||
|
`#5116 <https://github.com/aio-libs/aiohttp/issues/5116>`_
|
||||||
|
- Ensure sending a zero byte file does not throw an exception
|
||||||
|
`#5124 <https://github.com/aio-libs/aiohttp/issues/5124>`_
|
||||||
|
- Fix a bug in ``web.run_app()`` about Python version checking on Windows
|
||||||
|
`#5127 <https://github.com/aio-libs/aiohttp/issues/5127>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.7.0 (2020-10-24)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Response headers are now prepared prior to running ``on_response_prepare`` hooks, directly before headers are sent to the client.
|
||||||
|
`#1958 <https://github.com/aio-libs/aiohttp/issues/1958>`_
|
||||||
|
- Add a ``quote_cookie`` option to ``CookieJar``, a way to skip quotation wrapping of cookies containing special characters.
|
||||||
|
`#2571 <https://github.com/aio-libs/aiohttp/issues/2571>`_
|
||||||
|
- Call ``AccessLogger.log`` with the current exception available from ``sys.exc_info()``.
|
||||||
|
`#3557 <https://github.com/aio-libs/aiohttp/issues/3557>`_
|
||||||
|
- `web.UrlDispatcher.add_routes` and `web.Application.add_routes` return a list
|
||||||
|
of registered `AbstractRoute` instances. `AbstractRouteDef.register` (and all
|
||||||
|
subclasses) return a list of registered resources registered resource.
|
||||||
|
`#3866 <https://github.com/aio-libs/aiohttp/issues/3866>`_
|
||||||
|
- Added properties of default ClientSession params to ClientSession class so it is available for introspection
|
||||||
|
`#3882 <https://github.com/aio-libs/aiohttp/issues/3882>`_
|
||||||
|
- Don't cancel web handler on peer disconnection, raise `OSError` on reading/writing instead.
|
||||||
|
`#4080 <https://github.com/aio-libs/aiohttp/issues/4080>`_
|
||||||
|
- Implement BaseRequest.get_extra_info() to access a protocol transports' extra info.
|
||||||
|
`#4189 <https://github.com/aio-libs/aiohttp/issues/4189>`_
|
||||||
|
- Added `ClientSession.timeout` property.
|
||||||
|
`#4191 <https://github.com/aio-libs/aiohttp/issues/4191>`_
|
||||||
|
- allow use of SameSite in cookies.
|
||||||
|
`#4224 <https://github.com/aio-libs/aiohttp/issues/4224>`_
|
||||||
|
- Use ``loop.sendfile()`` instead of custom implementation if available.
|
||||||
|
`#4269 <https://github.com/aio-libs/aiohttp/issues/4269>`_
|
||||||
|
- Apply SO_REUSEADDR to test server's socket.
|
||||||
|
`#4393 <https://github.com/aio-libs/aiohttp/issues/4393>`_
|
||||||
|
- Use .raw_host instead of slower .host in client API
|
||||||
|
`#4402 <https://github.com/aio-libs/aiohttp/issues/4402>`_
|
||||||
|
- Allow configuring the buffer size of input stream by passing ``read_bufsize`` argument.
|
||||||
|
`#4453 <https://github.com/aio-libs/aiohttp/issues/4453>`_
|
||||||
|
- Pass tests on Python 3.8 for Windows.
|
||||||
|
`#4513 <https://github.com/aio-libs/aiohttp/issues/4513>`_
|
||||||
|
- Add `method` and `url` attributes to `TraceRequestChunkSentParams` and `TraceResponseChunkReceivedParams`.
|
||||||
|
`#4674 <https://github.com/aio-libs/aiohttp/issues/4674>`_
|
||||||
|
- Add ClientResponse.ok property for checking status code under 400.
|
||||||
|
`#4711 <https://github.com/aio-libs/aiohttp/issues/4711>`_
|
||||||
|
- Don't ceil timeouts that are smaller than 5 seconds.
|
||||||
|
`#4850 <https://github.com/aio-libs/aiohttp/issues/4850>`_
|
||||||
|
- TCPSite now listens by default on all interfaces instead of just IPv4 when `None` is passed in as the host.
|
||||||
|
`#4894 <https://github.com/aio-libs/aiohttp/issues/4894>`_
|
||||||
|
- Bump ``http_parser`` to 2.9.4
|
||||||
|
`#5070 <https://github.com/aio-libs/aiohttp/issues/5070>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix keepalive connections not being closed in time
|
||||||
|
`#3296 <https://github.com/aio-libs/aiohttp/issues/3296>`_
|
||||||
|
- Fix failed websocket handshake leaving connection hanging.
|
||||||
|
`#3380 <https://github.com/aio-libs/aiohttp/issues/3380>`_
|
||||||
|
- Fix tasks cancellation order on exit. The run_app task needs to be cancelled first for cleanup hooks to run with all tasks intact.
|
||||||
|
`#3805 <https://github.com/aio-libs/aiohttp/issues/3805>`_
|
||||||
|
- Don't start heartbeat until _writer is set
|
||||||
|
`#4062 <https://github.com/aio-libs/aiohttp/issues/4062>`_
|
||||||
|
- Fix handling of multipart file uploads without a content type.
|
||||||
|
`#4089 <https://github.com/aio-libs/aiohttp/issues/4089>`_
|
||||||
|
- Preserve view handler function attributes across middlewares
|
||||||
|
`#4174 <https://github.com/aio-libs/aiohttp/issues/4174>`_
|
||||||
|
- Fix the string representation of ``ServerDisconnectedError``.
|
||||||
|
`#4175 <https://github.com/aio-libs/aiohttp/issues/4175>`_
|
||||||
|
- Raising RuntimeError when trying to get encoding from not read body
|
||||||
|
`#4214 <https://github.com/aio-libs/aiohttp/issues/4214>`_
|
||||||
|
- Remove warning messages from noop.
|
||||||
|
`#4282 <https://github.com/aio-libs/aiohttp/issues/4282>`_
|
||||||
|
- Raise ClientPayloadError if FormData re-processed.
|
||||||
|
`#4345 <https://github.com/aio-libs/aiohttp/issues/4345>`_
|
||||||
|
- Fix a warning about unfinished task in ``web_protocol.py``
|
||||||
|
`#4408 <https://github.com/aio-libs/aiohttp/issues/4408>`_
|
||||||
|
- Fixed 'deflate' compression. According to RFC 2616 now.
|
||||||
|
`#4506 <https://github.com/aio-libs/aiohttp/issues/4506>`_
|
||||||
|
- Fixed OverflowError on platforms with 32-bit time_t
|
||||||
|
`#4515 <https://github.com/aio-libs/aiohttp/issues/4515>`_
|
||||||
|
- Fixed request.body_exists returns wrong value for methods without body.
|
||||||
|
`#4528 <https://github.com/aio-libs/aiohttp/issues/4528>`_
|
||||||
|
- Fix connecting to link-local IPv6 addresses.
|
||||||
|
`#4554 <https://github.com/aio-libs/aiohttp/issues/4554>`_
|
||||||
|
- Fix a problem with connection waiters that are never awaited.
|
||||||
|
`#4562 <https://github.com/aio-libs/aiohttp/issues/4562>`_
|
||||||
|
- Always make sure transport is not closing before reuse a connection.
|
||||||
|
|
||||||
|
Reuse a protocol based on keepalive in headers is unreliable.
|
||||||
|
For example, uWSGI will not support keepalive even it serves a
|
||||||
|
HTTP 1.1 request, except explicitly configure uWSGI with a
|
||||||
|
``--http-keepalive`` option.
|
||||||
|
|
||||||
|
Servers designed like uWSGI could cause aiohttp intermittently
|
||||||
|
raise a ConnectionResetException when the protocol poll runs
|
||||||
|
out and some protocol is reused.
|
||||||
|
`#4587 <https://github.com/aio-libs/aiohttp/issues/4587>`_
|
||||||
|
- Handle the last CRLF correctly even if it is received via separate TCP segment.
|
||||||
|
`#4630 <https://github.com/aio-libs/aiohttp/issues/4630>`_
|
||||||
|
- Fix the register_resource function to validate route name before splitting it so that route name can include python keywords.
|
||||||
|
`#4691 <https://github.com/aio-libs/aiohttp/issues/4691>`_
|
||||||
|
- Improve typing annotations for ``web.Request``, ``aiohttp.ClientResponse`` and
|
||||||
|
``multipart`` module.
|
||||||
|
`#4736 <https://github.com/aio-libs/aiohttp/issues/4736>`_
|
||||||
|
- Fix resolver task is not awaited when connector is cancelled
|
||||||
|
`#4795 <https://github.com/aio-libs/aiohttp/issues/4795>`_
|
||||||
|
- Fix a bug "Aiohttp doesn't return any error on invalid request methods"
|
||||||
|
`#4798 <https://github.com/aio-libs/aiohttp/issues/4798>`_
|
||||||
|
- Fix HEAD requests for static content.
|
||||||
|
`#4809 <https://github.com/aio-libs/aiohttp/issues/4809>`_
|
||||||
|
- Fix incorrect size calculation for memoryview
|
||||||
|
`#4890 <https://github.com/aio-libs/aiohttp/issues/4890>`_
|
||||||
|
- Add HTTPMove to _all__.
|
||||||
|
`#4897 <https://github.com/aio-libs/aiohttp/issues/4897>`_
|
||||||
|
- Fixed the type annotations in the ``tracing`` module.
|
||||||
|
`#4912 <https://github.com/aio-libs/aiohttp/issues/4912>`_
|
||||||
|
- Fix typing for multipart ``__aiter__``.
|
||||||
|
`#4931 <https://github.com/aio-libs/aiohttp/issues/4931>`_
|
||||||
|
- Fix for race condition on connections in BaseConnector that leads to exceeding the connection limit.
|
||||||
|
`#4936 <https://github.com/aio-libs/aiohttp/issues/4936>`_
|
||||||
|
- Add forced UTF-8 encoding for ``application/rdap+json`` responses.
|
||||||
|
`#4938 <https://github.com/aio-libs/aiohttp/issues/4938>`_
|
||||||
|
- Fix inconsistency between Python and C http request parsers in parsing pct-encoded URL.
|
||||||
|
`#4972 <https://github.com/aio-libs/aiohttp/issues/4972>`_
|
||||||
|
- Fix connection closing issue in HEAD request.
|
||||||
|
`#5012 <https://github.com/aio-libs/aiohttp/issues/5012>`_
|
||||||
|
- Fix type hint on BaseRunner.addresses (from ``List[str]`` to ``List[Any]``)
|
||||||
|
`#5086 <https://github.com/aio-libs/aiohttp/issues/5086>`_
|
||||||
|
- Make `web.run_app()` more responsive to Ctrl+C on Windows for Python < 3.8. It slightly
|
||||||
|
increases CPU load as a side effect.
|
||||||
|
`#5098 <https://github.com/aio-libs/aiohttp/issues/5098>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Fix example code in client quick-start
|
||||||
|
`#3376 <https://github.com/aio-libs/aiohttp/issues/3376>`_
|
||||||
|
- Updated the docs so there is no contradiction in ``ttl_dns_cache`` default value
|
||||||
|
`#3512 <https://github.com/aio-libs/aiohttp/issues/3512>`_
|
||||||
|
- Add 'Deploy with SSL' to docs.
|
||||||
|
`#4201 <https://github.com/aio-libs/aiohttp/issues/4201>`_
|
||||||
|
- Change typing of the secure argument on StreamResponse.set_cookie from ``Optional[str]`` to ``Optional[bool]``
|
||||||
|
`#4204 <https://github.com/aio-libs/aiohttp/issues/4204>`_
|
||||||
|
- Changes ``ttl_dns_cache`` type from int to Optional[int].
|
||||||
|
`#4270 <https://github.com/aio-libs/aiohttp/issues/4270>`_
|
||||||
|
- Simplify README hello word example and add a documentation page for people coming from requests.
|
||||||
|
`#4272 <https://github.com/aio-libs/aiohttp/issues/4272>`_
|
||||||
|
- Improve some code examples in the documentation involving websockets and starting a simple HTTP site with an AppRunner.
|
||||||
|
`#4285 <https://github.com/aio-libs/aiohttp/issues/4285>`_
|
||||||
|
- Fix typo in code example in Multipart docs
|
||||||
|
`#4312 <https://github.com/aio-libs/aiohttp/issues/4312>`_
|
||||||
|
- Fix code example in Multipart section.
|
||||||
|
`#4314 <https://github.com/aio-libs/aiohttp/issues/4314>`_
|
||||||
|
- Update contributing guide so new contributors read the most recent version of that guide. Update command used to create test coverage reporting.
|
||||||
|
`#4810 <https://github.com/aio-libs/aiohttp/issues/4810>`_
|
||||||
|
- Spelling: Change "canonize" to "canonicalize".
|
||||||
|
`#4986 <https://github.com/aio-libs/aiohttp/issues/4986>`_
|
||||||
|
- Add ``aiohttp-sse-client`` library to third party usage list.
|
||||||
|
`#5084 <https://github.com/aio-libs/aiohttp/issues/5084>`_
|
||||||
|
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
- `#2856 <https://github.com/aio-libs/aiohttp/issues/2856>`_, `#4218 <https://github.com/aio-libs/aiohttp/issues/4218>`_, `#4250 <https://github.com/aio-libs/aiohttp/issues/4250>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.6.3 (2020-10-12)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Pin yarl to ``<1.6.0`` to avoid buggy behavior that will be fixed by the next aiohttp
|
||||||
|
release.
|
||||||
|
|
||||||
|
3.6.2 (2019-10-09)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Made exceptions pickleable. Also changed the repr of some exceptions.
|
||||||
|
`#4077 <https://github.com/aio-libs/aiohttp/issues/4077>`_
|
||||||
|
- Use ``Iterable`` type hint instead of ``Sequence`` for ``Application`` *middleware*
|
||||||
|
parameter. `#4125 <https://github.com/aio-libs/aiohttp/issues/4125>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Reset the ``sock_read`` timeout each time data is received for a
|
||||||
|
``aiohttp.ClientResponse``. `#3808
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3808>`_
|
||||||
|
- Fix handling of expired cookies so they are not stored in CookieJar.
|
||||||
|
`#4063 <https://github.com/aio-libs/aiohttp/issues/4063>`_
|
||||||
|
- Fix misleading message in the string representation of ``ClientConnectorError``;
|
||||||
|
``self.ssl == None`` means default SSL context, not SSL disabled `#4097
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/4097>`_
|
||||||
|
- Don't clobber HTTP status when using FileResponse.
|
||||||
|
`#4106 <https://github.com/aio-libs/aiohttp/issues/4106>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Added minimal required logging configuration to logging documentation.
|
||||||
|
`#2469 <https://github.com/aio-libs/aiohttp/issues/2469>`_
|
||||||
|
- Update docs to reflect proxy support.
|
||||||
|
`#4100 <https://github.com/aio-libs/aiohttp/issues/4100>`_
|
||||||
|
- Fix typo in code example in testing docs.
|
||||||
|
`#4108 <https://github.com/aio-libs/aiohttp/issues/4108>`_
|
||||||
|
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
- `#4102 <https://github.com/aio-libs/aiohttp/issues/4102>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.6.1 (2019-09-19)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Compatibility with Python 3.8.
|
||||||
|
`#4056 <https://github.com/aio-libs/aiohttp/issues/4056>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- correct some exception string format
|
||||||
|
`#4068 <https://github.com/aio-libs/aiohttp/issues/4068>`_
|
||||||
|
- Emit a warning when ``ssl.OP_NO_COMPRESSION`` is
|
||||||
|
unavailable because the runtime is built against
|
||||||
|
an outdated OpenSSL.
|
||||||
|
`#4052 <https://github.com/aio-libs/aiohttp/issues/4052>`_
|
||||||
|
- Update multidict requirement to >= 4.5
|
||||||
|
`#4057 <https://github.com/aio-libs/aiohttp/issues/4057>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Provide pytest-aiohttp namespace for pytest fixtures in docs.
|
||||||
|
`#3723 <https://github.com/aio-libs/aiohttp/issues/3723>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.6.0 (2019-09-06)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Add support for Named Pipes (Site and Connector) under Windows. This feature requires
|
||||||
|
Proactor event loop to work. `#3629
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3629>`_
|
||||||
|
- Removed ``Transfer-Encoding: chunked`` header from websocket responses to be
|
||||||
|
compatible with more http proxy servers. `#3798
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3798>`_
|
||||||
|
- Accept non-GET request for starting websocket handshake on server side.
|
||||||
|
`#3980 <https://github.com/aio-libs/aiohttp/issues/3980>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Raise a ClientResponseError instead of an AssertionError for a blank
|
||||||
|
HTTP Reason Phrase.
|
||||||
|
`#3532 <https://github.com/aio-libs/aiohttp/issues/3532>`_
|
||||||
|
- Fix an issue where cookies would sometimes not be set during a redirect.
|
||||||
|
`#3576 <https://github.com/aio-libs/aiohttp/issues/3576>`_
|
||||||
|
- Change normalize_path_middleware to use 308 redirect instead of 301.
|
||||||
|
|
||||||
|
This behavior should prevent clients from being unable to use PUT/POST
|
||||||
|
methods on endpoints that are redirected because of a trailing slash.
|
||||||
|
`#3579 <https://github.com/aio-libs/aiohttp/issues/3579>`_
|
||||||
|
- Drop the processed task from ``all_tasks()`` list early. It prevents logging about a
|
||||||
|
task with unhandled exception when the server is used in conjunction with
|
||||||
|
``asyncio.run()``. `#3587 <https://github.com/aio-libs/aiohttp/issues/3587>`_
|
||||||
|
- ``Signal`` type annotation changed from ``Signal[Callable[['TraceConfig'],
|
||||||
|
Awaitable[None]]]`` to ``Signal[Callable[ClientSession, SimpleNamespace, ...]``.
|
||||||
|
`#3595 <https://github.com/aio-libs/aiohttp/issues/3595>`_
|
||||||
|
- Use sanitized URL as Location header in redirects
|
||||||
|
`#3614 <https://github.com/aio-libs/aiohttp/issues/3614>`_
|
||||||
|
- Improve typing annotations for multipart.py along with changes required
|
||||||
|
by mypy in files that references multipart.py.
|
||||||
|
`#3621 <https://github.com/aio-libs/aiohttp/issues/3621>`_
|
||||||
|
- Close session created inside ``aiohttp.request`` when unhandled exception occurs
|
||||||
|
`#3628 <https://github.com/aio-libs/aiohttp/issues/3628>`_
|
||||||
|
- Cleanup per-chunk data in generic data read. Memory leak fixed.
|
||||||
|
`#3631 <https://github.com/aio-libs/aiohttp/issues/3631>`_
|
||||||
|
- Use correct type for add_view and family
|
||||||
|
`#3633 <https://github.com/aio-libs/aiohttp/issues/3633>`_
|
||||||
|
- Fix _keepalive field in __slots__ of ``RequestHandler``.
|
||||||
|
`#3644 <https://github.com/aio-libs/aiohttp/issues/3644>`_
|
||||||
|
- Properly handle ConnectionResetError, to silence the "Cannot write to closing
|
||||||
|
transport" exception when clients disconnect uncleanly.
|
||||||
|
`#3648 <https://github.com/aio-libs/aiohttp/issues/3648>`_
|
||||||
|
- Suppress pytest warnings due to ``test_utils`` classes
|
||||||
|
`#3660 <https://github.com/aio-libs/aiohttp/issues/3660>`_
|
||||||
|
- Fix overshadowing of overlapped sub-application prefixes.
|
||||||
|
`#3701 <https://github.com/aio-libs/aiohttp/issues/3701>`_
|
||||||
|
- Fixed return type annotation for WSMessage.json()
|
||||||
|
`#3720 <https://github.com/aio-libs/aiohttp/issues/3720>`_
|
||||||
|
- Properly expose TooManyRedirects publicly as documented.
|
||||||
|
`#3818 <https://github.com/aio-libs/aiohttp/issues/3818>`_
|
||||||
|
- Fix missing brackets for IPv6 in proxy CONNECT request
|
||||||
|
`#3841 <https://github.com/aio-libs/aiohttp/issues/3841>`_
|
||||||
|
- Make the signature of ``aiohttp.test_utils.TestClient.request`` match
|
||||||
|
``asyncio.ClientSession.request`` according to the docs `#3852
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3852>`_
|
||||||
|
- Use correct style for re-exported imports, makes mypy ``--strict`` mode happy.
|
||||||
|
`#3868 <https://github.com/aio-libs/aiohttp/issues/3868>`_
|
||||||
|
- Fixed type annotation for add_view method of UrlDispatcher to accept any subclass of
|
||||||
|
View `#3880 <https://github.com/aio-libs/aiohttp/issues/3880>`_
|
||||||
|
- Made cython HTTP parser set Reason-Phrase of the response to an empty string if it is
|
||||||
|
missing. `#3906 <https://github.com/aio-libs/aiohttp/issues/3906>`_
|
||||||
|
- Add URL to the string representation of ClientResponseError.
|
||||||
|
`#3959 <https://github.com/aio-libs/aiohttp/issues/3959>`_
|
||||||
|
- Accept ``istr`` keys in ``LooseHeaders`` type hints.
|
||||||
|
`#3976 <https://github.com/aio-libs/aiohttp/issues/3976>`_
|
||||||
|
- Fixed race conditions in _resolve_host caching and throttling when tracing is enabled.
|
||||||
|
`#4013 <https://github.com/aio-libs/aiohttp/issues/4013>`_
|
||||||
|
- For URLs like "unix://localhost/..." set Host HTTP header to "localhost" instead of
|
||||||
|
"localhost:None". `#4039 <https://github.com/aio-libs/aiohttp/issues/4039>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Modify documentation for Background Tasks to remove deprecated usage of event loop.
|
||||||
|
`#3526 <https://github.com/aio-libs/aiohttp/issues/3526>`_
|
||||||
|
- use ``if __name__ == '__main__':`` in server examples.
|
||||||
|
`#3775 <https://github.com/aio-libs/aiohttp/issues/3775>`_
|
||||||
|
- Update documentation reference to the default access logger.
|
||||||
|
`#3783 <https://github.com/aio-libs/aiohttp/issues/3783>`_
|
||||||
|
- Improve documentation for ``web.BaseRequest.path`` and ``web.BaseRequest.raw_path``.
|
||||||
|
`#3791 <https://github.com/aio-libs/aiohttp/issues/3791>`_
|
||||||
|
- Removed deprecation warning in tracing example docs
|
||||||
|
`#3964 <https://github.com/aio-libs/aiohttp/issues/3964>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.5.4 (2019-01-12)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix stream ``.read()`` / ``.readany()`` / ``.iter_any()`` which used to return a
|
||||||
|
partial content only in case of compressed content
|
||||||
|
`#3525 <https://github.com/aio-libs/aiohttp/issues/3525>`_
|
||||||
|
|
||||||
|
|
||||||
|
3.5.3 (2019-01-10)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix type stubs for ``aiohttp.web.run_app(access_log=True)`` and fix edge case of
|
||||||
|
``access_log=True`` and the event loop being in debug mode. `#3504
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3504>`_
|
||||||
|
- Fix ``aiohttp.ClientTimeout`` type annotations to accept ``None`` for fields
|
||||||
|
`#3511 <https://github.com/aio-libs/aiohttp/issues/3511>`_
|
||||||
|
- Send custom per-request cookies even if session jar is empty
|
||||||
|
`#3515 <https://github.com/aio-libs/aiohttp/issues/3515>`_
|
||||||
|
- Restore Linux binary wheels publishing on PyPI
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.5.2 (2019-01-08)
|
||||||
|
==================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- ``FileResponse`` from ``web_fileresponse.py`` uses a ``ThreadPoolExecutor`` to work
|
||||||
|
with files asynchronously. I/O based payloads from ``payload.py`` uses a
|
||||||
|
``ThreadPoolExecutor`` to work with I/O objects asynchronously. `#3313
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3313>`_
|
||||||
|
- Internal Server Errors in plain text if the browser does not support HTML.
|
||||||
|
`#3483 <https://github.com/aio-libs/aiohttp/issues/3483>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Preserve MultipartWriter parts headers on write. Refactor the way how
|
||||||
|
``Payload.headers`` are handled. Payload instances now always have headers and
|
||||||
|
Content-Type defined. Fix Payload Content-Disposition header reset after initial
|
||||||
|
creation. `#3035 <https://github.com/aio-libs/aiohttp/issues/3035>`_
|
||||||
|
- Log suppressed exceptions in ``GunicornWebWorker``.
|
||||||
|
`#3464 <https://github.com/aio-libs/aiohttp/issues/3464>`_
|
||||||
|
- Remove wildcard imports.
|
||||||
|
`#3468 <https://github.com/aio-libs/aiohttp/issues/3468>`_
|
||||||
|
- Use the same task for app initialization and web server handling in gunicorn workers.
|
||||||
|
It allows to use Python3.7 context vars smoothly.
|
||||||
|
`#3471 <https://github.com/aio-libs/aiohttp/issues/3471>`_
|
||||||
|
- Fix handling of chunked+gzipped response when first chunk does not give uncompressed
|
||||||
|
data `#3477 <https://github.com/aio-libs/aiohttp/issues/3477>`_
|
||||||
|
- Replace ``collections.MutableMapping`` with ``collections.abc.MutableMapping`` to
|
||||||
|
avoid a deprecation warning. `#3480
|
||||||
|
<https://github.com/aio-libs/aiohttp/issues/3480>`_
|
||||||
|
- ``Payload.size`` type annotation changed from ``Optional[float]`` to
|
||||||
|
``Optional[int]``. `#3484 <https://github.com/aio-libs/aiohttp/issues/3484>`_
|
||||||
|
- Ignore done tasks when cancels pending activities on ``web.run_app`` finalization.
|
||||||
|
`#3497 <https://github.com/aio-libs/aiohttp/issues/3497>`_
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Add documentation for ``aiohttp.web.HTTPException``.
|
||||||
|
`#3490 <https://github.com/aio-libs/aiohttp/issues/3490>`_
|
||||||
|
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
- `#3487 <https://github.com/aio-libs/aiohttp/issues/3487>`_
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
3.5.1 (2018-12-24)
|
||||||
|
====================
|
||||||
|
|
||||||
|
- Fix a regression about ``ClientSession._requote_redirect_url`` modification in debug
|
||||||
|
mode.
|
||||||
|
|
||||||
|
3.5.0 (2018-12-22)
|
||||||
|
====================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- The library type annotations are checked in strict mode now.
|
||||||
|
- Add support for setting cookies for individual request (`#2387
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/2387>`_)
|
||||||
|
- Application.add_domain implementation (`#2809
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/2809>`_)
|
||||||
|
- The default ``app`` in the request returned by ``test_utils.make_mocked_request`` can
|
||||||
|
now have objects assigned to it and retrieved using the ``[]`` operator. (`#3174
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3174>`_)
|
||||||
|
- Make ``request.url`` accessible when transport is closed. (`#3177
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3177>`_)
|
||||||
|
- Add ``zlib_executor_size`` argument to ``Response`` constructor to allow compression
|
||||||
|
to run in a background executor to avoid blocking the main thread and potentially
|
||||||
|
triggering health check failures. (`#3205
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3205>`_)
|
||||||
|
- Enable users to set ``ClientTimeout`` in ``aiohttp.request`` (`#3213
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3213>`_)
|
||||||
|
- Don't raise a warning if ``NETRC`` environment variable is not set and ``~/.netrc``
|
||||||
|
file doesn't exist. (`#3267 <https://github.com/aio-libs/aiohttp/pull/3267>`_)
|
||||||
|
- Add default logging handler to web.run_app If the ``Application.debug``` flag is set
|
||||||
|
and the default logger ``aiohttp.access`` is used, access logs will now be output
|
||||||
|
using a *stderr* ``StreamHandler`` if no handlers are attached. Furthermore, if the
|
||||||
|
default logger has no log level set, the log level will be set to ``DEBUG``. (`#3324
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3324>`_)
|
||||||
|
- Add method argument to ``session.ws_connect()``. Sometimes server API requires a
|
||||||
|
different HTTP method for WebSocket connection establishment. For example, ``Docker
|
||||||
|
exec`` needs POST. (`#3378 <https://github.com/aio-libs/aiohttp/pull/3378>`_)
|
||||||
|
- Create a task per request handling. (`#3406
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3406>`_)
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Enable passing ``access_log_class`` via ``handler_args`` (`#3158
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3158>`_)
|
||||||
|
- Return empty bytes with end-of-chunk marker in empty stream reader. (`#3186
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3186>`_)
|
||||||
|
- Accept ``CIMultiDictProxy`` instances for ``headers`` argument in ``web.Response``
|
||||||
|
constructor. (`#3207 <https://github.com/aio-libs/aiohttp/pull/3207>`_)
|
||||||
|
- Don't uppercase HTTP method in parser (`#3233
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3233>`_)
|
||||||
|
- Make method match regexp RFC-7230 compliant (`#3235
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3235>`_)
|
||||||
|
- Add ``app.pre_frozen`` state to properly handle startup signals in
|
||||||
|
sub-applications. (`#3237 <https://github.com/aio-libs/aiohttp/pull/3237>`_)
|
||||||
|
- Enhanced parsing and validation of helpers.BasicAuth.decode. (`#3239
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3239>`_)
|
||||||
|
- Change imports from collections module in preparation for 3.8. (`#3258
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3258>`_)
|
||||||
|
- Ensure Host header is added first to ClientRequest to better replicate browser (`#3265
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3265>`_)
|
||||||
|
- Fix forward compatibility with Python 3.8: importing ABCs directly from the
|
||||||
|
collections module will not be supported anymore. (`#3273
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3273>`_)
|
||||||
|
- Keep the query string by ``normalize_path_middleware``. (`#3278
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3278>`_)
|
||||||
|
- Fix missing parameter ``raise_for_status`` for aiohttp.request() (`#3290
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3290>`_)
|
||||||
|
- Bracket IPv6 addresses in the HOST header (`#3304
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3304>`_)
|
||||||
|
- Fix default message for server ping and pong frames. (`#3308
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3308>`_)
|
||||||
|
- Fix tests/test_connector.py typo and tests/autobahn/server.py duplicate loop
|
||||||
|
def. (`#3337 <https://github.com/aio-libs/aiohttp/pull/3337>`_)
|
||||||
|
- Fix false-negative indicator end_of_HTTP_chunk in StreamReader.readchunk function
|
||||||
|
(`#3361 <https://github.com/aio-libs/aiohttp/pull/3361>`_)
|
||||||
|
- Release HTTP response before raising status exception (`#3364
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3364>`_)
|
||||||
|
- Fix task cancellation when ``sendfile()`` syscall is used by static file
|
||||||
|
handling. (`#3383 <https://github.com/aio-libs/aiohttp/pull/3383>`_)
|
||||||
|
- Fix stack trace for ``asyncio.TimeoutError`` which was not logged, when it is caught
|
||||||
|
in the handler. (`#3414 <https://github.com/aio-libs/aiohttp/pull/3414>`_)
|
||||||
|
|
||||||
|
|
||||||
|
Improved Documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Improve documentation of ``Application.make_handler`` parameters. (`#3152
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3152>`_)
|
||||||
|
- Fix BaseRequest.raw_headers doc. (`#3215
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3215>`_)
|
||||||
|
- Fix typo in TypeError exception reason in ``web.Application._handle`` (`#3229
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3229>`_)
|
||||||
|
- Make server access log format placeholder %b documentation reflect
|
||||||
|
behavior and docstring. (`#3307 <https://github.com/aio-libs/aiohttp/pull/3307>`_)
|
||||||
|
|
||||||
|
|
||||||
|
Deprecations and Removals
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Deprecate modification of ``session.requote_redirect_url`` (`#2278
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/2278>`_)
|
||||||
|
- Deprecate ``stream.unread_data()`` (`#3260
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3260>`_)
|
||||||
|
- Deprecated use of boolean in ``resp.enable_compression()`` (`#3318
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3318>`_)
|
||||||
|
- Encourage creation of aiohttp public objects inside a coroutine (`#3331
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3331>`_)
|
||||||
|
- Drop dead ``Connection.detach()`` and ``Connection.writer``. Both methods were broken
|
||||||
|
for more than 2 years. (`#3358 <https://github.com/aio-libs/aiohttp/pull/3358>`_)
|
||||||
|
- Deprecate ``app.loop``, ``request.loop``, ``client.loop`` and ``connector.loop``
|
||||||
|
properties. (`#3374 <https://github.com/aio-libs/aiohttp/pull/3374>`_)
|
||||||
|
- Deprecate explicit debug argument. Use asyncio debug mode instead. (`#3381
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3381>`_)
|
||||||
|
- Deprecate body parameter in HTTPException (and derived classes) constructor. (`#3385
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3385>`_)
|
||||||
|
- Deprecate bare connector close, use ``async with connector:`` and ``await
|
||||||
|
connector.close()`` instead. (`#3417
|
||||||
|
<https://github.com/aio-libs/aiohttp/pull/3417>`_)
|
||||||
|
- Deprecate obsolete ``read_timeout`` and ``conn_timeout`` in ``ClientSession``
|
||||||
|
constructor. (`#3438 <https://github.com/aio-libs/aiohttp/pull/3438>`_)
|
||||||
|
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
|
||||||
|
- #3341, #3351
|
||||||
|
|
136
venv/lib/python3.8/site-packages/aiohttp-3.7.3.dist-info/RECORD
Normal file
136
venv/lib/python3.8/site-packages/aiohttp-3.7.3.dist-info/RECORD
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
aiohttp-3.7.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||||
|
aiohttp-3.7.3.dist-info/LICENSE.txt,sha256=lmJ77QrQjpsu-p9OBOgIN80FUOdpSg_sM7HaslUCgqs,11321
|
||||||
|
aiohttp-3.7.3.dist-info/METADATA,sha256=gOf5MNle3SdwZffeO0Xm7xPKnGZDIgLlm-Jpn_lUeJ8,37657
|
||||||
|
aiohttp-3.7.3.dist-info/RECORD,,
|
||||||
|
aiohttp-3.7.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
|
aiohttp-3.7.3.dist-info/WHEEL,sha256=Ylm15sSUid92cdFeaRwBWqFPNU1PmetXIVrYmRl82M8,110
|
||||||
|
aiohttp-3.7.3.dist-info/top_level.txt,sha256=iv-JIaacmTl-hSho3QmphcKnbRRYx1st47yjz_178Ro,8
|
||||||
|
aiohttp/.hash/_cparser.pxd.hash,sha256=g9ydcacNvFizu1GVl--RrXpWlSawIZ-fN050i7iUo5c,64
|
||||||
|
aiohttp/.hash/_find_header.pxd.hash,sha256=BtbSPeZ2eOtt807jecTkoEeBQ4C5AiBxjzbvJj9eV6E,64
|
||||||
|
aiohttp/.hash/_frozenlist.pyx.hash,sha256=hmgKZnSvKFUnUuT9uCV7orAxYP6Js40SN70NrDWjDmI,64
|
||||||
|
aiohttp/.hash/_helpers.pyi.hash,sha256=pvlsQIMFVemm4rvS1BkQkfS2PGgJn5ZO2RmMSFxwCiE,64
|
||||||
|
aiohttp/.hash/_helpers.pyx.hash,sha256=JWBqptE_5nbmOzG3dYXdmEuAy_Y2snJfcR124T4TZpo,64
|
||||||
|
aiohttp/.hash/_http_parser.pyx.hash,sha256=qP5I4Mu5pXc_3aDx2RSPfN2j1akQ-szA5D269nw_Sxw,64
|
||||||
|
aiohttp/.hash/_http_writer.pyx.hash,sha256=CFBO14jclGTimiln6e8yXnfWwk-4s_ylld3lE6JrnY8,64
|
||||||
|
aiohttp/.hash/_websocket.pyx.hash,sha256=_6cqIcIQjICfniPJShOdspzQaB95Lu6cinOZJ6yESz8,64
|
||||||
|
aiohttp/.hash/frozenlist.pyi.hash,sha256=021hwHbk-0EfQ2c5mefxSctfrrvJ7CnQ0mPXYTBGJ4o,64
|
||||||
|
aiohttp/.hash/hdrs.py.hash,sha256=T8i1rURdD81PR6t5qOA05Lg3yV6C9Mm4LTjJucc36yA,64
|
||||||
|
aiohttp/.hash/signals.pyi.hash,sha256=GQA2kFtF7PaBpEJDZ6OpBpFaMhi_2ieNF7HaxYDmKQQ,64
|
||||||
|
aiohttp/__init__.py,sha256=ZUhHxtrrSa6HOMIYymRaLR2PaowfDWL5F4xiycUs2KM,6934
|
||||||
|
aiohttp/__pycache__/__init__.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/abc.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/base_protocol.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/client.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/client_exceptions.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/client_proto.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/client_reqrep.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/client_ws.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/connector.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/cookiejar.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/formdata.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/frozenlist.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/hdrs.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/helpers.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/http.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/http_exceptions.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/http_parser.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/http_websocket.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/http_writer.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/locks.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/log.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/multipart.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/payload.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/payload_streamer.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/pytest_plugin.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/resolver.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/signals.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/streams.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/tcp_helpers.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/test_utils.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/tracing.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/typedefs.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_app.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_exceptions.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_fileresponse.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_log.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_middlewares.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_protocol.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_request.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_response.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_routedef.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_runner.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_server.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_urldispatcher.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/web_ws.cpython-38.pyc,,
|
||||||
|
aiohttp/__pycache__/worker.cpython-38.pyc,,
|
||||||
|
aiohttp/_cparser.pxd,sha256=tgw30SL6kQSczzGMlMhx2Cuhf_O8P8ZPimVCb85xILc,3959
|
||||||
|
aiohttp/_find_header.c,sha256=s8Urnxv8CDd2NuKCEzCsLWy4NbVFXfLMNlg-s2bCg3A,187570
|
||||||
|
aiohttp/_find_header.h,sha256=5oOgQ85nF6V7rpU8NhyE5vyGkTo1Cgf1GIYrtxSTzQI,170
|
||||||
|
aiohttp/_find_header.pxd,sha256=0GfwFCPN2zxEKTO1_MA5sYq2UfzsG8kcV3aTqvwlz3g,68
|
||||||
|
aiohttp/_frozenlist.c,sha256=4m7L0I0wWumfGoXIMaYYeKxf9zG3ssoIxB-meEQDgh4,294193
|
||||||
|
aiohttp/_frozenlist.cpython-38-darwin.so,sha256=FEbt_c4enFq7lRad6Qfqfq_Q1ScIdbFhy_dbEsYw5i0,92520
|
||||||
|
aiohttp/_frozenlist.pyx,sha256=BD8LcERExsWdo4qzuuQ84f-L_pHVzkUQO0lEAOe3Fog,2605
|
||||||
|
aiohttp/_headers.pxi,sha256=n701k28dVPjwRnx5j6LpJhLTfj7dqu2vJt7f0O60Oyg,2007
|
||||||
|
aiohttp/_helpers.c,sha256=meXX95gKMrawWPUl-q3Sdyf4VxSdsH-8lbCON6-ATOo,211989
|
||||||
|
aiohttp/_helpers.cpython-38-darwin.so,sha256=pFBgEyfMVbLj-Xhw5xLYF7S3YtjG5T8CS3jfpYaJPxA,68192
|
||||||
|
aiohttp/_helpers.pyi,sha256=ZoKiJSS51PxELhI2cmIr5737YjjZcJt7FbIRO3ym1Ss,202
|
||||||
|
aiohttp/_helpers.pyx,sha256=XeLbNft5X_4ifi8QB8i6TyrRuayijMSO3IDHeSA89uM,1049
|
||||||
|
aiohttp/_http_parser.c,sha256=O51TiHCn0eXUeiBWCyl7E7y-JjZLgeLRj10D18HudSU,1011524
|
||||||
|
aiohttp/_http_parser.cpython-38-darwin.so,sha256=Fjesva-a5qu5VIl_BQyD2KFQPzPJvDzTv_GayRmCmeM,497480
|
||||||
|
aiohttp/_http_parser.pyx,sha256=8GiPsugeqSvwoXgiJg2VkaMJeRAdoSpLhzET_EWftfo,29022
|
||||||
|
aiohttp/_http_writer.c,sha256=QxJ09pt3guD8aVsQ7LaAxX4vxBUhJ7RhxeVMVWu8BUk,213020
|
||||||
|
aiohttp/_http_writer.cpython-38-darwin.so,sha256=eY6IoHwoSfNTpKXsfBeF8N364xQwDDov9bwPoZKVzfU,62928
|
||||||
|
aiohttp/_http_writer.pyx,sha256=Tnt_e6pcZZVOhaW3yNt3hqDsNJgIGwqUIPeSqAMIYoE,4200
|
||||||
|
aiohttp/_websocket.c,sha256=F5V1i__yewPzFcgYKmcTWk_CjptCZUYlhQesX14u4ec,137427
|
||||||
|
aiohttp/_websocket.cpython-38-darwin.so,sha256=dSgTXjkUuKeH2HTEmhl0wXyct9R-LAxhRE0xoOSUq2E,43696
|
||||||
|
aiohttp/_websocket.pyx,sha256=1XuOSNDCbyDrzF5uMA2isqausSs8l2jWTLDlNDLM9Io,1561
|
||||||
|
aiohttp/abc.py,sha256=tbhrXunYB8-Jmq3-e6zbYtXaCR7Vfb8eRo4Ifk-juLQ,5247
|
||||||
|
aiohttp/base_protocol.py,sha256=eNgmzKP-Lbh5vxSmShDBKTJ0JSAVpcrAZa-EKqmCTKA,2701
|
||||||
|
aiohttp/client.py,sha256=9firS0XBuNEGshPE81CsmLxnkfkZoJsRUV6amoGZ1FA,43916
|
||||||
|
aiohttp/client_exceptions.py,sha256=fW2rrDEcWitwpXhQIFtViuC2JEHDx1oIXXQsj6YGd5I,8529
|
||||||
|
aiohttp/client_proto.py,sha256=Iek_ZuTr_2xFoKt30zveOBh1xYt6iXE7XZVwUPiCXTs,8163
|
||||||
|
aiohttp/client_reqrep.py,sha256=okBWp3TC_leAiD0-kEtS8H0v8fZPTSVzyDXDwusSZrs,36439
|
||||||
|
aiohttp/client_ws.py,sha256=sxkvG5Vw37Mr6V_8w9WZ0ulo_jKL_tRtSK1l9bRIPlY,10287
|
||||||
|
aiohttp/connector.py,sha256=9A8wGKGoOXZCzRUBnw2dwT457aWXAxFSn4fPaEK5Lh8,42968
|
||||||
|
aiohttp/cookiejar.py,sha256=SbX_n44bl69PrGIPOmj2imHwynzBlUbxrZUe16T3K-4,12163
|
||||||
|
aiohttp/formdata.py,sha256=UJ4DgqX4Jk-LZpnKOeOCUewL5264eO4DyHPKOk5vgos,6080
|
||||||
|
aiohttp/frozenlist.py,sha256=nFqoDVmyxfStqiY_FxcrME8GpvhRDXf3mh-BGCVxhnQ,1718
|
||||||
|
aiohttp/frozenlist.pyi,sha256=bRNKoI2j1roPdtgfx_nseDanvBqZsZUNHDqmXtfjlRo,1434
|
||||||
|
aiohttp/hdrs.py,sha256=WsjDJYADYEyJk7-oNXNhA2M3MwtyLkhJAklyzLtclfU,3446
|
||||||
|
aiohttp/helpers.py,sha256=iAQNQGGoqN8ovgdMfHC2rggYSbOaSTToiUJqg1LJrzw,22918
|
||||||
|
aiohttp/http.py,sha256=CHdBKhli7yITl_VfpBDdjgF6nT_cCWPRXov8UzBeo2k,1824
|
||||||
|
aiohttp/http_exceptions.py,sha256=eACQt7azwNbUi8aqXB5J2tIcc_CB4_4y4mLM9SZd4tM,2586
|
||||||
|
aiohttp/http_parser.py,sha256=qtbVGSae1ny9BftziBkx3N02cd5wZXZYb3FNrRfjfcc,30224
|
||||||
|
aiohttp/http_websocket.py,sha256=k_mvpvQUsliv7F7ZlXmz01hzBnoysSHAr4KyZDC-O78,25098
|
||||||
|
aiohttp/http_writer.py,sha256=ofDAEH8IJry013XsbrrfNiV82Fr7Gs3d7syduMx1vYU,5341
|
||||||
|
aiohttp/locks.py,sha256=j5VO5HkQY_N5DRJAezRJXavE9y2N9Y9Sq3oWu8ftAOA,1220
|
||||||
|
aiohttp/log.py,sha256=BbNKx9e3VMIm0xYjZI0IcBBoS7wjdeIeSaiJE7-qK2g,325
|
||||||
|
aiohttp/multipart.py,sha256=ZrChyWL811TpsxcL0rcmx3VIJjzj-cINkrjgk9GhBt4,32251
|
||||||
|
aiohttp/payload.py,sha256=jvvuncmzh4RuHUR05srhzSMXCUCxclUPgFnEDm1vl40,13333
|
||||||
|
aiohttp/payload_streamer.py,sha256=qW8jvfRJYYnpRro74vQbrTXFd_5JZsHyVGi4-bulOwo,2102
|
||||||
|
aiohttp/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7
|
||||||
|
aiohttp/pytest_plugin.py,sha256=0z5FACR9mUEZp72jakz_jfDuy-dsmv2HISIY0EB01K4,11009
|
||||||
|
aiohttp/resolver.py,sha256=VmUmtY_mjuRQCy4OrByS74bgooPzUeHrO_pEUPaMXc4,4608
|
||||||
|
aiohttp/signals.py,sha256=YSWNpNheFirmccC7vWMr8J1TDWBN_P0m3Ch_FiZ3HVA,852
|
||||||
|
aiohttp/signals.pyi,sha256=SLTfUPdx1-g4VSTqCnBXyhSCl0-KQ-Z0mCsEsIvBfV4,319
|
||||||
|
aiohttp/streams.py,sha256=zmCpGESe27u2b-JmyOem_FThgOn9Iq_TpwIHJMjJfmY,20530
|
||||||
|
aiohttp/tcp_helpers.py,sha256=l3XD9wWiuMawXCMdqiNSRHIz0iVtMKi7lwqXnHvyK3k,962
|
||||||
|
aiohttp/test_utils.py,sha256=NG7YcgAE_E7LOlcaNQ8JhgOadhg5bg174-tukUQLDMA,20253
|
||||||
|
aiohttp/tracing.py,sha256=-G2cfF6LNFqY8nCbnHJ8NkLdnJV1WSjRtKOnJ1gz_lw,14363
|
||||||
|
aiohttp/typedefs.py,sha256=PUsJ7Y-f8bRqyDOdqd681VvaNi_LETRJ5L7rCPfPRN4,1374
|
||||||
|
aiohttp/web.py,sha256=WNOEIih5I3g_0BSIJkrKvWuTQ8qZVKoGkjg-v6wcSms,17881
|
||||||
|
aiohttp/web_app.py,sha256=lDfoKwy1y8_pnMkrqcfHiMnhWwH_4FCkCuSMLT4huA0,17053
|
||||||
|
aiohttp/web_exceptions.py,sha256=-ZqN_zv7EiaLDS0Na5IpgXmiiNv9QZm8sebYoW3zeYc,10106
|
||||||
|
aiohttp/web_fileresponse.py,sha256=hpzBp-L-VuVrlsSjoTvGRWpgWZrLODkaoQlGCNQrpag,9025
|
||||||
|
aiohttp/web_log.py,sha256=hDwnH_USBiNqC1-XggEorcuVQUuKhEezCfjPY1wkac4,7498
|
||||||
|
aiohttp/web_middlewares.py,sha256=QB-wcNt4KSFz4WHUQayvPp56VNgqIYMPQbAHjgaABiE,4111
|
||||||
|
aiohttp/web_protocol.py,sha256=2nHNxxg7Mf8ZP88SFPxnBNGL8zmPhQpjtZ68VT0PeIo,23251
|
||||||
|
aiohttp/web_request.py,sha256=fY-GmGuV3oayr5r0Szd1VsHraN8T-uW2wCij6iFfZOg,26454
|
||||||
|
aiohttp/web_response.py,sha256=Xb9PfJhFHzu9Od4qHRmN9O6z5ojBRuL0ETqmR6S_8Ek,26202
|
||||||
|
aiohttp/web_routedef.py,sha256=PIHf5KvaOnG30pg1J8IhZewoHLOEMd5emWBZBBWS9yE,6109
|
||||||
|
aiohttp/web_runner.py,sha256=4AM4y6lgmCxBU1AHt1Sdd7IpB4pm9dWqSdapNfgzqG8,11194
|
||||||
|
aiohttp/web_server.py,sha256=Zp-StXkTSDZ8Lyg2joDdRD05QRu9oh8LET3AKfx9D2I,2058
|
||||||
|
aiohttp/web_urldispatcher.py,sha256=M930z-C2umyGyU4KmGVsabJNL5ZpT6Aj5tpSf6mSSPc,39532
|
||||||
|
aiohttp/web_ws.py,sha256=f912oImpu973icUK0QUjeXIxa57R837gdkUUn1ZnSpQ,16783
|
||||||
|
aiohttp/worker.py,sha256=T1CvPYNP4rqsdpyz3dNRuqNF5bzrH3WaEdDMLDsfLOc,8022
|
|
@ -0,0 +1,5 @@
|
||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: bdist_wheel (0.35.1)
|
||||||
|
Root-Is-Purelib: false
|
||||||
|
Tag: cp38-cp38-macosx_10_14_x86_64
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
aiohttp
|
|
@ -0,0 +1 @@
|
||||||
|
b60c37d122fa91049ccf318c94c871d82ba17ff3bc3fc64f8a65426fce7120b7
|
|
@ -0,0 +1 @@
|
||||||
|
d067f01423cddb3c442933b5fcc039b18ab651fcec1bc91c577693aafc25cf78
|
|
@ -0,0 +1 @@
|
||||||
|
043f0b704444c6c59da38ab3bae43ce1ff8bfe91d5ce45103b494400e7b71688
|
|
@ -0,0 +1 @@
|
||||||
|
6682a22524b9d4fc442e123672622be7bdfb6238d9709b7b15b2113b7ca6d52b
|
|
@ -0,0 +1 @@
|
||||||
|
5de2db35fb795ffe227e2f1007c8ba4f2ad1b9aca28cc48edc80c779203cf6e3
|
|
@ -0,0 +1 @@
|
||||||
|
f0688fb2e81ea92bf0a17822260d9591a30979101da12a4b873113fc459fb5fa
|
|
@ -0,0 +1 @@
|
||||||
|
4e7b7f7baa5c65954e85a5b7c8db7786a0ec3498081b0a9420f792a803086281
|
|
@ -0,0 +1 @@
|
||||||
|
d57b8e48d0c26f20ebcc5e6e300da2b2a6aeb12b3c9768d64cb0e53432ccf48a
|
|
@ -0,0 +1 @@
|
||||||
|
6d134aa08da3d6ba0f76d81fc7f9ec7836a7bc1a99b1950d1c3aa65ed7e3951a
|
|
@ -0,0 +1 @@
|
||||||
|
5ac8c3258003604c8993bfa8357361036337330b722e4849024972ccbb5c95f5
|
|
@ -0,0 +1 @@
|
||||||
|
48b4df50f771d7e8385524ea0a7057ca1482974f8a43e674982b04b08bc17d5e
|
217
venv/lib/python3.8/site-packages/aiohttp/__init__.py
Normal file
217
venv/lib/python3.8/site-packages/aiohttp/__init__.py
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
__version__ = "3.7.3"
|
||||||
|
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
from . import hdrs as hdrs
|
||||||
|
from .client import (
|
||||||
|
BaseConnector as BaseConnector,
|
||||||
|
ClientConnectionError as ClientConnectionError,
|
||||||
|
ClientConnectorCertificateError as ClientConnectorCertificateError,
|
||||||
|
ClientConnectorError as ClientConnectorError,
|
||||||
|
ClientConnectorSSLError as ClientConnectorSSLError,
|
||||||
|
ClientError as ClientError,
|
||||||
|
ClientHttpProxyError as ClientHttpProxyError,
|
||||||
|
ClientOSError as ClientOSError,
|
||||||
|
ClientPayloadError as ClientPayloadError,
|
||||||
|
ClientProxyConnectionError as ClientProxyConnectionError,
|
||||||
|
ClientRequest as ClientRequest,
|
||||||
|
ClientResponse as ClientResponse,
|
||||||
|
ClientResponseError as ClientResponseError,
|
||||||
|
ClientSession as ClientSession,
|
||||||
|
ClientSSLError as ClientSSLError,
|
||||||
|
ClientTimeout as ClientTimeout,
|
||||||
|
ClientWebSocketResponse as ClientWebSocketResponse,
|
||||||
|
ContentTypeError as ContentTypeError,
|
||||||
|
Fingerprint as Fingerprint,
|
||||||
|
InvalidURL as InvalidURL,
|
||||||
|
NamedPipeConnector as NamedPipeConnector,
|
||||||
|
RequestInfo as RequestInfo,
|
||||||
|
ServerConnectionError as ServerConnectionError,
|
||||||
|
ServerDisconnectedError as ServerDisconnectedError,
|
||||||
|
ServerFingerprintMismatch as ServerFingerprintMismatch,
|
||||||
|
ServerTimeoutError as ServerTimeoutError,
|
||||||
|
TCPConnector as TCPConnector,
|
||||||
|
TooManyRedirects as TooManyRedirects,
|
||||||
|
UnixConnector as UnixConnector,
|
||||||
|
WSServerHandshakeError as WSServerHandshakeError,
|
||||||
|
request as request,
|
||||||
|
)
|
||||||
|
from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar
|
||||||
|
from .formdata import FormData as FormData
|
||||||
|
from .helpers import BasicAuth as BasicAuth, ChainMapProxy as ChainMapProxy
|
||||||
|
from .http import (
|
||||||
|
HttpVersion as HttpVersion,
|
||||||
|
HttpVersion10 as HttpVersion10,
|
||||||
|
HttpVersion11 as HttpVersion11,
|
||||||
|
WebSocketError as WebSocketError,
|
||||||
|
WSCloseCode as WSCloseCode,
|
||||||
|
WSMessage as WSMessage,
|
||||||
|
WSMsgType as WSMsgType,
|
||||||
|
)
|
||||||
|
from .multipart import (
|
||||||
|
BadContentDispositionHeader as BadContentDispositionHeader,
|
||||||
|
BadContentDispositionParam as BadContentDispositionParam,
|
||||||
|
BodyPartReader as BodyPartReader,
|
||||||
|
MultipartReader as MultipartReader,
|
||||||
|
MultipartWriter as MultipartWriter,
|
||||||
|
content_disposition_filename as content_disposition_filename,
|
||||||
|
parse_content_disposition as parse_content_disposition,
|
||||||
|
)
|
||||||
|
from .payload import (
|
||||||
|
PAYLOAD_REGISTRY as PAYLOAD_REGISTRY,
|
||||||
|
AsyncIterablePayload as AsyncIterablePayload,
|
||||||
|
BufferedReaderPayload as BufferedReaderPayload,
|
||||||
|
BytesIOPayload as BytesIOPayload,
|
||||||
|
BytesPayload as BytesPayload,
|
||||||
|
IOBasePayload as IOBasePayload,
|
||||||
|
JsonPayload as JsonPayload,
|
||||||
|
Payload as Payload,
|
||||||
|
StringIOPayload as StringIOPayload,
|
||||||
|
StringPayload as StringPayload,
|
||||||
|
TextIOPayload as TextIOPayload,
|
||||||
|
get_payload as get_payload,
|
||||||
|
payload_type as payload_type,
|
||||||
|
)
|
||||||
|
from .payload_streamer import streamer as streamer
|
||||||
|
from .resolver import (
|
||||||
|
AsyncResolver as AsyncResolver,
|
||||||
|
DefaultResolver as DefaultResolver,
|
||||||
|
ThreadedResolver as ThreadedResolver,
|
||||||
|
)
|
||||||
|
from .signals import Signal as Signal
|
||||||
|
from .streams import (
|
||||||
|
EMPTY_PAYLOAD as EMPTY_PAYLOAD,
|
||||||
|
DataQueue as DataQueue,
|
||||||
|
EofStream as EofStream,
|
||||||
|
FlowControlDataQueue as FlowControlDataQueue,
|
||||||
|
StreamReader as StreamReader,
|
||||||
|
)
|
||||||
|
from .tracing import (
|
||||||
|
TraceConfig as TraceConfig,
|
||||||
|
TraceConnectionCreateEndParams as TraceConnectionCreateEndParams,
|
||||||
|
TraceConnectionCreateStartParams as TraceConnectionCreateStartParams,
|
||||||
|
TraceConnectionQueuedEndParams as TraceConnectionQueuedEndParams,
|
||||||
|
TraceConnectionQueuedStartParams as TraceConnectionQueuedStartParams,
|
||||||
|
TraceConnectionReuseconnParams as TraceConnectionReuseconnParams,
|
||||||
|
TraceDnsCacheHitParams as TraceDnsCacheHitParams,
|
||||||
|
TraceDnsCacheMissParams as TraceDnsCacheMissParams,
|
||||||
|
TraceDnsResolveHostEndParams as TraceDnsResolveHostEndParams,
|
||||||
|
TraceDnsResolveHostStartParams as TraceDnsResolveHostStartParams,
|
||||||
|
TraceRequestChunkSentParams as TraceRequestChunkSentParams,
|
||||||
|
TraceRequestEndParams as TraceRequestEndParams,
|
||||||
|
TraceRequestExceptionParams as TraceRequestExceptionParams,
|
||||||
|
TraceRequestRedirectParams as TraceRequestRedirectParams,
|
||||||
|
TraceRequestStartParams as TraceRequestStartParams,
|
||||||
|
TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__: Tuple[str, ...] = (
|
||||||
|
"hdrs",
|
||||||
|
# client
|
||||||
|
"BaseConnector",
|
||||||
|
"ClientConnectionError",
|
||||||
|
"ClientConnectorCertificateError",
|
||||||
|
"ClientConnectorError",
|
||||||
|
"ClientConnectorSSLError",
|
||||||
|
"ClientError",
|
||||||
|
"ClientHttpProxyError",
|
||||||
|
"ClientOSError",
|
||||||
|
"ClientPayloadError",
|
||||||
|
"ClientProxyConnectionError",
|
||||||
|
"ClientResponse",
|
||||||
|
"ClientRequest",
|
||||||
|
"ClientResponseError",
|
||||||
|
"ClientSSLError",
|
||||||
|
"ClientSession",
|
||||||
|
"ClientTimeout",
|
||||||
|
"ClientWebSocketResponse",
|
||||||
|
"ContentTypeError",
|
||||||
|
"Fingerprint",
|
||||||
|
"InvalidURL",
|
||||||
|
"RequestInfo",
|
||||||
|
"ServerConnectionError",
|
||||||
|
"ServerDisconnectedError",
|
||||||
|
"ServerFingerprintMismatch",
|
||||||
|
"ServerTimeoutError",
|
||||||
|
"TCPConnector",
|
||||||
|
"TooManyRedirects",
|
||||||
|
"UnixConnector",
|
||||||
|
"NamedPipeConnector",
|
||||||
|
"WSServerHandshakeError",
|
||||||
|
"request",
|
||||||
|
# cookiejar
|
||||||
|
"CookieJar",
|
||||||
|
"DummyCookieJar",
|
||||||
|
# formdata
|
||||||
|
"FormData",
|
||||||
|
# helpers
|
||||||
|
"BasicAuth",
|
||||||
|
"ChainMapProxy",
|
||||||
|
# http
|
||||||
|
"HttpVersion",
|
||||||
|
"HttpVersion10",
|
||||||
|
"HttpVersion11",
|
||||||
|
"WSMsgType",
|
||||||
|
"WSCloseCode",
|
||||||
|
"WSMessage",
|
||||||
|
"WebSocketError",
|
||||||
|
# multipart
|
||||||
|
"BadContentDispositionHeader",
|
||||||
|
"BadContentDispositionParam",
|
||||||
|
"BodyPartReader",
|
||||||
|
"MultipartReader",
|
||||||
|
"MultipartWriter",
|
||||||
|
"content_disposition_filename",
|
||||||
|
"parse_content_disposition",
|
||||||
|
# payload
|
||||||
|
"AsyncIterablePayload",
|
||||||
|
"BufferedReaderPayload",
|
||||||
|
"BytesIOPayload",
|
||||||
|
"BytesPayload",
|
||||||
|
"IOBasePayload",
|
||||||
|
"JsonPayload",
|
||||||
|
"PAYLOAD_REGISTRY",
|
||||||
|
"Payload",
|
||||||
|
"StringIOPayload",
|
||||||
|
"StringPayload",
|
||||||
|
"TextIOPayload",
|
||||||
|
"get_payload",
|
||||||
|
"payload_type",
|
||||||
|
# payload_streamer
|
||||||
|
"streamer",
|
||||||
|
# resolver
|
||||||
|
"AsyncResolver",
|
||||||
|
"DefaultResolver",
|
||||||
|
"ThreadedResolver",
|
||||||
|
# signals
|
||||||
|
"Signal",
|
||||||
|
"DataQueue",
|
||||||
|
"EMPTY_PAYLOAD",
|
||||||
|
"EofStream",
|
||||||
|
"FlowControlDataQueue",
|
||||||
|
"StreamReader",
|
||||||
|
# tracing
|
||||||
|
"TraceConfig",
|
||||||
|
"TraceConnectionCreateEndParams",
|
||||||
|
"TraceConnectionCreateStartParams",
|
||||||
|
"TraceConnectionQueuedEndParams",
|
||||||
|
"TraceConnectionQueuedStartParams",
|
||||||
|
"TraceConnectionReuseconnParams",
|
||||||
|
"TraceDnsCacheHitParams",
|
||||||
|
"TraceDnsCacheMissParams",
|
||||||
|
"TraceDnsResolveHostEndParams",
|
||||||
|
"TraceDnsResolveHostStartParams",
|
||||||
|
"TraceRequestChunkSentParams",
|
||||||
|
"TraceRequestEndParams",
|
||||||
|
"TraceRequestExceptionParams",
|
||||||
|
"TraceRequestRedirectParams",
|
||||||
|
"TraceRequestStartParams",
|
||||||
|
"TraceResponseChunkReceivedParams",
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from .worker import GunicornUVLoopWebWorker, GunicornWebWorker
|
||||||
|
|
||||||
|
__all__ += ("GunicornWebWorker", "GunicornUVLoopWebWorker")
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
pass
|
140
venv/lib/python3.8/site-packages/aiohttp/_cparser.pxd
Normal file
140
venv/lib/python3.8/site-packages/aiohttp/_cparser.pxd
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
from libc.stdint cimport uint16_t, uint32_t, uint64_t
|
||||||
|
|
||||||
|
|
||||||
|
cdef extern from "../vendor/http-parser/http_parser.h":
|
||||||
|
ctypedef int (*http_data_cb) (http_parser*,
|
||||||
|
const char *at,
|
||||||
|
size_t length) except -1
|
||||||
|
|
||||||
|
ctypedef int (*http_cb) (http_parser*) except -1
|
||||||
|
|
||||||
|
struct http_parser:
|
||||||
|
unsigned int type
|
||||||
|
unsigned int flags
|
||||||
|
unsigned int state
|
||||||
|
unsigned int header_state
|
||||||
|
unsigned int index
|
||||||
|
|
||||||
|
uint32_t nread
|
||||||
|
uint64_t content_length
|
||||||
|
|
||||||
|
unsigned short http_major
|
||||||
|
unsigned short http_minor
|
||||||
|
unsigned int status_code
|
||||||
|
unsigned int method
|
||||||
|
unsigned int http_errno
|
||||||
|
|
||||||
|
unsigned int upgrade
|
||||||
|
|
||||||
|
void *data
|
||||||
|
|
||||||
|
struct http_parser_settings:
|
||||||
|
http_cb on_message_begin
|
||||||
|
http_data_cb on_url
|
||||||
|
http_data_cb on_status
|
||||||
|
http_data_cb on_header_field
|
||||||
|
http_data_cb on_header_value
|
||||||
|
http_cb on_headers_complete
|
||||||
|
http_data_cb on_body
|
||||||
|
http_cb on_message_complete
|
||||||
|
http_cb on_chunk_header
|
||||||
|
http_cb on_chunk_complete
|
||||||
|
|
||||||
|
enum http_parser_type:
|
||||||
|
HTTP_REQUEST,
|
||||||
|
HTTP_RESPONSE,
|
||||||
|
HTTP_BOTH
|
||||||
|
|
||||||
|
enum http_errno:
|
||||||
|
HPE_OK,
|
||||||
|
HPE_CB_message_begin,
|
||||||
|
HPE_CB_url,
|
||||||
|
HPE_CB_header_field,
|
||||||
|
HPE_CB_header_value,
|
||||||
|
HPE_CB_headers_complete,
|
||||||
|
HPE_CB_body,
|
||||||
|
HPE_CB_message_complete,
|
||||||
|
HPE_CB_status,
|
||||||
|
HPE_CB_chunk_header,
|
||||||
|
HPE_CB_chunk_complete,
|
||||||
|
HPE_INVALID_EOF_STATE,
|
||||||
|
HPE_HEADER_OVERFLOW,
|
||||||
|
HPE_CLOSED_CONNECTION,
|
||||||
|
HPE_INVALID_VERSION,
|
||||||
|
HPE_INVALID_STATUS,
|
||||||
|
HPE_INVALID_METHOD,
|
||||||
|
HPE_INVALID_URL,
|
||||||
|
HPE_INVALID_HOST,
|
||||||
|
HPE_INVALID_PORT,
|
||||||
|
HPE_INVALID_PATH,
|
||||||
|
HPE_INVALID_QUERY_STRING,
|
||||||
|
HPE_INVALID_FRAGMENT,
|
||||||
|
HPE_LF_EXPECTED,
|
||||||
|
HPE_INVALID_HEADER_TOKEN,
|
||||||
|
HPE_INVALID_CONTENT_LENGTH,
|
||||||
|
HPE_INVALID_CHUNK_SIZE,
|
||||||
|
HPE_INVALID_CONSTANT,
|
||||||
|
HPE_INVALID_INTERNAL_STATE,
|
||||||
|
HPE_STRICT,
|
||||||
|
HPE_PAUSED,
|
||||||
|
HPE_UNKNOWN
|
||||||
|
|
||||||
|
enum flags:
|
||||||
|
F_CHUNKED,
|
||||||
|
F_CONNECTION_KEEP_ALIVE,
|
||||||
|
F_CONNECTION_CLOSE,
|
||||||
|
F_CONNECTION_UPGRADE,
|
||||||
|
F_TRAILING,
|
||||||
|
F_UPGRADE,
|
||||||
|
F_SKIPBODY,
|
||||||
|
F_CONTENTLENGTH
|
||||||
|
|
||||||
|
enum http_method:
|
||||||
|
DELETE, GET, HEAD, POST, PUT, CONNECT, OPTIONS, TRACE, COPY,
|
||||||
|
LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH, SEARCH, UNLOCK, BIND,
|
||||||
|
REBIND, UNBIND, ACL, REPORT, MKACTIVITY, CHECKOUT, MERGE,
|
||||||
|
MSEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, PATCH, PURGE, MKCALENDAR,
|
||||||
|
LINK, UNLINK
|
||||||
|
|
||||||
|
void http_parser_init(http_parser *parser, http_parser_type type)
|
||||||
|
|
||||||
|
size_t http_parser_execute(http_parser *parser,
|
||||||
|
const http_parser_settings *settings,
|
||||||
|
const char *data,
|
||||||
|
size_t len)
|
||||||
|
|
||||||
|
int http_should_keep_alive(const http_parser *parser)
|
||||||
|
|
||||||
|
void http_parser_settings_init(http_parser_settings *settings)
|
||||||
|
|
||||||
|
const char *http_errno_name(http_errno err)
|
||||||
|
const char *http_errno_description(http_errno err)
|
||||||
|
const char *http_method_str(http_method m)
|
||||||
|
|
||||||
|
# URL Parser
|
||||||
|
|
||||||
|
enum http_parser_url_fields:
|
||||||
|
UF_SCHEMA = 0,
|
||||||
|
UF_HOST = 1,
|
||||||
|
UF_PORT = 2,
|
||||||
|
UF_PATH = 3,
|
||||||
|
UF_QUERY = 4,
|
||||||
|
UF_FRAGMENT = 5,
|
||||||
|
UF_USERINFO = 6,
|
||||||
|
UF_MAX = 7
|
||||||
|
|
||||||
|
struct http_parser_url_field_data:
|
||||||
|
uint16_t off
|
||||||
|
uint16_t len
|
||||||
|
|
||||||
|
struct http_parser_url:
|
||||||
|
uint16_t field_set
|
||||||
|
uint16_t port
|
||||||
|
http_parser_url_field_data[<int>UF_MAX] field_data
|
||||||
|
|
||||||
|
void http_parser_url_init(http_parser_url *u)
|
||||||
|
|
||||||
|
int http_parser_parse_url(const char *buf,
|
||||||
|
size_t buflen,
|
||||||
|
int is_connect,
|
||||||
|
http_parser_url *u)
|
9870
venv/lib/python3.8/site-packages/aiohttp/_find_header.c
Normal file
9870
venv/lib/python3.8/site-packages/aiohttp/_find_header.c
Normal file
File diff suppressed because it is too large
Load diff
14
venv/lib/python3.8/site-packages/aiohttp/_find_header.h
Normal file
14
venv/lib/python3.8/site-packages/aiohttp/_find_header.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef _FIND_HEADERS_H
|
||||||
|
#define _FIND_HEADERS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int find_header(const char *str, int size);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -0,0 +1,2 @@
|
||||||
|
cdef extern from "_find_header.h":
|
||||||
|
int find_header(char *, int)
|
7512
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.c
Normal file
7512
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.cpython-38-darwin.so
Executable file
BIN
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.cpython-38-darwin.so
Executable file
Binary file not shown.
108
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.pyx
Normal file
108
venv/lib/python3.8/site-packages/aiohttp/_frozenlist.pyx
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
from collections.abc import MutableSequence
|
||||||
|
|
||||||
|
|
||||||
|
cdef class FrozenList:
|
||||||
|
|
||||||
|
cdef readonly bint frozen
|
||||||
|
cdef list _items
|
||||||
|
|
||||||
|
def __init__(self, items=None):
|
||||||
|
self.frozen = False
|
||||||
|
if items is not None:
|
||||||
|
items = list(items)
|
||||||
|
else:
|
||||||
|
items = []
|
||||||
|
self._items = items
|
||||||
|
|
||||||
|
cdef object _check_frozen(self):
|
||||||
|
if self.frozen:
|
||||||
|
raise RuntimeError("Cannot modify frozen list.")
|
||||||
|
|
||||||
|
cdef inline object _fast_len(self):
|
||||||
|
return len(self._items)
|
||||||
|
|
||||||
|
def freeze(self):
|
||||||
|
self.frozen = True
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self._items[index]
|
||||||
|
|
||||||
|
def __setitem__(self, index, value):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items[index] = value
|
||||||
|
|
||||||
|
def __delitem__(self, index):
|
||||||
|
self._check_frozen()
|
||||||
|
del self._items[index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self._fast_len()
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self._items.__iter__()
|
||||||
|
|
||||||
|
def __reversed__(self):
|
||||||
|
return self._items.__reversed__()
|
||||||
|
|
||||||
|
def __richcmp__(self, other, op):
|
||||||
|
if op == 0: # <
|
||||||
|
return list(self) < other
|
||||||
|
if op == 1: # <=
|
||||||
|
return list(self) <= other
|
||||||
|
if op == 2: # ==
|
||||||
|
return list(self) == other
|
||||||
|
if op == 3: # !=
|
||||||
|
return list(self) != other
|
||||||
|
if op == 4: # >
|
||||||
|
return list(self) > other
|
||||||
|
if op == 5: # =>
|
||||||
|
return list(self) >= other
|
||||||
|
|
||||||
|
def insert(self, pos, item):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items.insert(pos, item)
|
||||||
|
|
||||||
|
def __contains__(self, item):
|
||||||
|
return item in self._items
|
||||||
|
|
||||||
|
def __iadd__(self, items):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items += list(items)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def index(self, item):
|
||||||
|
return self._items.index(item)
|
||||||
|
|
||||||
|
def remove(self, item):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items.remove(item)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items.clear()
|
||||||
|
|
||||||
|
def extend(self, items):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items += list(items)
|
||||||
|
|
||||||
|
def reverse(self):
|
||||||
|
self._check_frozen()
|
||||||
|
self._items.reverse()
|
||||||
|
|
||||||
|
def pop(self, index=-1):
|
||||||
|
self._check_frozen()
|
||||||
|
return self._items.pop(index)
|
||||||
|
|
||||||
|
def append(self, item):
|
||||||
|
self._check_frozen()
|
||||||
|
return self._items.append(item)
|
||||||
|
|
||||||
|
def count(self, item):
|
||||||
|
return self._items.count(item)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<FrozenList(frozen={}, {!r})>'.format(self.frozen,
|
||||||
|
self._items)
|
||||||
|
|
||||||
|
|
||||||
|
MutableSequence.register(FrozenList)
|
83
venv/lib/python3.8/site-packages/aiohttp/_headers.pxi
Normal file
83
venv/lib/python3.8/site-packages/aiohttp/_headers.pxi
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
# The file is autogenerated from aiohttp/hdrs.py
|
||||||
|
# Run ./tools/gen.py to update it after the origin changing.
|
||||||
|
|
||||||
|
from . import hdrs
|
||||||
|
cdef tuple headers = (
|
||||||
|
hdrs.ACCEPT,
|
||||||
|
hdrs.ACCEPT_CHARSET,
|
||||||
|
hdrs.ACCEPT_ENCODING,
|
||||||
|
hdrs.ACCEPT_LANGUAGE,
|
||||||
|
hdrs.ACCEPT_RANGES,
|
||||||
|
hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
||||||
|
hdrs.ACCESS_CONTROL_ALLOW_HEADERS,
|
||||||
|
hdrs.ACCESS_CONTROL_ALLOW_METHODS,
|
||||||
|
hdrs.ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||||
|
hdrs.ACCESS_CONTROL_EXPOSE_HEADERS,
|
||||||
|
hdrs.ACCESS_CONTROL_MAX_AGE,
|
||||||
|
hdrs.ACCESS_CONTROL_REQUEST_HEADERS,
|
||||||
|
hdrs.ACCESS_CONTROL_REQUEST_METHOD,
|
||||||
|
hdrs.AGE,
|
||||||
|
hdrs.ALLOW,
|
||||||
|
hdrs.AUTHORIZATION,
|
||||||
|
hdrs.CACHE_CONTROL,
|
||||||
|
hdrs.CONNECTION,
|
||||||
|
hdrs.CONTENT_DISPOSITION,
|
||||||
|
hdrs.CONTENT_ENCODING,
|
||||||
|
hdrs.CONTENT_LANGUAGE,
|
||||||
|
hdrs.CONTENT_LENGTH,
|
||||||
|
hdrs.CONTENT_LOCATION,
|
||||||
|
hdrs.CONTENT_MD5,
|
||||||
|
hdrs.CONTENT_RANGE,
|
||||||
|
hdrs.CONTENT_TRANSFER_ENCODING,
|
||||||
|
hdrs.CONTENT_TYPE,
|
||||||
|
hdrs.COOKIE,
|
||||||
|
hdrs.DATE,
|
||||||
|
hdrs.DESTINATION,
|
||||||
|
hdrs.DIGEST,
|
||||||
|
hdrs.ETAG,
|
||||||
|
hdrs.EXPECT,
|
||||||
|
hdrs.EXPIRES,
|
||||||
|
hdrs.FORWARDED,
|
||||||
|
hdrs.FROM,
|
||||||
|
hdrs.HOST,
|
||||||
|
hdrs.IF_MATCH,
|
||||||
|
hdrs.IF_MODIFIED_SINCE,
|
||||||
|
hdrs.IF_NONE_MATCH,
|
||||||
|
hdrs.IF_RANGE,
|
||||||
|
hdrs.IF_UNMODIFIED_SINCE,
|
||||||
|
hdrs.KEEP_ALIVE,
|
||||||
|
hdrs.LAST_EVENT_ID,
|
||||||
|
hdrs.LAST_MODIFIED,
|
||||||
|
hdrs.LINK,
|
||||||
|
hdrs.LOCATION,
|
||||||
|
hdrs.MAX_FORWARDS,
|
||||||
|
hdrs.ORIGIN,
|
||||||
|
hdrs.PRAGMA,
|
||||||
|
hdrs.PROXY_AUTHENTICATE,
|
||||||
|
hdrs.PROXY_AUTHORIZATION,
|
||||||
|
hdrs.RANGE,
|
||||||
|
hdrs.REFERER,
|
||||||
|
hdrs.RETRY_AFTER,
|
||||||
|
hdrs.SEC_WEBSOCKET_ACCEPT,
|
||||||
|
hdrs.SEC_WEBSOCKET_EXTENSIONS,
|
||||||
|
hdrs.SEC_WEBSOCKET_KEY,
|
||||||
|
hdrs.SEC_WEBSOCKET_KEY1,
|
||||||
|
hdrs.SEC_WEBSOCKET_PROTOCOL,
|
||||||
|
hdrs.SEC_WEBSOCKET_VERSION,
|
||||||
|
hdrs.SERVER,
|
||||||
|
hdrs.SET_COOKIE,
|
||||||
|
hdrs.TE,
|
||||||
|
hdrs.TRAILER,
|
||||||
|
hdrs.TRANSFER_ENCODING,
|
||||||
|
hdrs.URI,
|
||||||
|
hdrs.UPGRADE,
|
||||||
|
hdrs.USER_AGENT,
|
||||||
|
hdrs.VARY,
|
||||||
|
hdrs.VIA,
|
||||||
|
hdrs.WWW_AUTHENTICATE,
|
||||||
|
hdrs.WANT_DIGEST,
|
||||||
|
hdrs.WARNING,
|
||||||
|
hdrs.X_FORWARDED_FOR,
|
||||||
|
hdrs.X_FORWARDED_HOST,
|
||||||
|
hdrs.X_FORWARDED_PROTO,
|
||||||
|
)
|
5433
venv/lib/python3.8/site-packages/aiohttp/_helpers.c
Normal file
5433
venv/lib/python3.8/site-packages/aiohttp/_helpers.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
venv/lib/python3.8/site-packages/aiohttp/_helpers.cpython-38-darwin.so
Executable file
BIN
venv/lib/python3.8/site-packages/aiohttp/_helpers.cpython-38-darwin.so
Executable file
Binary file not shown.
6
venv/lib/python3.8/site-packages/aiohttp/_helpers.pyi
Normal file
6
venv/lib/python3.8/site-packages/aiohttp/_helpers.pyi
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
class reify:
|
||||||
|
def __init__(self, wrapped: Any) -> None: ...
|
||||||
|
def __get__(self, inst: Any, owner: Any) -> Any: ...
|
||||||
|
def __set__(self, inst: Any, value: Any) -> None: ...
|
35
venv/lib/python3.8/site-packages/aiohttp/_helpers.pyx
Normal file
35
venv/lib/python3.8/site-packages/aiohttp/_helpers.pyx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
cdef class reify:
|
||||||
|
"""Use as a class method decorator. It operates almost exactly like
|
||||||
|
the Python `@property` decorator, but it puts the result of the
|
||||||
|
method it decorates into the instance dict after the first call,
|
||||||
|
effectively replacing the function it decorates with an instance
|
||||||
|
variable. It is, in Python parlance, a data descriptor.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdef object wrapped
|
||||||
|
cdef object name
|
||||||
|
|
||||||
|
def __init__(self, wrapped):
|
||||||
|
self.wrapped = wrapped
|
||||||
|
self.name = wrapped.__name__
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __doc__(self):
|
||||||
|
return self.wrapped.__doc__
|
||||||
|
|
||||||
|
def __get__(self, inst, owner):
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
return inst._cache[self.name]
|
||||||
|
except KeyError:
|
||||||
|
val = self.wrapped(inst)
|
||||||
|
inst._cache[self.name] = val
|
||||||
|
return val
|
||||||
|
except AttributeError:
|
||||||
|
if inst is None:
|
||||||
|
return self
|
||||||
|
raise
|
||||||
|
|
||||||
|
def __set__(self, inst, value):
|
||||||
|
raise AttributeError("reified property is read-only")
|
24607
venv/lib/python3.8/site-packages/aiohttp/_http_parser.c
Normal file
24607
venv/lib/python3.8/site-packages/aiohttp/_http_parser.c
Normal file
File diff suppressed because it is too large
Load diff
BIN
venv/lib/python3.8/site-packages/aiohttp/_http_parser.cpython-38-darwin.so
Executable file
BIN
venv/lib/python3.8/site-packages/aiohttp/_http_parser.cpython-38-darwin.so
Executable file
Binary file not shown.
875
venv/lib/python3.8/site-packages/aiohttp/_http_parser.pyx
Normal file
875
venv/lib/python3.8/site-packages/aiohttp/_http_parser.pyx
Normal file
|
@ -0,0 +1,875 @@
|
||||||
|
#cython: language_level=3
|
||||||
|
#
|
||||||
|
# Based on https://github.com/MagicStack/httptools
|
||||||
|
#
|
||||||
|
from __future__ import absolute_import, print_function
|
||||||
|
|
||||||
|
from cpython cimport (
|
||||||
|
Py_buffer,
|
||||||
|
PyBUF_SIMPLE,
|
||||||
|
PyBuffer_Release,
|
||||||
|
PyBytes_AsString,
|
||||||
|
PyBytes_AsStringAndSize,
|
||||||
|
PyObject_GetBuffer,
|
||||||
|
)
|
||||||
|
from cpython.mem cimport PyMem_Free, PyMem_Malloc
|
||||||
|
from libc.limits cimport ULLONG_MAX
|
||||||
|
from libc.string cimport memcpy
|
||||||
|
|
||||||
|
from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy
|
||||||
|
from yarl import URL as _URL
|
||||||
|
|
||||||
|
from aiohttp import hdrs
|
||||||
|
|
||||||
|
from .http_exceptions import (
|
||||||
|
BadHttpMessage,
|
||||||
|
BadStatusLine,
|
||||||
|
ContentLengthError,
|
||||||
|
InvalidHeader,
|
||||||
|
InvalidURLError,
|
||||||
|
LineTooLong,
|
||||||
|
PayloadEncodingError,
|
||||||
|
TransferEncodingError,
|
||||||
|
)
|
||||||
|
from .http_parser import DeflateBuffer as _DeflateBuffer
|
||||||
|
from .http_writer import (
|
||||||
|
HttpVersion as _HttpVersion,
|
||||||
|
HttpVersion10 as _HttpVersion10,
|
||||||
|
HttpVersion11 as _HttpVersion11,
|
||||||
|
)
|
||||||
|
from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader
|
||||||
|
|
||||||
|
cimport cython
|
||||||
|
|
||||||
|
from aiohttp cimport _cparser as cparser
|
||||||
|
|
||||||
|
include "_headers.pxi"
|
||||||
|
|
||||||
|
from aiohttp cimport _find_header
|
||||||
|
|
||||||
|
DEF DEFAULT_FREELIST_SIZE = 250
|
||||||
|
|
||||||
|
cdef extern from "Python.h":
|
||||||
|
int PyByteArray_Resize(object, Py_ssize_t) except -1
|
||||||
|
Py_ssize_t PyByteArray_Size(object) except -1
|
||||||
|
char* PyByteArray_AsString(object)
|
||||||
|
|
||||||
|
__all__ = ('HttpRequestParser', 'HttpResponseParser',
|
||||||
|
'RawRequestMessage', 'RawResponseMessage')
|
||||||
|
|
||||||
|
cdef object URL = _URL
|
||||||
|
cdef object URL_build = URL.build
|
||||||
|
cdef object CIMultiDict = _CIMultiDict
|
||||||
|
cdef object CIMultiDictProxy = _CIMultiDictProxy
|
||||||
|
cdef object HttpVersion = _HttpVersion
|
||||||
|
cdef object HttpVersion10 = _HttpVersion10
|
||||||
|
cdef object HttpVersion11 = _HttpVersion11
|
||||||
|
cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1
|
||||||
|
cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING
|
||||||
|
cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD
|
||||||
|
cdef object StreamReader = _StreamReader
|
||||||
|
cdef object DeflateBuffer = _DeflateBuffer
|
||||||
|
|
||||||
|
|
||||||
|
cdef inline object extend(object buf, const char* at, size_t length):
|
||||||
|
cdef Py_ssize_t s
|
||||||
|
cdef char* ptr
|
||||||
|
s = PyByteArray_Size(buf)
|
||||||
|
PyByteArray_Resize(buf, s + length)
|
||||||
|
ptr = PyByteArray_AsString(buf)
|
||||||
|
memcpy(ptr + s, at, length)
|
||||||
|
|
||||||
|
|
||||||
|
DEF METHODS_COUNT = 34;
|
||||||
|
|
||||||
|
cdef list _http_method = []
|
||||||
|
|
||||||
|
for i in range(METHODS_COUNT):
|
||||||
|
_http_method.append(
|
||||||
|
cparser.http_method_str(<cparser.http_method> i).decode('ascii'))
|
||||||
|
|
||||||
|
|
||||||
|
cdef inline str http_method_str(int i):
|
||||||
|
if i < METHODS_COUNT:
|
||||||
|
return <str>_http_method[i]
|
||||||
|
else:
|
||||||
|
return "<unknown>"
|
||||||
|
|
||||||
|
cdef inline object find_header(bytes raw_header):
|
||||||
|
cdef Py_ssize_t size
|
||||||
|
cdef char *buf
|
||||||
|
cdef int idx
|
||||||
|
PyBytes_AsStringAndSize(raw_header, &buf, &size)
|
||||||
|
idx = _find_header.find_header(buf, size)
|
||||||
|
if idx == -1:
|
||||||
|
return raw_header.decode('utf-8', 'surrogateescape')
|
||||||
|
return headers[idx]
|
||||||
|
|
||||||
|
|
||||||
|
@cython.freelist(DEFAULT_FREELIST_SIZE)
|
||||||
|
cdef class RawRequestMessage:
|
||||||
|
cdef readonly str method
|
||||||
|
cdef readonly str path
|
||||||
|
cdef readonly object version # HttpVersion
|
||||||
|
cdef readonly object headers # CIMultiDict
|
||||||
|
cdef readonly object raw_headers # tuple
|
||||||
|
cdef readonly object should_close
|
||||||
|
cdef readonly object compression
|
||||||
|
cdef readonly object upgrade
|
||||||
|
cdef readonly object chunked
|
||||||
|
cdef readonly object url # yarl.URL
|
||||||
|
|
||||||
|
def __init__(self, method, path, version, headers, raw_headers,
|
||||||
|
should_close, compression, upgrade, chunked, url):
|
||||||
|
self.method = method
|
||||||
|
self.path = path
|
||||||
|
self.version = version
|
||||||
|
self.headers = headers
|
||||||
|
self.raw_headers = raw_headers
|
||||||
|
self.should_close = should_close
|
||||||
|
self.compression = compression
|
||||||
|
self.upgrade = upgrade
|
||||||
|
self.chunked = chunked
|
||||||
|
self.url = url
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
info = []
|
||||||
|
info.append(("method", self.method))
|
||||||
|
info.append(("path", self.path))
|
||||||
|
info.append(("version", self.version))
|
||||||
|
info.append(("headers", self.headers))
|
||||||
|
info.append(("raw_headers", self.raw_headers))
|
||||||
|
info.append(("should_close", self.should_close))
|
||||||
|
info.append(("compression", self.compression))
|
||||||
|
info.append(("upgrade", self.upgrade))
|
||||||
|
info.append(("chunked", self.chunked))
|
||||||
|
info.append(("url", self.url))
|
||||||
|
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
|
||||||
|
return '<RawRequestMessage(' + sinfo + ')>'
|
||||||
|
|
||||||
|
def _replace(self, **dct):
|
||||||
|
cdef RawRequestMessage ret
|
||||||
|
ret = _new_request_message(self.method,
|
||||||
|
self.path,
|
||||||
|
self.version,
|
||||||
|
self.headers,
|
||||||
|
self.raw_headers,
|
||||||
|
self.should_close,
|
||||||
|
self.compression,
|
||||||
|
self.upgrade,
|
||||||
|
self.chunked,
|
||||||
|
self.url)
|
||||||
|
if "method" in dct:
|
||||||
|
ret.method = dct["method"]
|
||||||
|
if "path" in dct:
|
||||||
|
ret.path = dct["path"]
|
||||||
|
if "version" in dct:
|
||||||
|
ret.version = dct["version"]
|
||||||
|
if "headers" in dct:
|
||||||
|
ret.headers = dct["headers"]
|
||||||
|
if "raw_headers" in dct:
|
||||||
|
ret.raw_headers = dct["raw_headers"]
|
||||||
|
if "should_close" in dct:
|
||||||
|
ret.should_close = dct["should_close"]
|
||||||
|
if "compression" in dct:
|
||||||
|
ret.compression = dct["compression"]
|
||||||
|
if "upgrade" in dct:
|
||||||
|
ret.upgrade = dct["upgrade"]
|
||||||
|
if "chunked" in dct:
|
||||||
|
ret.chunked = dct["chunked"]
|
||||||
|
if "url" in dct:
|
||||||
|
ret.url = dct["url"]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
cdef _new_request_message(str method,
|
||||||
|
str path,
|
||||||
|
object version,
|
||||||
|
object headers,
|
||||||
|
object raw_headers,
|
||||||
|
bint should_close,
|
||||||
|
object compression,
|
||||||
|
bint upgrade,
|
||||||
|
bint chunked,
|
||||||
|
object url):
|
||||||
|
cdef RawRequestMessage ret
|
||||||
|
ret = RawRequestMessage.__new__(RawRequestMessage)
|
||||||
|
ret.method = method
|
||||||
|
ret.path = path
|
||||||
|
ret.version = version
|
||||||
|
ret.headers = headers
|
||||||
|
ret.raw_headers = raw_headers
|
||||||
|
ret.should_close = should_close
|
||||||
|
ret.compression = compression
|
||||||
|
ret.upgrade = upgrade
|
||||||
|
ret.chunked = chunked
|
||||||
|
ret.url = url
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@cython.freelist(DEFAULT_FREELIST_SIZE)
|
||||||
|
cdef class RawResponseMessage:
|
||||||
|
cdef readonly object version # HttpVersion
|
||||||
|
cdef readonly int code
|
||||||
|
cdef readonly str reason
|
||||||
|
cdef readonly object headers # CIMultiDict
|
||||||
|
cdef readonly object raw_headers # tuple
|
||||||
|
cdef readonly object should_close
|
||||||
|
cdef readonly object compression
|
||||||
|
cdef readonly object upgrade
|
||||||
|
cdef readonly object chunked
|
||||||
|
|
||||||
|
def __init__(self, version, code, reason, headers, raw_headers,
|
||||||
|
should_close, compression, upgrade, chunked):
|
||||||
|
self.version = version
|
||||||
|
self.code = code
|
||||||
|
self.reason = reason
|
||||||
|
self.headers = headers
|
||||||
|
self.raw_headers = raw_headers
|
||||||
|
self.should_close = should_close
|
||||||
|
self.compression = compression
|
||||||
|
self.upgrade = upgrade
|
||||||
|
self.chunked = chunked
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
info = []
|
||||||
|
info.append(("version", self.version))
|
||||||
|
info.append(("code", self.code))
|
||||||
|
info.append(("reason", self.reason))
|
||||||
|
info.append(("headers", self.headers))
|
||||||
|
info.append(("raw_headers", self.raw_headers))
|
||||||
|
info.append(("should_close", self.should_close))
|
||||||
|
info.append(("compression", self.compression))
|
||||||
|
info.append(("upgrade", self.upgrade))
|
||||||
|
info.append(("chunked", self.chunked))
|
||||||
|
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
|
||||||
|
return '<RawResponseMessage(' + sinfo + ')>'
|
||||||
|
|
||||||
|
|
||||||
|
cdef _new_response_message(object version,
|
||||||
|
int code,
|
||||||
|
str reason,
|
||||||
|
object headers,
|
||||||
|
object raw_headers,
|
||||||
|
bint should_close,
|
||||||
|
object compression,
|
||||||
|
bint upgrade,
|
||||||
|
bint chunked):
|
||||||
|
cdef RawResponseMessage ret
|
||||||
|
ret = RawResponseMessage.__new__(RawResponseMessage)
|
||||||
|
ret.version = version
|
||||||
|
ret.code = code
|
||||||
|
ret.reason = reason
|
||||||
|
ret.headers = headers
|
||||||
|
ret.raw_headers = raw_headers
|
||||||
|
ret.should_close = should_close
|
||||||
|
ret.compression = compression
|
||||||
|
ret.upgrade = upgrade
|
||||||
|
ret.chunked = chunked
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@cython.internal
|
||||||
|
cdef class HttpParser:
|
||||||
|
|
||||||
|
cdef:
|
||||||
|
cparser.http_parser* _cparser
|
||||||
|
cparser.http_parser_settings* _csettings
|
||||||
|
|
||||||
|
bytearray _raw_name
|
||||||
|
bytearray _raw_value
|
||||||
|
bint _has_value
|
||||||
|
|
||||||
|
object _protocol
|
||||||
|
object _loop
|
||||||
|
object _timer
|
||||||
|
|
||||||
|
size_t _max_line_size
|
||||||
|
size_t _max_field_size
|
||||||
|
size_t _max_headers
|
||||||
|
bint _response_with_body
|
||||||
|
bint _read_until_eof
|
||||||
|
|
||||||
|
bint _started
|
||||||
|
object _url
|
||||||
|
bytearray _buf
|
||||||
|
str _path
|
||||||
|
str _reason
|
||||||
|
object _headers
|
||||||
|
list _raw_headers
|
||||||
|
bint _upgraded
|
||||||
|
list _messages
|
||||||
|
object _payload
|
||||||
|
bint _payload_error
|
||||||
|
object _payload_exception
|
||||||
|
object _last_error
|
||||||
|
bint _auto_decompress
|
||||||
|
int _limit
|
||||||
|
|
||||||
|
str _content_encoding
|
||||||
|
|
||||||
|
Py_buffer py_buf
|
||||||
|
|
||||||
|
def __cinit__(self):
|
||||||
|
self._cparser = <cparser.http_parser*> \
|
||||||
|
PyMem_Malloc(sizeof(cparser.http_parser))
|
||||||
|
if self._cparser is NULL:
|
||||||
|
raise MemoryError()
|
||||||
|
|
||||||
|
self._csettings = <cparser.http_parser_settings*> \
|
||||||
|
PyMem_Malloc(sizeof(cparser.http_parser_settings))
|
||||||
|
if self._csettings is NULL:
|
||||||
|
raise MemoryError()
|
||||||
|
|
||||||
|
def __dealloc__(self):
|
||||||
|
PyMem_Free(self._cparser)
|
||||||
|
PyMem_Free(self._csettings)
|
||||||
|
|
||||||
|
cdef _init(self, cparser.http_parser_type mode,
|
||||||
|
object protocol, object loop, int limit,
|
||||||
|
object timer=None,
|
||||||
|
size_t max_line_size=8190, size_t max_headers=32768,
|
||||||
|
size_t max_field_size=8190, payload_exception=None,
|
||||||
|
bint response_with_body=True, bint read_until_eof=False,
|
||||||
|
bint auto_decompress=True):
|
||||||
|
cparser.http_parser_init(self._cparser, mode)
|
||||||
|
self._cparser.data = <void*>self
|
||||||
|
self._cparser.content_length = 0
|
||||||
|
|
||||||
|
cparser.http_parser_settings_init(self._csettings)
|
||||||
|
|
||||||
|
self._protocol = protocol
|
||||||
|
self._loop = loop
|
||||||
|
self._timer = timer
|
||||||
|
|
||||||
|
self._buf = bytearray()
|
||||||
|
self._payload = None
|
||||||
|
self._payload_error = 0
|
||||||
|
self._payload_exception = payload_exception
|
||||||
|
self._messages = []
|
||||||
|
|
||||||
|
self._raw_name = bytearray()
|
||||||
|
self._raw_value = bytearray()
|
||||||
|
self._has_value = False
|
||||||
|
|
||||||
|
self._max_line_size = max_line_size
|
||||||
|
self._max_headers = max_headers
|
||||||
|
self._max_field_size = max_field_size
|
||||||
|
self._response_with_body = response_with_body
|
||||||
|
self._read_until_eof = read_until_eof
|
||||||
|
self._upgraded = False
|
||||||
|
self._auto_decompress = auto_decompress
|
||||||
|
self._content_encoding = None
|
||||||
|
|
||||||
|
self._csettings.on_url = cb_on_url
|
||||||
|
self._csettings.on_status = cb_on_status
|
||||||
|
self._csettings.on_header_field = cb_on_header_field
|
||||||
|
self._csettings.on_header_value = cb_on_header_value
|
||||||
|
self._csettings.on_headers_complete = cb_on_headers_complete
|
||||||
|
self._csettings.on_body = cb_on_body
|
||||||
|
self._csettings.on_message_begin = cb_on_message_begin
|
||||||
|
self._csettings.on_message_complete = cb_on_message_complete
|
||||||
|
self._csettings.on_chunk_header = cb_on_chunk_header
|
||||||
|
self._csettings.on_chunk_complete = cb_on_chunk_complete
|
||||||
|
|
||||||
|
self._last_error = None
|
||||||
|
self._limit = limit
|
||||||
|
|
||||||
|
cdef _process_header(self):
|
||||||
|
if self._raw_name:
|
||||||
|
raw_name = bytes(self._raw_name)
|
||||||
|
raw_value = bytes(self._raw_value)
|
||||||
|
|
||||||
|
name = find_header(raw_name)
|
||||||
|
value = raw_value.decode('utf-8', 'surrogateescape')
|
||||||
|
|
||||||
|
self._headers.add(name, value)
|
||||||
|
|
||||||
|
if name is CONTENT_ENCODING:
|
||||||
|
self._content_encoding = value
|
||||||
|
|
||||||
|
PyByteArray_Resize(self._raw_name, 0)
|
||||||
|
PyByteArray_Resize(self._raw_value, 0)
|
||||||
|
self._has_value = False
|
||||||
|
self._raw_headers.append((raw_name, raw_value))
|
||||||
|
|
||||||
|
cdef _on_header_field(self, char* at, size_t length):
|
||||||
|
cdef Py_ssize_t size
|
||||||
|
cdef char *buf
|
||||||
|
if self._has_value:
|
||||||
|
self._process_header()
|
||||||
|
|
||||||
|
size = PyByteArray_Size(self._raw_name)
|
||||||
|
PyByteArray_Resize(self._raw_name, size + length)
|
||||||
|
buf = PyByteArray_AsString(self._raw_name)
|
||||||
|
memcpy(buf + size, at, length)
|
||||||
|
|
||||||
|
cdef _on_header_value(self, char* at, size_t length):
|
||||||
|
cdef Py_ssize_t size
|
||||||
|
cdef char *buf
|
||||||
|
|
||||||
|
size = PyByteArray_Size(self._raw_value)
|
||||||
|
PyByteArray_Resize(self._raw_value, size + length)
|
||||||
|
buf = PyByteArray_AsString(self._raw_value)
|
||||||
|
memcpy(buf + size, at, length)
|
||||||
|
self._has_value = True
|
||||||
|
|
||||||
|
cdef _on_headers_complete(self):
|
||||||
|
self._process_header()
|
||||||
|
|
||||||
|
method = http_method_str(self._cparser.method)
|
||||||
|
should_close = not cparser.http_should_keep_alive(self._cparser)
|
||||||
|
upgrade = self._cparser.upgrade
|
||||||
|
chunked = self._cparser.flags & cparser.F_CHUNKED
|
||||||
|
|
||||||
|
raw_headers = tuple(self._raw_headers)
|
||||||
|
headers = CIMultiDictProxy(self._headers)
|
||||||
|
|
||||||
|
if upgrade or self._cparser.method == 5: # cparser.CONNECT:
|
||||||
|
self._upgraded = True
|
||||||
|
|
||||||
|
# do not support old websocket spec
|
||||||
|
if SEC_WEBSOCKET_KEY1 in headers:
|
||||||
|
raise InvalidHeader(SEC_WEBSOCKET_KEY1)
|
||||||
|
|
||||||
|
encoding = None
|
||||||
|
enc = self._content_encoding
|
||||||
|
if enc is not None:
|
||||||
|
self._content_encoding = None
|
||||||
|
enc = enc.lower()
|
||||||
|
if enc in ('gzip', 'deflate', 'br'):
|
||||||
|
encoding = enc
|
||||||
|
|
||||||
|
if self._cparser.type == cparser.HTTP_REQUEST:
|
||||||
|
msg = _new_request_message(
|
||||||
|
method, self._path,
|
||||||
|
self.http_version(), headers, raw_headers,
|
||||||
|
should_close, encoding, upgrade, chunked, self._url)
|
||||||
|
else:
|
||||||
|
msg = _new_response_message(
|
||||||
|
self.http_version(), self._cparser.status_code, self._reason,
|
||||||
|
headers, raw_headers, should_close, encoding,
|
||||||
|
upgrade, chunked)
|
||||||
|
|
||||||
|
if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or
|
||||||
|
self._cparser.method == 5 or # CONNECT: 5
|
||||||
|
(self._cparser.status_code >= 199 and
|
||||||
|
self._cparser.content_length == ULLONG_MAX and
|
||||||
|
self._read_until_eof)
|
||||||
|
):
|
||||||
|
payload = StreamReader(
|
||||||
|
self._protocol, timer=self._timer, loop=self._loop,
|
||||||
|
limit=self._limit)
|
||||||
|
else:
|
||||||
|
payload = EMPTY_PAYLOAD
|
||||||
|
|
||||||
|
self._payload = payload
|
||||||
|
if encoding is not None and self._auto_decompress:
|
||||||
|
self._payload = DeflateBuffer(payload, encoding)
|
||||||
|
|
||||||
|
if not self._response_with_body:
|
||||||
|
payload = EMPTY_PAYLOAD
|
||||||
|
|
||||||
|
self._messages.append((msg, payload))
|
||||||
|
|
||||||
|
cdef _on_message_complete(self):
|
||||||
|
self._payload.feed_eof()
|
||||||
|
self._payload = None
|
||||||
|
|
||||||
|
cdef _on_chunk_header(self):
|
||||||
|
self._payload.begin_http_chunk_receiving()
|
||||||
|
|
||||||
|
cdef _on_chunk_complete(self):
|
||||||
|
self._payload.end_http_chunk_receiving()
|
||||||
|
|
||||||
|
cdef object _on_status_complete(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
cdef inline http_version(self):
|
||||||
|
cdef cparser.http_parser* parser = self._cparser
|
||||||
|
|
||||||
|
if parser.http_major == 1:
|
||||||
|
if parser.http_minor == 0:
|
||||||
|
return HttpVersion10
|
||||||
|
elif parser.http_minor == 1:
|
||||||
|
return HttpVersion11
|
||||||
|
|
||||||
|
return HttpVersion(parser.http_major, parser.http_minor)
|
||||||
|
|
||||||
|
### Public API ###
|
||||||
|
|
||||||
|
def feed_eof(self):
|
||||||
|
cdef bytes desc
|
||||||
|
|
||||||
|
if self._payload is not None:
|
||||||
|
if self._cparser.flags & cparser.F_CHUNKED:
|
||||||
|
raise TransferEncodingError(
|
||||||
|
"Not enough data for satisfy transfer length header.")
|
||||||
|
elif self._cparser.flags & cparser.F_CONTENTLENGTH:
|
||||||
|
raise ContentLengthError(
|
||||||
|
"Not enough data for satisfy content length header.")
|
||||||
|
elif self._cparser.http_errno != cparser.HPE_OK:
|
||||||
|
desc = cparser.http_errno_description(
|
||||||
|
<cparser.http_errno> self._cparser.http_errno)
|
||||||
|
raise PayloadEncodingError(desc.decode('latin-1'))
|
||||||
|
else:
|
||||||
|
self._payload.feed_eof()
|
||||||
|
elif self._started:
|
||||||
|
self._on_headers_complete()
|
||||||
|
if self._messages:
|
||||||
|
return self._messages[-1][0]
|
||||||
|
|
||||||
|
def feed_data(self, data):
|
||||||
|
cdef:
|
||||||
|
size_t data_len
|
||||||
|
size_t nb
|
||||||
|
|
||||||
|
PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE)
|
||||||
|
data_len = <size_t>self.py_buf.len
|
||||||
|
|
||||||
|
nb = cparser.http_parser_execute(
|
||||||
|
self._cparser,
|
||||||
|
self._csettings,
|
||||||
|
<char*>self.py_buf.buf,
|
||||||
|
data_len)
|
||||||
|
|
||||||
|
PyBuffer_Release(&self.py_buf)
|
||||||
|
|
||||||
|
if (self._cparser.http_errno != cparser.HPE_OK):
|
||||||
|
if self._payload_error == 0:
|
||||||
|
if self._last_error is not None:
|
||||||
|
ex = self._last_error
|
||||||
|
self._last_error = None
|
||||||
|
else:
|
||||||
|
ex = parser_error_from_errno(
|
||||||
|
<cparser.http_errno> self._cparser.http_errno)
|
||||||
|
self._payload = None
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
if self._messages:
|
||||||
|
messages = self._messages
|
||||||
|
self._messages = []
|
||||||
|
else:
|
||||||
|
messages = ()
|
||||||
|
|
||||||
|
if self._upgraded:
|
||||||
|
return messages, True, data[nb:]
|
||||||
|
else:
|
||||||
|
return messages, False, b''
|
||||||
|
|
||||||
|
def set_upgraded(self, val):
|
||||||
|
self._upgraded = val
|
||||||
|
|
||||||
|
|
||||||
|
cdef class HttpRequestParser(HttpParser):
|
||||||
|
|
||||||
|
def __init__(self, protocol, loop, int limit, timer=None,
|
||||||
|
size_t max_line_size=8190, size_t max_headers=32768,
|
||||||
|
size_t max_field_size=8190, payload_exception=None,
|
||||||
|
bint response_with_body=True, bint read_until_eof=False,
|
||||||
|
):
|
||||||
|
self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer,
|
||||||
|
max_line_size, max_headers, max_field_size,
|
||||||
|
payload_exception, response_with_body, read_until_eof)
|
||||||
|
|
||||||
|
cdef object _on_status_complete(self):
|
||||||
|
cdef Py_buffer py_buf
|
||||||
|
if not self._buf:
|
||||||
|
return
|
||||||
|
self._path = self._buf.decode('utf-8', 'surrogateescape')
|
||||||
|
if self._cparser.method == 5: # CONNECT
|
||||||
|
self._url = URL(self._path)
|
||||||
|
else:
|
||||||
|
PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE)
|
||||||
|
try:
|
||||||
|
self._url = _parse_url(<char*>py_buf.buf,
|
||||||
|
py_buf.len)
|
||||||
|
finally:
|
||||||
|
PyBuffer_Release(&py_buf)
|
||||||
|
PyByteArray_Resize(self._buf, 0)
|
||||||
|
|
||||||
|
|
||||||
|
cdef class HttpResponseParser(HttpParser):
|
||||||
|
|
||||||
|
def __init__(self, protocol, loop, int limit, timer=None,
|
||||||
|
size_t max_line_size=8190, size_t max_headers=32768,
|
||||||
|
size_t max_field_size=8190, payload_exception=None,
|
||||||
|
bint response_with_body=True, bint read_until_eof=False,
|
||||||
|
bint auto_decompress=True
|
||||||
|
):
|
||||||
|
self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer,
|
||||||
|
max_line_size, max_headers, max_field_size,
|
||||||
|
payload_exception, response_with_body, read_until_eof,
|
||||||
|
auto_decompress)
|
||||||
|
|
||||||
|
cdef object _on_status_complete(self):
|
||||||
|
if self._buf:
|
||||||
|
self._reason = self._buf.decode('utf-8', 'surrogateescape')
|
||||||
|
PyByteArray_Resize(self._buf, 0)
|
||||||
|
else:
|
||||||
|
self._reason = self._reason or ''
|
||||||
|
|
||||||
|
cdef int cb_on_message_begin(cparser.http_parser* parser) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
|
||||||
|
pyparser._started = True
|
||||||
|
pyparser._headers = CIMultiDict()
|
||||||
|
pyparser._raw_headers = []
|
||||||
|
PyByteArray_Resize(pyparser._buf, 0)
|
||||||
|
pyparser._path = None
|
||||||
|
pyparser._reason = None
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_url(cparser.http_parser* parser,
|
||||||
|
const char *at, size_t length) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
try:
|
||||||
|
if length > pyparser._max_line_size:
|
||||||
|
raise LineTooLong(
|
||||||
|
'Status line is too long', pyparser._max_line_size, length)
|
||||||
|
extend(pyparser._buf, at, length)
|
||||||
|
except BaseException as ex:
|
||||||
|
pyparser._last_error = ex
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_status(cparser.http_parser* parser,
|
||||||
|
const char *at, size_t length) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
cdef str reason
|
||||||
|
try:
|
||||||
|
if length > pyparser._max_line_size:
|
||||||
|
raise LineTooLong(
|
||||||
|
'Status line is too long', pyparser._max_line_size, length)
|
||||||
|
extend(pyparser._buf, at, length)
|
||||||
|
except BaseException as ex:
|
||||||
|
pyparser._last_error = ex
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_header_field(cparser.http_parser* parser,
|
||||||
|
const char *at, size_t length) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
cdef Py_ssize_t size
|
||||||
|
try:
|
||||||
|
pyparser._on_status_complete()
|
||||||
|
size = len(pyparser._raw_name) + length
|
||||||
|
if size > pyparser._max_field_size:
|
||||||
|
raise LineTooLong(
|
||||||
|
'Header name is too long', pyparser._max_field_size, size)
|
||||||
|
pyparser._on_header_field(at, length)
|
||||||
|
except BaseException as ex:
|
||||||
|
pyparser._last_error = ex
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_header_value(cparser.http_parser* parser,
|
||||||
|
const char *at, size_t length) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
cdef Py_ssize_t size
|
||||||
|
try:
|
||||||
|
size = len(pyparser._raw_value) + length
|
||||||
|
if size > pyparser._max_field_size:
|
||||||
|
raise LineTooLong(
|
||||||
|
'Header value is too long', pyparser._max_field_size, size)
|
||||||
|
pyparser._on_header_value(at, length)
|
||||||
|
except BaseException as ex:
|
||||||
|
pyparser._last_error = ex
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
try:
|
||||||
|
pyparser._on_status_complete()
|
||||||
|
pyparser._on_headers_complete()
|
||||||
|
except BaseException as exc:
|
||||||
|
pyparser._last_error = exc
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT
|
||||||
|
return 2
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_body(cparser.http_parser* parser,
|
||||||
|
const char *at, size_t length) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
cdef bytes body = at[:length]
|
||||||
|
try:
|
||||||
|
pyparser._payload.feed_data(body, length)
|
||||||
|
except BaseException as exc:
|
||||||
|
if pyparser._payload_exception is not None:
|
||||||
|
pyparser._payload.set_exception(pyparser._payload_exception(str(exc)))
|
||||||
|
else:
|
||||||
|
pyparser._payload.set_exception(exc)
|
||||||
|
pyparser._payload_error = 1
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_message_complete(cparser.http_parser* parser) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
try:
|
||||||
|
pyparser._started = False
|
||||||
|
pyparser._on_message_complete()
|
||||||
|
except BaseException as exc:
|
||||||
|
pyparser._last_error = exc
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
try:
|
||||||
|
pyparser._on_chunk_header()
|
||||||
|
except BaseException as exc:
|
||||||
|
pyparser._last_error = exc
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1:
|
||||||
|
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||||
|
try:
|
||||||
|
pyparser._on_chunk_complete()
|
||||||
|
except BaseException as exc:
|
||||||
|
pyparser._last_error = exc
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
cdef parser_error_from_errno(cparser.http_errno errno):
|
||||||
|
cdef bytes desc = cparser.http_errno_description(errno)
|
||||||
|
|
||||||
|
if errno in (cparser.HPE_CB_message_begin,
|
||||||
|
cparser.HPE_CB_url,
|
||||||
|
cparser.HPE_CB_header_field,
|
||||||
|
cparser.HPE_CB_header_value,
|
||||||
|
cparser.HPE_CB_headers_complete,
|
||||||
|
cparser.HPE_CB_body,
|
||||||
|
cparser.HPE_CB_message_complete,
|
||||||
|
cparser.HPE_CB_status,
|
||||||
|
cparser.HPE_CB_chunk_header,
|
||||||
|
cparser.HPE_CB_chunk_complete):
|
||||||
|
cls = BadHttpMessage
|
||||||
|
|
||||||
|
elif errno == cparser.HPE_INVALID_STATUS:
|
||||||
|
cls = BadStatusLine
|
||||||
|
|
||||||
|
elif errno == cparser.HPE_INVALID_METHOD:
|
||||||
|
cls = BadStatusLine
|
||||||
|
|
||||||
|
elif errno == cparser.HPE_INVALID_URL:
|
||||||
|
cls = InvalidURLError
|
||||||
|
|
||||||
|
else:
|
||||||
|
cls = BadHttpMessage
|
||||||
|
|
||||||
|
return cls(desc.decode('latin-1'))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_url(url):
|
||||||
|
cdef:
|
||||||
|
Py_buffer py_buf
|
||||||
|
char* buf_data
|
||||||
|
|
||||||
|
PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE)
|
||||||
|
try:
|
||||||
|
buf_data = <char*>py_buf.buf
|
||||||
|
return _parse_url(buf_data, py_buf.len)
|
||||||
|
finally:
|
||||||
|
PyBuffer_Release(&py_buf)
|
||||||
|
|
||||||
|
|
||||||
|
cdef _parse_url(char* buf_data, size_t length):
|
||||||
|
cdef:
|
||||||
|
cparser.http_parser_url* parsed
|
||||||
|
int res
|
||||||
|
str schema = None
|
||||||
|
str host = None
|
||||||
|
object port = None
|
||||||
|
str path = None
|
||||||
|
str query = None
|
||||||
|
str fragment = None
|
||||||
|
str user = None
|
||||||
|
str password = None
|
||||||
|
str userinfo = None
|
||||||
|
object result = None
|
||||||
|
int off
|
||||||
|
int ln
|
||||||
|
|
||||||
|
parsed = <cparser.http_parser_url*> \
|
||||||
|
PyMem_Malloc(sizeof(cparser.http_parser_url))
|
||||||
|
if parsed is NULL:
|
||||||
|
raise MemoryError()
|
||||||
|
cparser.http_parser_url_init(parsed)
|
||||||
|
try:
|
||||||
|
res = cparser.http_parser_parse_url(buf_data, length, 0, parsed)
|
||||||
|
|
||||||
|
if res == 0:
|
||||||
|
if parsed.field_set & (1 << cparser.UF_SCHEMA):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_SCHEMA].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_SCHEMA].len
|
||||||
|
schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
else:
|
||||||
|
schema = ''
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_HOST):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_HOST].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_HOST].len
|
||||||
|
host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
else:
|
||||||
|
host = ''
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_PORT):
|
||||||
|
port = parsed.port
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_PATH):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_PATH].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_PATH].len
|
||||||
|
path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
else:
|
||||||
|
path = ''
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_QUERY):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_QUERY].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_QUERY].len
|
||||||
|
query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
else:
|
||||||
|
query = ''
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_FRAGMENT):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_FRAGMENT].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_FRAGMENT].len
|
||||||
|
fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
else:
|
||||||
|
fragment = ''
|
||||||
|
|
||||||
|
if parsed.field_set & (1 << cparser.UF_USERINFO):
|
||||||
|
off = parsed.field_data[<int>cparser.UF_USERINFO].off
|
||||||
|
ln = parsed.field_data[<int>cparser.UF_USERINFO].len
|
||||||
|
userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
|
||||||
|
|
||||||
|
user, sep, password = userinfo.partition(':')
|
||||||
|
|
||||||
|
return URL_build(scheme=schema,
|
||||||
|
user=user, password=password, host=host, port=port,
|
||||||
|
path=path, query_string=query, fragment=fragment, encoded=True)
|
||||||
|
else:
|
||||||
|
raise InvalidURLError("invalid url {!r}".format(buf_data))
|
||||||
|
finally:
|
||||||
|
PyMem_Free(parsed)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue