allow running client methods syncronously

This commit is contained in:
Izalia Mae 2022-08-10 22:00:06 -04:00
parent 656d58f52d
commit 18944eca58
5 changed files with 95 additions and 30 deletions

View file

@ -1,6 +1,7 @@
import asyncio
from functools import partial
from izzylib.misc import Async
from .config import Config
@ -9,31 +10,20 @@ from ..utils import methods
class Client:
def __init__(self, loop=None, **kwargs):
def __init__(self, **kwargs):
self.cfg = Config(**kwargs)
if not loop:
try:
self.loop = asyncio.get_event_loop()
except:
self.loop = asyncio.new_event_loop()
else:
self.loop = loop
for method in methods:
setattr(self, method.lower(), partial(self.request, method=method))
@Async
async def request(self, *args, **kwargs):
request = self.create_request(*args, **kwargs)
return await self.send_request(request)
@Async
async def send_request(self, request):
connection = asyncio.open_connection(request.host, request.port, ssl=request.secure)
connection = asyncio.open_connection(request.domain, request.port, ssl=request.secure)
reader, writer = await asyncio.wait_for(connection, timeout=self.cfg.timeout)
transport = self.cfg.transport_class(reader, writer, self.cfg.timeout)
@ -47,6 +37,51 @@ class Client:
return self.cfg.response_class(transport, *data)
@Async
async def connect(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='CONNECT')
@Async
async def delete(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='DELETE')
@Async
async def get(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='GET')
@Async
async def head(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='HEAD')
@Async
async def options(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='OPTIONS')
@Async
async def patch(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='PATCH')
@Async
async def post(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='POST')
@Async
async def put(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='PUT')
@Async
async def trace(self, *args, **kwargs):
return await self.request(*args, **kwargs, method='TRACE')
def create_request(self, url, body=b'', headers={}, cookies={}, method='GET', privkey=None, keyid=None):
if (keyid and not privkey) or (not keyid and privkey):
raise ValueError('Please provide a keyid and a privkey, not either')

View file

@ -13,7 +13,7 @@ from ..utils import AsyncTransport
class Config(BaseConfig):
def __init__(self, **kwargs):
super().__init__(
headers = LowerDotDict({'User-Agent': f'IzzyLib/{__version__}'}),
headers = LowerDotDict({'User-Agent': f'IzzyLib-HTTP-Async/{__version__}'}),
request_class = ClientRequest,
response_class = ClientResponse,
transport_class = AsyncTransport,
@ -35,4 +35,4 @@ class Config(BaseConfig):
@property
def agent(self):
return self.headers['user-agent']
return self.headers['User-Agent']

View file

@ -1,7 +1,7 @@
import json
from datetime import datetime
from izzylib import Url
from izzylib.url import Url
from ..utils import (
Headers,
@ -36,7 +36,7 @@ class ClientRequest:
raise ValueError(f'Invalid protocol in url: {self.url.proto}')
if not self.headers.get('host'):
self.headers.host = self.host
self.headers.host = self.url.host
@property
@ -51,8 +51,8 @@ class ClientRequest:
@property
def host(self):
return self.url.host
def domain(self):
return self.url.domain
@property

View file

@ -1,6 +1,8 @@
from asyncio.exceptions import TimeoutError
from functools import partial
from io import BytesIO
from izzylib import DotDict
from izzylib.dotdict import DotDict
from izzylib.misc import Async
from ..utils import (
Cookies,
@ -19,6 +21,22 @@ class ClientResponse:
self.cookies = cookies if type(cookies) == Cookies else Cookies(cookies)
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
async def __aenter__(self):
return self.__enter__()
async def __aexit__(self, *args):
return self.__exit__(*args)
@property
def type(self):
return self.headers.getone('content-type')
@ -34,6 +52,7 @@ class ClientResponse:
return int(self.headers.getone('content-length', 0))
@Async
async def read(self, length=None):
data = await self.transport.read(length or self.length or 8192)
@ -43,17 +62,27 @@ class ClientResponse:
return data
def body(self, encoding=None):
data = self._body.readall()
@Async
async def body(self, encoding=None):
length = self._body.getbuffer().nbytes
if not length or (self.length and self.length > length):
data = await self.read(self.length - length)
else:
data = self._body.readall()
return data.decode(encoding) if encoding else data
def text(self, encoding='utf-8'):
return self.body(encoding)
@Async
async def text(self, encoding='utf-8'):
return await self.body(encoding)
def dict(self):
return DotDict(self.text())
@Async
async def dict(self):
return DotDict(await self.text())
def close(self):

View file

@ -5,7 +5,8 @@ from io import BytesIO
from izzylib import (
DateString,
DotDict,
Url
Url,
logging
)
@ -562,7 +563,7 @@ def parse_headers(raw_headers, request=True):
try: key, value = line.split(': ', 1)
except: continue
if key.lower() == 'cookie':
if key.lower() in ['cookie', 'set-cookie']:
for cookie in value.split(';'):
try:
item = CookieItem.from_string(cookie)