Git Product home page Git Product logo

aiosonic's Introduction

github status Coverage Status PyPI version Documentation Status Discord

aiosonic - lightweight Python asyncio http client

Very fast, lightweight Python asyncio http client

Here is some documentation.

There is a performance script in tests folder which shows very nice numbers

ยป python tests/performance.py
doing tests...
{
 "aiosonic": "1000 requests in 182.03 ms",
 "aiosonic cyclic": "1000 requests in 370.55 ms",
 "aiohttp": "1000 requests in 367.66 ms",
 "requests": "1000 requests in 4613.77 ms",
 "httpx": "1000 requests in 812.41 ms"
}
aiosonic is 101.97% faster than aiohttp
aiosonic is 2434.55% faster than requests
aiosonic is 103.56% faster than aiosonic cyclic
aiosonic is 346.29% faster than httpx

This is a very basic, dummy test, machine dependant. If you look for performance, test and compare your code with this and other packages like aiohttp.

You can perform this test by installing all test dependencies with pip install -e ".[test]" and doing python tests/performance.py in your own machine

Requirements:

  • Python>=3.7
  • PyPy>=3.7

Features:

  • Keepalive and smart pool of connections
  • Multipart File Uploads
  • Chunked responses handling
  • Chunked requests
  • Connection Timeouts
  • Automatic Decompression
  • Follow Redirects
  • Fully type annotated.
  • 100% test coverage (Sometimes not).
  • HTTP2 (BETA) when using the correct flag

Installation

pip install aiosonic

Usage

import asyncio
import aiosonic
import json


async def run():
    client = aiosonic.HTTPClient()

    # ##################
    # Sample get request
    # ##################
    response = await client.get('https://www.google.com/')
    assert response.status_code == 200
    assert 'Google' in (await response.text())

    # ##################
    # Post data as multipart form
    # ##################
    url = "https://postman-echo.com/post"
    posted_data = {'foo': 'bar'}
    response = await client.post(url, data=posted_data)

    assert response.status_code == 200
    data = json.loads(await response.content())
    assert data['form'] == posted_data

    # ##################
    # Posted as json
    # ##################
    response = await client.post(url, json=posted_data)

    assert response.status_code == 200
    data = json.loads(await response.content())
    assert data['json'] == posted_data

    # ##################
    # Sample request + timeout
    # ##################
    from aiosonic.timeout import Timeouts
    timeouts = Timeouts(
        sock_read=10,
        sock_connect=3
    )
    response = await client.get('https://www.google.com/', timeouts=timeouts)
    assert response.status_code == 200
    assert 'Google' in (await response.text())
    await client.shutdown()

    print('success')


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
  • HTTP2
    • Get
    • Request with data sending
    • Do a aiosonic release with stable http2
  • Better documentation
  • International Domains and URLs (idna + cache)
  • Basic/Digest Authentication
  • Requests using a http proxy
  • Sessions with Cookie Persistence
  • Elegant Key/Value Cookies

Development

Install packages with pip-tools:

pip install pip-tools
pip-compile
pip-compile test-requirements.in
pip-sync requirements.txt test-requirements.txt

Contribute

  1. Fork
  2. create a branch feature/your_feature
  3. commit - push - pull request

Thanks :)

Contributors

aiosonic's People

Contributors

alirezabeigy avatar cabaglaban avatar dependabot-preview[bot] avatar dependabot[bot] avatar dibel avatar difeid avatar geraldog avatar jamim avatar pysergio avatar radiophysicist avatar skyoo2003 avatar sonic182 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

aiosonic's Issues

Missing ok property on HttpResponse

Is your feature request related to a problem? Please describe.
Missing ok property on HttpResponse

Describe the solution you'd like
Implement it

sometime throws HttpParsingError

so i do a request to an API but it sometimes raise these errors:

2021-06-27T12:02:51.478515+00:00 app[worker.1]:     return await self.request(url,
2021-06-27T12:02:51.478515+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/aiosonic/__init__.py", line 738, in request
2021-06-27T12:02:51.478516+00:00 app[worker.1]:     response = await wait_for(
2021-06-27T12:02:51.478516+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/asyncio/tasks.py", line 481, in wait_for
2021-06-27T12:02:51.478516+00:00 app[worker.1]:     return fut.result()
2021-06-27T12:02:51.478516+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/aiosonic/__init__.py", line 433, in _do_request
2021-06-27T12:02:51.478518+00:00 app[worker.1]:     async with (await connector.acquire(*args)) as connection:
2021-06-27T12:02:51.478518+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/aiosonic/connectors.py", line 59, in acquire
2021-06-27T12:02:51.478518+00:00 app[worker.1]:     raise HttpParsingError('missing hostname')
2021-06-27T12:02:51.478518+00:00 app[worker.1]: aiosonic.exceptions.HttpParsingError: missing hostname

aiosonic version: 0.10.1

wait_free_pool loops forever without awaiting?

Describe the bug
We saw ConnectionPoolTimeouts in prod and did a code review of the relevant code, and found something unusual - covered by a pragma

To Reproduce
n/a - was a review of code

Expected behavior
The wait_free_pool coroutine does not hot loop forever without awaiting

Screenshots
image

Desktop (please complete the following information):

  • linux

Smartphone (please complete the following information):
n/a

Additional context
It seems to me that if the pool is ever full, this coroutine will loop forever, and the system will never schedule another coroutine. its early so maybe im in space.

proxy support not only in the client, but in requests suggestion

Is your feature request related to a problem? Please describe.
no, its not.

Describe the solution you'd like
i want to have proxy support in requests, like what aiohttp have.

Describe alternatives you've considered
hi. ii'm new to this library, and because of the code I'm creating now, i'm using proxies. since im constantly making requests, i need to switch proxies every once in a while, but with library docs information, you can put the proxy you want to use only in the client and not in the request, like aiohttp can do. so, in a nutshell, can you add proxy support not only in the client but also in requests? thanks!

Error: ssl NPN is deprecated, use ALPN instead

Python version:
Python 3.10.6 (tags/v3.10.6:9c7b4bd, Aug 1 2022, 21:53:49) [MSC v.1932 64 bit (AMD64)] on win32

Mensagge:
aiosonic\connection.py:110: DeprecationWarning: ssl NPN is deprecated, use ALPN instead
negotiated_protocol = tls_conn.selected_npn_protocol()

Is there no auth parameter in the get or post methods?

This seems like a great library for python but I am unable to find in the docs about authenticating a HTTPclient for either get or post. There is an auth param in the Proxy class but none in the HTTPclient class itself!

Help would be greatly appreciated! Thank you!!

HTTPS requests over HTTP proxy problem

Describe the bug
Unable to use proxy to access many https sites.

To Reproduce
Steps to reproduce the behavior:

async with aiosonic.HTTPClient(proxy=Proxy(proxy)) as client:
    resp = await client.get('https://github.com')
    print(resp.status) # 301
    print(resp.headers) # HttpHeaders({'Content-Length': '0', 'Location': 'https://github.com/'})
    resp2 = await client.get('https://github.com/')
    print(resp2.status) # 301
    print(resp2.headers) # HttpHeaders({'Content-Length': '0', 'Location': 'https://github.com/'})

Expected behavior
Response 200

Additional context
After debugging, I found that aiosonic uses the proxy without the CONNECT method to create the tunnel.

Proxy Support

Is your feature request related to a problem? Please describe.
No, It is just a suggestion.

Describe the solution you'd like
I want proxy support for the project.

Describe alternatives you've considered
Alternatives, such as httpx, already have this.

Additional context
N/A

pip install fails in python3.11

There is a problem building the wheel for onecache==0.51 in Python 3.11. When I pip install aiosonic in my venv with python3.11 I get this error:

Building wheels for collected packages: onecache
Building wheel for onecache (setup.py) ... error
error: subprocess-exited-with-error

ร— python setup.py bdist_wheel did not run successfully.
โ”‚ exit code: 1
โ•ฐโ”€> [42 lines of output]
/private/var/folders/vc/_nb0skyd1y99_st51_2xqvvm0000gn/T/pip-install-u6evf5hl/onecache_342b75d5c1fb49028c2d6b7ee886c42c/setup.py:6: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import parse_requirements
/Users/aisha/PycharmProjects/ohlc/venv/lib/python3.11/site-packages/setuptools/dist.py:745: SetuptoolsDeprecationWarning: Invalid dash-separated options
!!

          ********************************************************************************
          Usage of dash-separated 'description-file' will not be supported in future
          versions. Please use the underscore name 'description_file' instead.
  
          By 2023-Sep-26, you need to update your project and remove deprecated calls
          or your builds will no longer be supported.
  
          See https://setuptools.pypa.io/en/latest/userguide/declarative_config.html for details.
          ********************************************************************************
  
  !!
    opt = self.warn_dash_deprecation(opt, section)
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.9-universal2-cpython-311
  creating build/lib.macosx-10.9-universal2-cpython-311/onecache
  copying onecache/__init__.py -> build/lib.macosx-10.9-universal2-cpython-311/onecache
  copying onecache/utils.py -> build/lib.macosx-10.9-universal2-cpython-311/onecache
  copying onecache/cache_value.py -> build/lib.macosx-10.9-universal2-cpython-311/onecache
  running build_ext
  building 'onecache.cache_value' extension
  creating build/temp.macosx-10.9-universal2-cpython-311
  creating build/temp.macosx-10.9-universal2-cpython-311/onecache
  clang -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch arm64 -arch x86_64 -g -I/Users/aisha/PycharmProjects/ohlc/venv/include -I/Library/Frameworks/Python.framework/Versions/3.11/include/python3.11 -c onecache/cache_value.c -o build/temp.macosx-10.9-universal2-cpython-311/onecache/cache_value.o
  onecache/cache_value.c:5187:5: error: incomplete definition of type 'struct _frame'
      __Pyx_PyFrame_SetLineNumber(py_frame, py_line);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  onecache/cache_value.c:444:62: note: expanded from macro '__Pyx_PyFrame_SetLineNumber'
    #define __Pyx_PyFrame_SetLineNumber(frame, lineno)  (frame)->f_lineno = (lineno)
                                                        ~~~~~~~^
  /Library/Frameworks/Python.framework/Versions/3.11/include/python3.11/pytypedefs.h:22:16: note: forward declaration of 'struct _frame'
  typedef struct _frame PyFrameObject;
                 ^
  1 error generated.
  error: command '/usr/bin/clang' failed with exit code 1
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for onecache
Running setup.py clean for onecache
Failed to build onecache
ERROR: Could not build wheels for onecache, which is required to install pyproject.toml-based projects

TypeError in ExpirableCache class

Describe the bug
The get function from ExpirableCache raises an exception TypeError: 'NoneType' object is not subscriptable

To Reproduce
Steps to reproduce the behavior:

  1. create HttpClient()
  2. perform clinet.post(....)
  3. make a timeout
  4. try to make same POST again

Logs

  File "/usr/local/lib/python3.9/dist-packages/aiosonic/__init__.py", line 433, in _do_request
    async with (await connector.acquire(*args)) as connection:
  File "/usr/local/lib/python3.9/dist-packages/aiosonic/connectors.py", line 64, in acquire
    return await self.after_acquire(
  File "/usr/local/lib/python3.9/dist-packages/aiosonic/connectors.py", line 76, in after_acquire
    dns_info = await self.__resolve_dns(
  File "/usr/local/lib/python3.9/dist-packages/aiosonic/connectors.py", line 106, in __resolve_dns
    dns_data = self.cache.get(key)
  File "/usr/local/lib/python3.9/dist-packages/aiosonic/utils.py", line 44, in get
    return data['value']
TypeError: 'NoneType' object is not subscriptable

Desktop (please complete the following information):

  • OS: Debian buster
  • Python: 3.9
  • Aiosonic: 0.10.0

Additional context
Bug in utils.py lines 43-44.

    def get(self, key):
        data = self.cache.get(key)
        if self.timeout and data:
            if datetime.utcnow() > data['expire_at']:
                del self.cache[key]
                **data = None
            return data['value']**
        return data

Not need to try get data['value'] after assignment None

Faster HTTP/2 with libnghttp2 (and easy)

h2 in my experience is terribly slow.

I had much more success with not-so-well known "pynghttp2" which is a ctypes wrapper around the most popular http/2 library in C.
That would be low hanging fruit.

Also you may want to try libh2o, a potentially faster lib.

Header parameter content is overriden in request calls

Describe the bug
Aiosonic request processing overrides given headers parameter. This can cause weird bugs if caller re-uses them. It might be similar with other parameters passed to requests.

To Reproduce

await client.post(post_uri, headers = self._headers, ...)
await client.get(get_uri, headers = self._headers, ...)

What happens
Headers are overridden inside the aiosonic request processing and get call has Content-Type header set to application/x-www-form-urlencoded. This causes some servers to fail, in my case of CloudFront returned mysterious 403 errors.

Additional context
aiosonic==0.11.3

.

wrong issue

HTTPClient context manager gets stuck on exit

Describe the bug

The HTTPClient context manager gets stuck on exit if the response content is not read or the response connection is not released manually.

To Reproduce

async with aiosonic.HTTPClient() as client:
    resp = await client.get('https://github.com')

Expected behavior
Response connection should be released automatically.

Workaround

async with aiosonic.HTTPClient() as client:
    resp = await client.get('https://github.com')
    # either read the response until the end
    print(await resp.content()) 
    # or manually release the response connection
    await resp.connection.release()

ConnectTimeOut

when sending 999 req, it gets stuck for a while (15-20 sec) then throws a connection error.

code:

async def make_req(ses, dx):
   resp = await ses.post(url, json=dx)
   if resp.status_code in (200, 201):
      print("sent data successfully")
   elif resp.status_code == 429:
      await asyncio.sleep(await resp.json()['retry_after'])
async def main():
   async with aiosonic.HTTPClient() as cli:
      await asyncio.gather(*[asyncio. create_task(make_req(cli, ...)) for i in range(999])

error:

Traceback (most recent call last):
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/tasks.py", line 490, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/connection.py", line 48, in connect
    await self._connect(urlparsed, verify, ssl_context, dns_info, http2)
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/connection.py", line 95, in _connect
    self.reader, self.writer = await open_connection(                                                                               ^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/streams.py", line 48, in open_connection
    transport, _ = await loop.create_connection(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/base_events.py", line 1098, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/base_events.py", line 1131, in _create_connection_transport
    await waiter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/connectors.py", line 92, in after_acquire
    await wait_for(
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/tasks.py", line 492, in wait_for
    raise exceptions.TimeoutError() from exc
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/data/data/com.termux/files/home/spam/main.py", line 36, in <module>
    asyncio.run(main())
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/base_events.py", line 650, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/home/spam/main.py", line 32, in main
    async with aiosonic.HTTPClient(TCPConnector(pool_size=999)) as ses:
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/__init__.py", line 508, in __aexit__
    raise exc
  File "/data/data/com.termux/files/home/spam/main.py", line 33, in main
    await asyncio.gather(*[asyncio.create_task(make_req(ses, ...)) for i in range(999)])
  File "/data/data/com.termux/files/home/spam/main.py", line 21, in make_req
    resp = await ses.post(url, json=data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/__init__.py", line 592, in post
    return await self._request_with_body(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/__init__.py", line 538, in _request_with_body
    return await self.request(
           ^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/__init__.py", line 768, in request
    response = await wait_for(
               ^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/__init__.py", line 418, in _do_request
    async with (await connector.acquire(*args)) as connection:
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/connectors.py", line 74, in acquire
    return await self.after_acquire(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/aiosonic/connectors.py", line 97, in after_acquire
    raise ConnectTimeout()
aiosonic.exceptions.ConnectTimeout

RuntimeError: aclose(): asynchronous generator is already running

When im using py-cord with aiosonic, and when im using aiosonic request in slash command, im getting this error.

To Reproduce
Create slash_command using module py-cord
add to func with slash command some aiosonic requests.
Profit

Screenshots
image

Additional context
Same requests from last issue.

An open stream object is being garbage collected; call "stream.close()" explicitly

Describe the bug

Using the following code to test connection ton InfluxDB:

import asyncio
import aiosonic

async def aiosonic_test():
    c = aiosonic.HTTPClient()
    async def get(url):
        r = await c.get(url)
        print(r.status_code, r.headers, await r.text())

    await get("http://127.0.0.1:8086/ping")
    await get("http://127.0.0.1:8086/query?q=SHOW%20DATABASES")

    await c.wait_requests()
    await c.shutdown()

asyncio.run(aiosonic_test())

Works fine but I get an error that the stream was not closed.

An open stream object is being garbage collected; call "stream.close()" explicitly

Desktop (please complete the following information):

  • OS: Ubuntu 18.04.5

Downloading Image Files

Describe the bug
When downloading jpeg files using aiosonic we receive the following:

'utf-8' codec can't decode byte 0x85 in position 2: invalid start byte
Traceback (most recent call last):
  File "./clients/http_client.py", line 28, in query_url
    response = await aiosonic.get("https://example.com/1.jpg")
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aiosonic/__init__.py", line 463, in get
    return await request(url, 'GET', headers, params, connector=connector,
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aiosonic/__init__.py", line 566, in request
    response = await asyncio.wait_for(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/tasks.py", line 455, in wait_for
    return await fut
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aiosonic/__init__.py", line 402, in _do_request
    response._set_response_initial(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aiosonic/__init__.py", line 130, in _set_response_initial
    _HTTP_RESPONSE_STATUS_LINE, data.decode().rstrip('\r\n'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 2: invalid start byte

To Reproduce
Steps to reproduce the behavior:

  1. Use aiosonic to GET a JPEG image link.

Expected behavior
Proper download of image.

Desktop (please complete the following information):

  • OS: MacOS 10.14
  • Browser N/A

Slower than aiohttp

Hello!
I've tried your library and it worked perfect, until I used the follow=True parameter

Here is the test sketch:

import grequests as gr
import asyncio
from aiosonic import HTTPClient
from time import perf_counter
from json import dumps, loads
from aiohttp import ClientSession

class Response:
	def __init__(self, status, headers, content=None):
		self.status_code = status
		self.content = content
		self.text = None
		if self.content is not None:
			self.text = self.content.decode("latin1")
		self.headers = {}
		for h in headers.keys():
			val = headers[h]
			self.headers[h] = val

	def json(self):
		return loads(self.text)

	def __repr__(self):
		return f"<Response [{self.status_code}]>"	# Isn't really needed in this example, just makes responses more comfortable to view

async def request(client, url, include_content):	# AIOSonic request
	resp = await client.get(url, follow=True)	# Follow makes everything much slower
	content = None
	if include_content:
		content = await resp.content()
	resp = Response(resp.status_code, resp.headers, content)
	return resp

async def request_aiohttp(sess, url, include_content):	# AIOHttp request
	async with sess.get(url) as resp:
		content = None
		if include_content:
			content = await resp.read()
		final = Response(resp.status, resp.headers, content)
		return final

async def main(urls, include_content=True, core="aiosonic"):	# Main async method
	client = HTTPClient()	# Client for aiosonic
	sess = ClientSession()	# Client for aiohttp
	resp = []
	for url in urls:
		if core == "aiosonic":
			data = await request(client, url, include_content)
		else:
			data = await request_aiohttp(sess, url, include_content)
		if not data:
			resp.append(None)
			continue
		resp.append(data)
	await client.shutdown()	# Close both clients
	await sess.close()
	return resp

website = "https://google.com"

loop = asyncio.get_event_loop()

fut = asyncio.gather(main([website for _ in range(10)]))	# AIOSonic requests
start = perf_counter()
resp = loop.run_until_complete(fut)
print("AIOSonic:", perf_counter() - start)

fut = asyncio.gather(main([website for _ in range(10)], core="aiohttp"))	# AIOHttp
start = perf_counter()
resp = loop.run_until_complete(fut)
print("AIOHttp:", perf_counter() - start)

start = perf_counter()
reqs = [gr.get(website) for _ in range(10)]
resp = gr.map(reqs)
print("GRequests:", perf_counter() - start)	# GRequests (gevent) [pip install grequests]

My results:

AIOSonic: 0.7438048629992409
AIOHttp: 0.6540690379988519
GRequests: 0.5792230990009557

on a linux server. Maybe it is not fair to compare it with gevent-based one, but it is even slower than aiohttp! Am I doing something wrong or doing redirects requires so much time? Thanks!

aiosonic.exceptions.HttpParsingError: missing hostname

Have this error

Traceback (most recent call last): File "asyncchecker.py", line 46, in check req = await client.post(url, headers={ File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\site-packages\aiosonic\__init__.py", line 663, in post return await self._request_with_body( File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\site-packages\aiosonic\__init__.py", line 609, in _request_with_body return await self.request( File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\site-packages\aiosonic\__init__.py", line 839, in request response = await wait_for( File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\asyncio\tasks.py", line 483, in wait_for return fut.result() File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\site-packages\aiosonic\__init__.py", line 491, in _do_request async with (await connector.acquire(*args)) as connection: File "C:\Users\e\AppData\Local\Programs\Python\Python38\lib\site-packages\aiosonic\connectors.py", line 71, in acquire raise HttpParsingError("missing hostname") aiosonic.exceptions.HttpParsingError: missing hostname

Any idea why is this happening, please ?

Edit: Proxy is the problem, I don't know why tho

RuntimeError: no running event loop

Describe the bug
When im trying create a aiosonic.HTTPClient() class, i getting a error from asyncio "RuntimeError: no running event loop"

To Reproduce
Steps to reproduce the behavior:
Get Python 3.10.4 version and run code with:
import aiosonic
aiosonic.HTTPClient()

Screenshots
Screenshot 1
Screenshot 2

Desktop:

  • OS: [Windows 10, x64, 21H2]
  • Aiosonic Version: [0.14.0]

Post request returns unsupported media type

Describe the bug
Using aiosonic I get a 415 status code.

To Reproduce

  1. set 'Content-Type': "application/json" and "Accept": "application/json" as headers
  2. add a json data

Expected behavior
Getting a 400 status

Screenshots
image
The first status code is from aiohttp with the same headers and json, the second one is from aiosonic using the same headers and json

Desktop (please complete the following information):

  • OS: Windows
  • Browser kk
  • Version kk

Additional context
nothing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.