websockets-proxy


Namewebsockets-proxy JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryConnect to websockets through a proxy server.
upload_time2024-04-07 10:10:16
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT License Copyright (c) 2023 Andrei Karavatski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords async http http proxy https socks4 socks5 websocket client websocket proxy websockets websockets proxy ws wss
VCS
bugtrack_url
requirements websockets python-socks
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # websockets_proxy

This module will enable you to use [websockets](https://github.com/python-websockets/websockets) package with proxies.

Proxy heavy-lifting is done by [python-socks](https://github.com/romis2012/python-socks) package.

# Usage

To install, use:

```
pip install websockets_proxy
```

All you need is create a proxy object and pass it into `proxy_connect` constructor:

```python
from websockets_proxy import Proxy, proxy_connect


proxy = Proxy.from_url("...")
async with proxy_connect("wss://example.com", proxy=proxy) as ws:
    ...
```

`proxy_connect` constructor accepts the same arguments as regular `connect` constructor, 
with the addition of `proxy` and `proxy_conn_timeout`, which are self-explanatory.

> **With this patch you cannot use `sock` keyword argument, because it is used to connect to a proxy server.**

> **You must create your `Proxy` objects within a running event loop** (inside an `async` function). 
> This is a [python-socks](https://github.com/romis2012/python-socks) limitation. 
> If you define your `Proxy` objects outside of running event loop, you'll get this kind of error: `RuntimeError: Task <Task pending name=...> attached to a different loop`.

# WebSocket proxy checker

## Server
Here is a simple `aiohttp` server, which allows you to check, if your proxy connections work as expected:

```python
import asyncio

from aiohttp import web, WSMsgType, WSMessage


HOST = '0.0.0.0'
PORT = 9999

app = web.Application()


async def websocket_handler(request: web.Request) -> web.StreamResponse:
    ws = web.WebSocketResponse()
    await ws.prepare(request)
    await ws.send_str(str(request.remote))
    await ws.close()
    print('accepted connection from', request.remote)
    return ws


app.add_routes([
    web.get('/', websocket_handler)
])


async def main():
    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, host=HOST, port=PORT)
    await site.start()
    print('server is running')
    await asyncio.Future()


if __name__ == '__main__':
    asyncio.run(main())
```


## Client
An example of a client-side proxy checker script:

```python
import asyncio

from websockets_proxy import Proxy, proxy_connect
from websockets import connect


# this script is written with the above checker server in mind
CHECKER_URL = 'ws://address:port'


async def main():
    async with connect(CHECKER_URL) as ws:
        async for msg in ws:
            ip_no_proxy = msg
            print("Your IP:", ip_no_proxy)
    print('.')
    # be sure to create your "Proxy" objects inside an async function
    proxy = Proxy.from_url("http://login:password@address:port")
    async with proxy_connect(CHECKER_URL, proxy=proxy) as ws:
        async for msg in ws:
            ip_with_proxy = msg
            print("(async with) Proxy IP", ip_with_proxy)
    print('.')

    ws = await proxy_connect(CHECKER_URL, proxy=proxy)
    async for msg in ws:
        ip_with_proxy = msg
        print("(await) Proxy IP", ip_with_proxy)
    await ws.close()
    print('.')


if __name__ == "__main__":
    asyncio.run(main())

```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "websockets-proxy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Andrei Karavatski <verolomnyy@gmail.com>",
    "keywords": "async, http, http proxy, https, socks4, socks5, websocket client, websocket proxy, websockets, websockets proxy, ws, wss",
    "author": null,
    "author_email": "Andrei Karavatski <verolomnyy@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/86/1f/d39627d26c0e16271be505697594ec05f8552d735483d52d7107abfe9eca/websockets_proxy-0.1.2.tar.gz",
    "platform": null,
    "description": "# websockets_proxy\n\nThis module will enable you to use [websockets](https://github.com/python-websockets/websockets) package with proxies.\n\nProxy heavy-lifting is done by [python-socks](https://github.com/romis2012/python-socks) package.\n\n# Usage\n\nTo install, use:\n\n```\npip install websockets_proxy\n```\n\nAll you need is create a proxy object and pass it into `proxy_connect` constructor:\n\n```python\nfrom websockets_proxy import Proxy, proxy_connect\n\n\nproxy = Proxy.from_url(\"...\")\nasync with proxy_connect(\"wss://example.com\", proxy=proxy) as ws:\n    ...\n```\n\n`proxy_connect` constructor accepts the same arguments as regular `connect` constructor, \nwith the addition of `proxy` and `proxy_conn_timeout`, which are self-explanatory.\n\n> **With this patch you cannot use `sock` keyword argument, because it is used to connect to a proxy server.**\n\n> **You must create your `Proxy` objects within a running event loop** (inside an `async` function). \n> This is a [python-socks](https://github.com/romis2012/python-socks) limitation. \n> If you define your `Proxy` objects outside of running event loop, you'll get this kind of error: `RuntimeError: Task <Task pending name=...> attached to a different loop`.\n\n# WebSocket proxy checker\n\n## Server\nHere is a simple `aiohttp` server, which allows you to check, if your proxy connections work as expected:\n\n```python\nimport asyncio\n\nfrom aiohttp import web, WSMsgType, WSMessage\n\n\nHOST = '0.0.0.0'\nPORT = 9999\n\napp = web.Application()\n\n\nasync def websocket_handler(request: web.Request) -> web.StreamResponse:\n    ws = web.WebSocketResponse()\n    await ws.prepare(request)\n    await ws.send_str(str(request.remote))\n    await ws.close()\n    print('accepted connection from', request.remote)\n    return ws\n\n\napp.add_routes([\n    web.get('/', websocket_handler)\n])\n\n\nasync def main():\n    runner = web.AppRunner(app)\n    await runner.setup()\n    site = web.TCPSite(runner, host=HOST, port=PORT)\n    await site.start()\n    print('server is running')\n    await asyncio.Future()\n\n\nif __name__ == '__main__':\n    asyncio.run(main())\n```\n\n\n## Client\nAn example of a client-side proxy checker script:\n\n```python\nimport asyncio\n\nfrom websockets_proxy import Proxy, proxy_connect\nfrom websockets import connect\n\n\n# this script is written with the above checker server in mind\nCHECKER_URL = 'ws://address:port'\n\n\nasync def main():\n    async with connect(CHECKER_URL) as ws:\n        async for msg in ws:\n            ip_no_proxy = msg\n            print(\"Your IP:\", ip_no_proxy)\n    print('.')\n    # be sure to create your \"Proxy\" objects inside an async function\n    proxy = Proxy.from_url(\"http://login:password@address:port\")\n    async with proxy_connect(CHECKER_URL, proxy=proxy) as ws:\n        async for msg in ws:\n            ip_with_proxy = msg\n            print(\"(async with) Proxy IP\", ip_with_proxy)\n    print('.')\n\n    ws = await proxy_connect(CHECKER_URL, proxy=proxy)\n    async for msg in ws:\n        ip_with_proxy = msg\n        print(\"(await) Proxy IP\", ip_with_proxy)\n    await ws.close()\n    print('.')\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n```\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2023 Andrei Karavatski  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "Connect to websockets through a proxy server.",
    "version": "0.1.2",
    "project_urls": {
        "Homepage": "https://github.com/racinette/websockets_proxy",
        "Issues": "https://github.com/racinette/websockets_proxy/issues"
    },
    "split_keywords": [
        "async",
        " http",
        " http proxy",
        " https",
        " socks4",
        " socks5",
        " websocket client",
        " websocket proxy",
        " websockets",
        " websockets proxy",
        " ws",
        " wss"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6bc45f9c41553081f41a03b70edbd2ad5788f3f817432765fa23073141c74459",
                "md5": "b4c3c3ae728da39746862b677a8523c0",
                "sha256": "77fe7bdda558e074b74c932143cd6f68ad58d72db3daa46720a74c9e037b8dfe"
            },
            "downloads": -1,
            "filename": "websockets_proxy-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b4c3c3ae728da39746862b677a8523c0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 5319,
            "upload_time": "2024-04-07T10:10:14",
            "upload_time_iso_8601": "2024-04-07T10:10:14.529823Z",
            "url": "https://files.pythonhosted.org/packages/6b/c4/5f9c41553081f41a03b70edbd2ad5788f3f817432765fa23073141c74459/websockets_proxy-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "861fd39627d26c0e16271be505697594ec05f8552d735483d52d7107abfe9eca",
                "md5": "fb688d3d017691fdc5a0b76bb8d1725b",
                "sha256": "6abe798fcef6d1800a76f8a6dfb4b02ff8f0d8348cae7288a4de9aa89537351d"
            },
            "downloads": -1,
            "filename": "websockets_proxy-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "fb688d3d017691fdc5a0b76bb8d1725b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 4094,
            "upload_time": "2024-04-07T10:10:16",
            "upload_time_iso_8601": "2024-04-07T10:10:16.203134Z",
            "url": "https://files.pythonhosted.org/packages/86/1f/d39627d26c0e16271be505697594ec05f8552d735483d52d7107abfe9eca/websockets_proxy-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-07 10:10:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "racinette",
    "github_project": "websockets_proxy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "websockets",
            "specs": []
        },
        {
            "name": "python-socks",
            "specs": [
                [
                    "==",
                    "2.4.4"
                ]
            ]
        }
    ],
    "lcname": "websockets-proxy"
}
        
Elapsed time: 0.26534s