winloop


Namewinloop JSON
Version 0.1.3 PyPI version JSON
download
home_pageNone
SummaryAn alternative library for uvloop compatibility with Windows
upload_time2024-04-29 07:06:24
maintainerNone
docs_urlNone
authorVizonex
requires_pythonNone
licenseMIT
keywords winloop libuv windows cython fast-asyncio uvloop-alternative
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <img src="https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png" width="200px"/>
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>

# Winloop
An Alternative library for uvloop compatability with windows because let's face it. Window's python asyncio standard libaray is garabage escpecially when Windows Defender decides to eat half your ram. 
I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is avalible for windows [but windows was never compatable with uvloop.](https://github.com/MagicStack/uvloop/issues/14#issuecomment-575826367])

Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows compatable by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist. 

The differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed, error handling has been carefully modified and subprocesses instead release the gil instead of forking out...

There is a perfromance increase of about 5 times vs using the `WindowsSelectorEventLoopPolicy` and `WindowsProactorEventLoopPolicy` which have been known to trigger ssl problems in `python 3.9`. Winloop is a very good replacement for solving those ssl problem as well. This library also has comparable performace to it's brother uvloop. 


## How to install Winloop on your Windows Operating System

```
pip install winloop
```

You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions 
to compile this library on your own. 

```
python setup.py build_ext --inplace 
```

## Issues Reporting

If you find any bugs with this library be sure to open up an issue to our github repo. Me and other contributors will be happy try to help you figure out and diagnose your problems.

## Making pull requests 
We encourage anyone to make pull-requests to winloop from spelling mistakes to vulnerability patches. Every little bit helps keep this library maintained and alive.
Make sure that you are able to compile the library with the steps shown above. We plan to implement a nightly workflow to verify one's pull request in the future.




```python
try:
    import aiohttp
    import aiohttp.web
except ImportError:
    skip_tests = True
else:
    skip_tests = False

import asyncio
import unittest
import weakref
import winloop
import sys

class TestAioHTTP(unittest.TestCase):
    def __init__(self, methodName: str = "test_aiohttp_basic_1") -> None:
        super().__init__(methodName)
       

    def setUp(self):
        self.loop = asyncio.get_event_loop()

    def test_aiohttp_basic_1(self):
        PAYLOAD = '<h1>It Works!</h1>' * 10000

        async def on_request(request):
            return aiohttp.web.Response(text=PAYLOAD)

        asyncio.set_event_loop(self.loop)
        app = aiohttp.web.Application()
        app.router.add_get('/', on_request)

        runner = aiohttp.web.AppRunner(app)
        self.loop.run_until_complete(runner.setup())
        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')
        self.loop.run_until_complete(site.start())
        port = site._server.sockets[0].getsockname()[1]

        async def test():
            # Make sure we're using the correct event loop.
            self.assertIs(asyncio.get_event_loop(), self.loop)

            for addr in (('localhost', port),
                         ('127.0.0.1', port)):
                async with aiohttp.ClientSession() as client:
                    async with client.get('http://{}:{}'.format(*addr)) as r:
                        self.assertEqual(r.status, 200)
                        result = await r.text()
                        self.assertEqual(result, PAYLOAD)

        self.loop.run_until_complete(test())
        self.loop.run_until_complete(runner.cleanup())

    def test_aiohttp_graceful_shutdown(self):
        async def websocket_handler(request):
            ws = aiohttp.web.WebSocketResponse()
            await ws.prepare(request)
            request.app['websockets'].add(ws)
            try:
                async for msg in ws:
                    await ws.send_str(msg.data)
            finally:
                request.app['websockets'].discard(ws)
            return ws

        async def on_shutdown(app):
            for ws in set(app['websockets']):
                await ws.close(
                    code=aiohttp.WSCloseCode.GOING_AWAY,
                    message='Server shutdown')

        asyncio.set_event_loop(self.loop)
        app = aiohttp.web.Application()
        app.router.add_get('/', websocket_handler)
        app.on_shutdown.append(on_shutdown)
        app['websockets'] = weakref.WeakSet()

        runner = aiohttp.web.AppRunner(app)
        self.loop.run_until_complete(runner.setup())
        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')
        self.loop.run_until_complete(site.start())
        port = site._server.sockets[0].getsockname()[1]

        async def client():
            async with aiohttp.ClientSession() as client:
                async with client.ws_connect(
                        'http://127.0.0.1:{}'.format(port)) as ws:
                    await ws.send_str("hello")
                    async for msg in ws:
                        assert msg.data == "hello"

        client_task = asyncio.ensure_future(client())

        async def stop():
            await asyncio.sleep(0.1)
            try:
                await asyncio.wait_for(runner.cleanup(), timeout=0.1)
            except Exception as e:
                print(e)
            finally:
                try:
                    client_task.cancel()
                    await client_task
                except asyncio.CancelledError:
                    pass

        self.loop.run_until_complete(stop())



if __name__ == "__main__":
    # print("tesing without winloop")
    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy
    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsProactorEventLoopPolicy
    unittest.main()
    # Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT! 
    print("testing again but with winloop enabled")
    winloop.install()
    unittest.main()
```

The benchmarks for the code above are as follows 

## Benchmarks

### TCP Connections 
-------------------

| Asyncio Event Loop Policy         | Time (in Seconds)     |          
|-----------------------------------|-----------------------|
| WinLoopPolicy                     | 0.493s                |
| WindowsProactorEventLoopPolicy    | 2.510s                |
| WindowsSelectorEventLoopPolicy    | 2.723s                |


That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as 
I modify more of the current test suites made by uvloop...


## How to Use Winloop with Fastapi 

This was a cool little script I put together Just to make fastapi that much faster to handle

```python

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import winloop 
import uvicorn
import asyncio 
import datetime 

app = FastAPI()

@app.on_event("startup")
def make_assertion():
    # Check to make sure that we bypassed the original eventloop Policy....
    assert isinstance(asyncio.get_event_loop_policy(), winloop.WinLoopPolicy)


@app.get("/test")
async def test_get_request():
    return HTMLResponse("<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>")


# starllete will use asyncio.to_thread() so that this can remain asynchronous 
@app.get("/date")
def test_dynamic_response():
    return str(datetime.datetime.now())


# Although tricky to pass and is not normal, it does in fact work...
if __name__ == "__main__":
    winloop.install()
    # Winloop's eventlooppolicy will be passed to uvicorn after this point...
    loop = asyncio.get_event_loop()
    config = uvicorn.Config(app=app,port=10000,loop=loop)
    server = uvicorn.Server(config)
    asyncio.run(server.serve())
```


## How To Use Winloop When Uvloop is not avalible

```python

# Here's A small Example of using winloop when uvloop is not avalible to us
import sys
import aiohttp
import asyncio 

async def main():
    async with aiohttp.ClientSession("https://httpbin.org") as client:
        async with client.get("/ip") as resp:
            print(await resp.json())

if __name__ == "__main__":
    if sys.platform in ('win32', 'cygwin', 'cli'):
        from winloop import run
    else:
        # if we're on apple or linux do this instead
        from uvloop import run 
    run(main())
  ```
  
  
 ## TODO-List

- Update Fastapi Example to a more recent version of fastapi

- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...

- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.

- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time

- Adding in the nessesary hooks for pyinstaller to compile this fast library to executable code even though hooks have been known to inflate the size of the `.exe` files. This is because calling hidden-imports for all the `__init__.py` modules might annoy some developers. (Luckily I'm aware of this issue because I've been doing this myself...)

- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.

- write a workflow for nightly builds if nessesary for verification of pull requests.

- Sphinx Styled Documentation (Maybe I'm thinking about it...)

- Update benchmarks (They are old) can't belive I maintained this project for over a year now...

## Videos
- By me: https://www.youtube.com/watch?v=tz9RYJ6aBZ8  (I might make a tutorial on how to use and install winloop it for those who have reading problems)
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY 

## Contributing
I put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me. 

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "winloop",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "winloop, libuv, windows, cython, fast-asyncio, uvloop-alternative",
    "author": "Vizonex",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/12/fe/c09dfc66e57bbfade39e6e460008588d4dfb1b64d38dbb60a3e373f0d6bb/winloop-0.1.3.tar.gz",
    "platform": "Microsoft Windows",
    "description": "<img src=\"https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png\" width=\"200px\"/>\r\n<a href=\"https://github.com/psf/black\"><img alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"></a>\r\n\r\n# Winloop\r\nAn Alternative library for uvloop compatability with windows because let's face it. Window's python asyncio standard libaray is garabage escpecially when Windows Defender decides to eat half your ram. \r\nI never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is avalible for windows [but windows was never compatable with uvloop.](https://github.com/MagicStack/uvloop/issues/14#issuecomment-575826367])\r\n\r\nBecause nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows compatable by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist. \r\n\r\nThe differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed, error handling has been carefully modified and subprocesses instead release the gil instead of forking out...\r\n\r\nThere is a perfromance increase of about 5 times vs using the `WindowsSelectorEventLoopPolicy` and `WindowsProactorEventLoopPolicy` which have been known to trigger ssl problems in `python 3.9`. Winloop is a very good replacement for solving those ssl problem as well. This library also has comparable performace to it's brother uvloop. \r\n\r\n\r\n## How to install Winloop on your Windows Operating System\r\n\r\n```\r\npip install winloop\r\n```\r\n\r\nYou can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions \r\nto compile this library on your own. \r\n\r\n```\r\npython setup.py build_ext --inplace \r\n```\r\n\r\n## Issues Reporting\r\n\r\nIf you find any bugs with this library be sure to open up an issue to our github repo. Me and other contributors will be happy try to help you figure out and diagnose your problems.\r\n\r\n## Making pull requests \r\nWe encourage anyone to make pull-requests to winloop from spelling mistakes to vulnerability patches. Every little bit helps keep this library maintained and alive.\r\nMake sure that you are able to compile the library with the steps shown above. We plan to implement a nightly workflow to verify one's pull request in the future.\r\n\r\n\r\n\r\n\r\n```python\r\ntry:\r\n    import aiohttp\r\n    import aiohttp.web\r\nexcept ImportError:\r\n    skip_tests = True\r\nelse:\r\n    skip_tests = False\r\n\r\nimport asyncio\r\nimport unittest\r\nimport weakref\r\nimport winloop\r\nimport sys\r\n\r\nclass TestAioHTTP(unittest.TestCase):\r\n    def __init__(self, methodName: str = \"test_aiohttp_basic_1\") -> None:\r\n        super().__init__(methodName)\r\n       \r\n\r\n    def setUp(self):\r\n        self.loop = asyncio.get_event_loop()\r\n\r\n    def test_aiohttp_basic_1(self):\r\n        PAYLOAD = '<h1>It Works!</h1>' * 10000\r\n\r\n        async def on_request(request):\r\n            return aiohttp.web.Response(text=PAYLOAD)\r\n\r\n        asyncio.set_event_loop(self.loop)\r\n        app = aiohttp.web.Application()\r\n        app.router.add_get('/', on_request)\r\n\r\n        runner = aiohttp.web.AppRunner(app)\r\n        self.loop.run_until_complete(runner.setup())\r\n        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')\r\n        self.loop.run_until_complete(site.start())\r\n        port = site._server.sockets[0].getsockname()[1]\r\n\r\n        async def test():\r\n            # Make sure we're using the correct event loop.\r\n            self.assertIs(asyncio.get_event_loop(), self.loop)\r\n\r\n            for addr in (('localhost', port),\r\n                         ('127.0.0.1', port)):\r\n                async with aiohttp.ClientSession() as client:\r\n                    async with client.get('http://{}:{}'.format(*addr)) as r:\r\n                        self.assertEqual(r.status, 200)\r\n                        result = await r.text()\r\n                        self.assertEqual(result, PAYLOAD)\r\n\r\n        self.loop.run_until_complete(test())\r\n        self.loop.run_until_complete(runner.cleanup())\r\n\r\n    def test_aiohttp_graceful_shutdown(self):\r\n        async def websocket_handler(request):\r\n            ws = aiohttp.web.WebSocketResponse()\r\n            await ws.prepare(request)\r\n            request.app['websockets'].add(ws)\r\n            try:\r\n                async for msg in ws:\r\n                    await ws.send_str(msg.data)\r\n            finally:\r\n                request.app['websockets'].discard(ws)\r\n            return ws\r\n\r\n        async def on_shutdown(app):\r\n            for ws in set(app['websockets']):\r\n                await ws.close(\r\n                    code=aiohttp.WSCloseCode.GOING_AWAY,\r\n                    message='Server shutdown')\r\n\r\n        asyncio.set_event_loop(self.loop)\r\n        app = aiohttp.web.Application()\r\n        app.router.add_get('/', websocket_handler)\r\n        app.on_shutdown.append(on_shutdown)\r\n        app['websockets'] = weakref.WeakSet()\r\n\r\n        runner = aiohttp.web.AppRunner(app)\r\n        self.loop.run_until_complete(runner.setup())\r\n        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')\r\n        self.loop.run_until_complete(site.start())\r\n        port = site._server.sockets[0].getsockname()[1]\r\n\r\n        async def client():\r\n            async with aiohttp.ClientSession() as client:\r\n                async with client.ws_connect(\r\n                        'http://127.0.0.1:{}'.format(port)) as ws:\r\n                    await ws.send_str(\"hello\")\r\n                    async for msg in ws:\r\n                        assert msg.data == \"hello\"\r\n\r\n        client_task = asyncio.ensure_future(client())\r\n\r\n        async def stop():\r\n            await asyncio.sleep(0.1)\r\n            try:\r\n                await asyncio.wait_for(runner.cleanup(), timeout=0.1)\r\n            except Exception as e:\r\n                print(e)\r\n            finally:\r\n                try:\r\n                    client_task.cancel()\r\n                    await client_task\r\n                except asyncio.CancelledError:\r\n                    pass\r\n\r\n        self.loop.run_until_complete(stop())\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    # print(\"tesing without winloop\")\r\n    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy\r\n    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsProactorEventLoopPolicy\r\n    unittest.main()\r\n    # Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT! \r\n    print(\"testing again but with winloop enabled\")\r\n    winloop.install()\r\n    unittest.main()\r\n```\r\n\r\nThe benchmarks for the code above are as follows \r\n\r\n## Benchmarks\r\n\r\n### TCP Connections \r\n-------------------\r\n\r\n| Asyncio Event Loop Policy         | Time (in Seconds)     |          \r\n|-----------------------------------|-----------------------|\r\n| WinLoopPolicy                     | 0.493s                |\r\n| WindowsProactorEventLoopPolicy    | 2.510s                |\r\n| WindowsSelectorEventLoopPolicy    | 2.723s                |\r\n\r\n\r\nThat's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as \r\nI modify more of the current test suites made by uvloop...\r\n\r\n\r\n## How to Use Winloop with Fastapi \r\n\r\nThis was a cool little script I put together Just to make fastapi that much faster to handle\r\n\r\n```python\r\n\r\nfrom fastapi import FastAPI\r\nfrom fastapi.responses import HTMLResponse\r\nimport winloop \r\nimport uvicorn\r\nimport asyncio \r\nimport datetime \r\n\r\napp = FastAPI()\r\n\r\n@app.on_event(\"startup\")\r\ndef make_assertion():\r\n    # Check to make sure that we bypassed the original eventloop Policy....\r\n    assert isinstance(asyncio.get_event_loop_policy(), winloop.WinLoopPolicy)\r\n\r\n\r\n@app.get(\"/test\")\r\nasync def test_get_request():\r\n    return HTMLResponse(\"<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>\")\r\n\r\n\r\n# starllete will use asyncio.to_thread() so that this can remain asynchronous \r\n@app.get(\"/date\")\r\ndef test_dynamic_response():\r\n    return str(datetime.datetime.now())\r\n\r\n\r\n# Although tricky to pass and is not normal, it does in fact work...\r\nif __name__ == \"__main__\":\r\n    winloop.install()\r\n    # Winloop's eventlooppolicy will be passed to uvicorn after this point...\r\n    loop = asyncio.get_event_loop()\r\n    config = uvicorn.Config(app=app,port=10000,loop=loop)\r\n    server = uvicorn.Server(config)\r\n    asyncio.run(server.serve())\r\n```\r\n\r\n\r\n## How To Use Winloop When Uvloop is not avalible\r\n\r\n```python\r\n\r\n# Here's A small Example of using winloop when uvloop is not avalible to us\r\nimport sys\r\nimport aiohttp\r\nimport asyncio \r\n\r\nasync def main():\r\n    async with aiohttp.ClientSession(\"https://httpbin.org\") as client:\r\n        async with client.get(\"/ip\") as resp:\r\n            print(await resp.json())\r\n\r\nif __name__ == \"__main__\":\r\n    if sys.platform in ('win32', 'cygwin', 'cli'):\r\n        from winloop import run\r\n    else:\r\n        # if we're on apple or linux do this instead\r\n        from uvloop import run \r\n    run(main())\r\n  ```\r\n  \r\n  \r\n ## TODO-List\r\n\r\n- Update Fastapi Example to a more recent version of fastapi\r\n\r\n- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...\r\n\r\n- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.\r\n\r\n- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time\r\n\r\n- Adding in the nessesary hooks for pyinstaller to compile this fast library to executable code even though hooks have been known to inflate the size of the `.exe` files. This is because calling hidden-imports for all the `__init__.py` modules might annoy some developers. (Luckily I'm aware of this issue because I've been doing this myself...)\r\n\r\n- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.\r\n\r\n- write a workflow for nightly builds if nessesary for verification of pull requests.\r\n\r\n- Sphinx Styled Documentation (Maybe I'm thinking about it...)\r\n\r\n- Update benchmarks (They are old) can't belive I maintained this project for over a year now...\r\n\r\n## Videos\r\n- By me: https://www.youtube.com/watch?v=tz9RYJ6aBZ8  (I might make a tutorial on how to use and install winloop it for those who have reading problems)\r\n- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY \r\n\r\n## Contributing\r\nI put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me. \r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "An alternative library for uvloop compatibility with Windows",
    "version": "0.1.3",
    "project_urls": null,
    "split_keywords": [
        "winloop",
        " libuv",
        " windows",
        " cython",
        " fast-asyncio",
        " uvloop-alternative"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bf7a010c3f331595032f5a6f1ce9fba284adf6df6c44c710e59311f0a2fe4689",
                "md5": "8807d09208da0793d1ec065c08349d94",
                "sha256": "b7b43db0c32d09ea46757b4ef99a181a5d34037ed35ce138a0fbf68d7395e1e7"
            },
            "downloads": -1,
            "filename": "winloop-0.1.3-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8807d09208da0793d1ec065c08349d94",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 1477146,
            "upload_time": "2024-04-29T07:06:17",
            "upload_time_iso_8601": "2024-04-29T07:06:17.284665Z",
            "url": "https://files.pythonhosted.org/packages/bf/7a/010c3f331595032f5a6f1ce9fba284adf6df6c44c710e59311f0a2fe4689/winloop-0.1.3-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "828500624ce43c147e28d814e61563d9852a6fdeac25d665a8193ab2958f0ec4",
                "md5": "c02e88b011439e9ae8d2e748b70bc899",
                "sha256": "5c81f35d39670afd012b96db9574da9433e40dd4233c99959163416ea70bef77"
            },
            "downloads": -1,
            "filename": "winloop-0.1.3-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "c02e88b011439e9ae8d2e748b70bc899",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 1486242,
            "upload_time": "2024-04-29T07:06:19",
            "upload_time_iso_8601": "2024-04-29T07:06:19.464757Z",
            "url": "https://files.pythonhosted.org/packages/82/85/00624ce43c147e28d814e61563d9852a6fdeac25d665a8193ab2958f0ec4/winloop-0.1.3-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7008d5ff151349ac91c3d3ed8e1a5a3f5de319975f37d5f5c12d02da93d9f1ad",
                "md5": "8d29dbe08349af655d235ba9bfb1bfee",
                "sha256": "1d5139693d0a7bfbd274c69165dace52974eed8b23c4736911263ac9a628bd0d"
            },
            "downloads": -1,
            "filename": "winloop-0.1.3-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8d29dbe08349af655d235ba9bfb1bfee",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 1490974,
            "upload_time": "2024-04-29T07:06:21",
            "upload_time_iso_8601": "2024-04-29T07:06:21.139539Z",
            "url": "https://files.pythonhosted.org/packages/70/08/d5ff151349ac91c3d3ed8e1a5a3f5de319975f37d5f5c12d02da93d9f1ad/winloop-0.1.3-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d6bcbc3edaff843bc3eb1b810f6014725abc33039a30c2bd978a58c7a42b8019",
                "md5": "5249f8b127f0facfff79103f1f585d2e",
                "sha256": "4dc4b8ef81cfb17197b7a490404e9f04803e28a46caec1b8e72b3cf80f9f75b8"
            },
            "downloads": -1,
            "filename": "winloop-0.1.3-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "5249f8b127f0facfff79103f1f585d2e",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 1477454,
            "upload_time": "2024-04-29T07:06:22",
            "upload_time_iso_8601": "2024-04-29T07:06:22.774739Z",
            "url": "https://files.pythonhosted.org/packages/d6/bc/bc3edaff843bc3eb1b810f6014725abc33039a30c2bd978a58c7a42b8019/winloop-0.1.3-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "12fec09dfc66e57bbfade39e6e460008588d4dfb1b64d38dbb60a3e373f0d6bb",
                "md5": "18fd046a361b50a8b9c9f3ce1318e17b",
                "sha256": "8c8b56f4852dcbb5b01b811d779a0c59d3093ac0125cc802d12e507014f38b03"
            },
            "downloads": -1,
            "filename": "winloop-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "18fd046a361b50a8b9c9f3ce1318e17b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 872933,
            "upload_time": "2024-04-29T07:06:24",
            "upload_time_iso_8601": "2024-04-29T07:06:24.257259Z",
            "url": "https://files.pythonhosted.org/packages/12/fe/c09dfc66e57bbfade39e6e460008588d4dfb1b64d38dbb60a3e373f0d6bb/winloop-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-29 07:06:24",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "winloop"
}
        
Elapsed time: 0.26105s