linksocks


Namelinksocks JSON
Version 1.7.1 PyPI version JSON
download
home_pagehttps://github.com/linksocks/linksocks
SummaryPython bindings for LinkSocks - SOCKS proxy over WebSocket
upload_time2025-08-20 10:45:34
maintainerNone
docs_urlNone
authorjackzzs
requires_python>=3.9
licenseMIT
keywords socks proxy websocket network tunneling firewall bypass load-balancing go bindings
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # LinkSocks Python Bindings

[![PyPI version](https://badge.fury.io/py/linksocks.svg)](https://badge.fury.io/py/linksocks)
[![Python versions](https://img.shields.io/pypi/pyversions/linksocks.svg)](https://pypi.org/project/linksocks/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Python bindings for LinkSocks - a SOCKS5 over WebSocket proxy tool.

## Overview

LinkSocks is a SOCKS proxy implementation over WebSocket protocol that allows you to securely expose SOCKS proxy services under Web Application Firewall (WAF) protection. This package provides Python bindings for the Go implementation.

### Key Features

- 🔄 **Forward & Reverse Proxy**: Support both forward and reverse SOCKS5 proxy modes
- 🌐 **WebSocket Transport**: Works under WAF protection using standard WebSocket connections
- ⚖️ **Load Balancing**: Round-robin load balancing for reverse proxy with multiple clients
- 🔐 **Authentication**: SOCKS5 proxy authentication and secure token-based WebSocket authentication
- 🌍 **Protocol Support**: Full IPv6 over SOCKS5 and UDP over SOCKS5 support
- 🐍 **Pythonic API**: Both synchronous and asynchronous APIs with context manager support

## Installation

### Using pip (Recommended)

```bash
pip install linksocks
```

### Development Installation

```bash
git clone https://github.com/linksocks/linksocks.git
cd linksocks/_bindings/python
pip install -e .
```

### Requirements

- Python 3.8 or later
- Go 1.19 or later (for building from source)

## Quick Start

### Forward Proxy Example

```python
import asyncio
from linksocks import Server, Client

async def main():
    # Create server and client with async context managers
    async with Server(ws_port=8765) as server:
        # Add forward token asynchronously
        token = await server.async_add_forward_token()
        
        async with Client(token, ws_url="ws://localhost:8765", socks_port=9870, no_env_proxy=True) as client:
            print("✅ Forward proxy ready!")
            print("🌐 SOCKS5 proxy: 127.0.0.1:9870")
            print("🔧 Test: curl --socks5 127.0.0.1:9870 http://httpbin.org/ip")
            
            # Keep running
            await asyncio.sleep(3600)

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

### Reverse Proxy Example

```python
import asyncio
from linksocks import Server, Client

async def main():
    # Create server and client with async context managers
    async with Server(ws_port=8765) as server:
        # Add reverse token (port is auto-allocated)
        result = server.add_reverse_token()
        print(f"🔑 Reverse token: {result.token}")
        print(f"🌐 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}")
        
        # Create client in reverse mode
        async with Client(result.token, ws_url="ws://localhost:8765", reverse=True, no_env_proxy=True) as client:
            print("✅ Reverse proxy ready!")
            print(f"🔧 Test: curl --socks5 127.0.0.1:{result.port} http://httpbin.org/ip")
            
            # Keep running
            await asyncio.sleep(3600)

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

## API Reference

### Server Class

The `Server` class manages WebSocket connections and provides SOCKS5 proxy functionality.

```python
from linksocks import Server

# Create server with options
server = Server(
    ws_host="0.0.0.0",           # WebSocket listen address
    ws_port=8765,                # WebSocket listen port  
    socks_host="127.0.0.1",      # SOCKS5 listen address (reverse mode)
    buffer_size=32768,           # Buffer size for data transfer
    api_key="your_api_key",      # Enable HTTP API
    channel_timeout=30.0,        # WebSocket channel timeout (seconds)
    connect_timeout=10.0,        # Connection timeout (seconds)
    fast_open=False,             # Enable fast open optimization
    upstream_proxy="socks5://proxy:1080",  # Upstream proxy
    upstream_username="user",    # Upstream proxy username
    upstream_password="pass"     # Upstream proxy password
)
```

#### Token Management

```python
# Add forward proxy token (synchronous)
token = server.add_forward_token("custom_token")  # or auto-generate with None

# Add forward proxy token (asynchronous - recommended)
token = await server.async_add_forward_token("custom_token")

# Add reverse proxy token
result = server.add_reverse_token(
    token="custom_token",        # optional, auto-generated if None
    port=9870,                   # optional, auto-allocated if None
    username="socks_user",       # optional, SOCKS5 auth username
    password="socks_pass",       # optional, SOCKS5 auth password
    allow_manage_connector=True  # optional, allow client connector management
)
print(f"Token: {result.token}, Port: {result.port}")

# Add connector token  
connector_token = server.add_connector_token("connector_token", "reverse_token")

# Remove any token
success = server.remove_token("token_to_remove")
```

#### Running the Server

```python
# Asynchronous (recommended) - automatically waits for ready
async with server:
    print("Server is ready!")  # No need for async_wait_ready()
    # Server runs while in context

# Synchronous - requires manual wait
server.wait_ready()  # Blocks until ready
# Server runs in background
server.close()  # Clean shutdown

# Manual wait with timeout (only needed for synchronous usage)
server.wait_ready(timeout=30.0)  # 30 second timeout
await server.async_wait_ready(timeout="30s")  # Go duration string (rarely needed)
```

### Client Class

The `Client` class connects to WebSocket servers and provides SOCKS5 functionality.

```python
from linksocks import Client

# Create client with options
client = Client(
    token="your_token",          # Authentication token (required)
    ws_url="ws://localhost:8765", # WebSocket server URL
    reverse=False,               # Enable reverse proxy mode
    socks_host="127.0.0.1",      # SOCKS5 listen address (forward mode)
    socks_port=9870,             # SOCKS5 listen port (forward mode)
    socks_username="user",       # SOCKS5 auth username
    socks_password="pass",       # SOCKS5 auth password
    socks_wait_server=True,      # Wait for server before starting SOCKS5
    reconnect=True,              # Auto-reconnect on disconnect
    reconnect_delay=5.0,         # Reconnect delay (seconds)
    buffer_size=32768,           # Buffer size for data transfer
    channel_timeout=30.0,        # WebSocket channel timeout
    connect_timeout=10.0,        # Connection timeout
    threads=4,                   # Number of processing threads
    fast_open=False,             # Enable fast open optimization
    upstream_proxy="socks5://proxy:1080",  # Upstream proxy
    upstream_username="proxy_user",        # Upstream proxy username
    upstream_password="proxy_pass",        # Upstream proxy password
    no_env_proxy=False           # Ignore proxy environment variables
)
```

#### Running the Client

```python
# Asynchronous (recommended) - automatically waits for ready
async with client:
    print(f"Client ready! SOCKS5 port: {client.socks_port}")
    print(f"Connected: {client.is_connected}")
    # Client runs while in context

# Synchronous - requires manual wait
client.wait_ready()
print(f"Connected: {client.is_connected}")
client.close()  # Clean shutdown
```

#### Connector Management (Reverse Mode)

```python
# Add connector token (reverse mode only)
connector_token = client.add_connector("my_connector")  # or auto-generate
connector_token = await client.async_add_connector(None)  # async version
```

### Logging

```python
import logging
from linksocks import set_log_level

# Set global log level
set_log_level(logging.DEBUG)
set_log_level("INFO")  # String format

# Use custom logger
logger = logging.getLogger("my_app")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)

server = Server(logger=logger)
client = Client("token", logger=logger)
```

## Advanced Examples

### Agent Proxy with Connector Management

```python
import asyncio
from linksocks import Server, Client

async def agent_proxy():
    # Server with connector autonomy enabled
    async with Server(ws_port=8765) as server:
        result = server.add_reverse_token(allow_manage_connector=True)
        print(f"🔑 Provider token: {result.token}")
        print(f"🌐 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}")
        
        # Provider client (provides network access)
        async with Client(result.token, ws_url="ws://localhost:8765", reverse=True, no_env_proxy=True) as provider:
            print("✅ Agent proxy server and provider ready!")
            
            # Provider can manage its own connectors
            connector_token = await provider.async_add_connector("my_connector")
            print(f"🔑 Connector token: {connector_token}")
            
            # Now external connectors can use this token
            print(f"🔧 Start connector: linksocks connector -t {connector_token} -u ws://localhost:8765 -p 1180")
            
            await asyncio.sleep(3600)

asyncio.run(agent_proxy())
```

### Error Handling and Monitoring

```python
import asyncio
import logging
from linksocks import Client

async def robust_client():
    logger = logging.getLogger("robust_client")
    
    client = Client(
        "your_token",
        ws_url="ws://server:8765",
        reconnect=True,
        reconnect_delay=5.0,
        no_env_proxy=True,
        logger=logger
    )
    
    try:
        async with client:
            logger.info("✅ Client connected successfully")
            
            # Monitor connection status
            while True:
                if not client.is_connected:
                    logger.warning("⚠️  Connection lost, reconnecting...")
                    
                await asyncio.sleep(5)
                    
    except asyncio.TimeoutError:
        logger.error("❌ Connection timeout after 30 seconds")
    except Exception as e:
        logger.error(f"❌ Client error: {e}")
    finally:
        logger.info("🔄 Client shutting down")

asyncio.run(robust_client())
```

### HTTP API Integration

```python
import asyncio
import aiohttp
from linksocks import Server

async def api_server_example():
    # Start server with API enabled
    server = Server(ws_port=8765, api_key="secret_api_key")
    
    async with server:
        print("✅ Server with API ready!")
        
        # Use HTTP API to manage tokens
        async with aiohttp.ClientSession() as session:
            headers = {"X-API-Key": "secret_api_key"}
            
            # Add forward token via API
            async with session.post(
                "http://localhost:8765/api/token",
                headers=headers,
                json={"type": "forward", "token": "api_token"}
            ) as resp:
                result = await resp.json()
                print(f"📝 Added token via API: {result}")
            
            # Get server status
            async with session.get(
                "http://localhost:8765/api/status",
                headers=headers
            ) as resp:
                status = await resp.json()
                print(f"📊 Server status: {status}")
        
        await asyncio.sleep(3600)

asyncio.run(api_server_example())
```

## Type Hints

The package includes comprehensive type hints for better IDE support:

```python
from typing import Optional
from linksocks import Server, Client, ReverseTokenResult

def create_proxy_pair(token: str, port: Optional[int] = None) -> tuple[Server, Client]:
    server = Server(ws_port=8765)
    server.add_forward_token(token)
    
    client = Client(token, ws_url="ws://localhost:8765", socks_port=port or 9870, no_env_proxy=True)
    return server, client

# ReverseTokenResult is a dataclass
server = Server(ws_port=8765)
result: ReverseTokenResult = server.add_reverse_token()
print(f"Token: {result.token}, Port: {result.port}")
```

## Comparison with CLI Tool

| Feature | Python Bindings | Go CLI Tool |
|---------|-----------------|-------------|
| **Integration** | Library for Python apps | Standalone binary |
| **API Style** | Object-oriented, async/sync | Command-line flags |
| **Use Cases** | Embedded in applications | Quick setup, scripting |
| **Performance** | Same (uses Go backend) | Same |
| **Features** | Full feature parity | Full feature parity |

## Troubleshooting

### Common Issues

1. **Import Error**: Make sure Go 1.19+ is installed when building from source
2. **Connection Refused**: Check that server is running and ports are correct
3. **Authentication Failed**: Verify tokens match between server and client
4. **Port Already in Use**: Choose different ports or check for existing processes

### Debug Logging

```python
import logging
from linksocks import set_log_level

# Enable debug logging
set_log_level(logging.DEBUG)

# Or use environment variable
import os
os.environ["LINKSOCKS_LOG_LEVEL"] = "DEBUG"
```

### Performance Tuning

```python
# Increase buffer size for high-throughput scenarios
server = Server(buffer_size=65536)
client = Client("token", buffer_size=65536, threads=8)

# Enable fast open for lower latency
server = Server(fast_open=True)
client = Client("token", fast_open=True)
```

## Contributing

We welcome contributions! Please see the main [LinkSocks repository](https://github.com/linksocks/linksocks) for contribution guidelines.

## License

This project is licensed under the MIT License.

## Links

- 📚 [Full Documentation](https://linksocks.github.io/linksocks/)
- 🐛 [Issue Tracker](https://github.com/linksocks/linksocks/issues)
- 💬 [Discussions](https://github.com/linksocks/linksocks/discussions)
- 📦 [PyPI Package](https://pypi.org/project/linksocks/)
- 🐳 [Docker Hub](https://hub.docker.com/r/jackzzs/linksocks)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/linksocks/linksocks",
    "name": "linksocks",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "socks proxy websocket network tunneling firewall bypass load-balancing go bindings",
    "author": "jackzzs",
    "author_email": "jackzzs@outlook.com",
    "download_url": "https://files.pythonhosted.org/packages/d7/7a/1f6230fa830021d463cb89b2a983cd46ef85146d9a66f9fd774e269146a5/linksocks-1.7.1.tar.gz",
    "platform": "any",
    "description": "# LinkSocks Python Bindings\n\n[![PyPI version](https://badge.fury.io/py/linksocks.svg)](https://badge.fury.io/py/linksocks)\n[![Python versions](https://img.shields.io/pypi/pyversions/linksocks.svg)](https://pypi.org/project/linksocks/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nPython bindings for LinkSocks - a SOCKS5 over WebSocket proxy tool.\n\n## Overview\n\nLinkSocks is a SOCKS proxy implementation over WebSocket protocol that allows you to securely expose SOCKS proxy services under Web Application Firewall (WAF) protection. This package provides Python bindings for the Go implementation.\n\n### Key Features\n\n- \ud83d\udd04 **Forward & Reverse Proxy**: Support both forward and reverse SOCKS5 proxy modes\n- \ud83c\udf10 **WebSocket Transport**: Works under WAF protection using standard WebSocket connections\n- \u2696\ufe0f **Load Balancing**: Round-robin load balancing for reverse proxy with multiple clients\n- \ud83d\udd10 **Authentication**: SOCKS5 proxy authentication and secure token-based WebSocket authentication\n- \ud83c\udf0d **Protocol Support**: Full IPv6 over SOCKS5 and UDP over SOCKS5 support\n- \ud83d\udc0d **Pythonic API**: Both synchronous and asynchronous APIs with context manager support\n\n## Installation\n\n### Using pip (Recommended)\n\n```bash\npip install linksocks\n```\n\n### Development Installation\n\n```bash\ngit clone https://github.com/linksocks/linksocks.git\ncd linksocks/_bindings/python\npip install -e .\n```\n\n### Requirements\n\n- Python 3.8 or later\n- Go 1.19 or later (for building from source)\n\n## Quick Start\n\n### Forward Proxy Example\n\n```python\nimport asyncio\nfrom linksocks import Server, Client\n\nasync def main():\n    # Create server and client with async context managers\n    async with Server(ws_port=8765) as server:\n        # Add forward token asynchronously\n        token = await server.async_add_forward_token()\n        \n        async with Client(token, ws_url=\"ws://localhost:8765\", socks_port=9870, no_env_proxy=True) as client:\n            print(\"\u2705 Forward proxy ready!\")\n            print(\"\ud83c\udf10 SOCKS5 proxy: 127.0.0.1:9870\")\n            print(\"\ud83d\udd27 Test: curl --socks5 127.0.0.1:9870 http://httpbin.org/ip\")\n            \n            # Keep running\n            await asyncio.sleep(3600)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Reverse Proxy Example\n\n```python\nimport asyncio\nfrom linksocks import Server, Client\n\nasync def main():\n    # Create server and client with async context managers\n    async with Server(ws_port=8765) as server:\n        # Add reverse token (port is auto-allocated)\n        result = server.add_reverse_token()\n        print(f\"\ud83d\udd11 Reverse token: {result.token}\")\n        print(f\"\ud83c\udf10 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}\")\n        \n        # Create client in reverse mode\n        async with Client(result.token, ws_url=\"ws://localhost:8765\", reverse=True, no_env_proxy=True) as client:\n            print(\"\u2705 Reverse proxy ready!\")\n            print(f\"\ud83d\udd27 Test: curl --socks5 127.0.0.1:{result.port} http://httpbin.org/ip\")\n            \n            # Keep running\n            await asyncio.sleep(3600)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## API Reference\n\n### Server Class\n\nThe `Server` class manages WebSocket connections and provides SOCKS5 proxy functionality.\n\n```python\nfrom linksocks import Server\n\n# Create server with options\nserver = Server(\n    ws_host=\"0.0.0.0\",           # WebSocket listen address\n    ws_port=8765,                # WebSocket listen port  \n    socks_host=\"127.0.0.1\",      # SOCKS5 listen address (reverse mode)\n    buffer_size=32768,           # Buffer size for data transfer\n    api_key=\"your_api_key\",      # Enable HTTP API\n    channel_timeout=30.0,        # WebSocket channel timeout (seconds)\n    connect_timeout=10.0,        # Connection timeout (seconds)\n    fast_open=False,             # Enable fast open optimization\n    upstream_proxy=\"socks5://proxy:1080\",  # Upstream proxy\n    upstream_username=\"user\",    # Upstream proxy username\n    upstream_password=\"pass\"     # Upstream proxy password\n)\n```\n\n#### Token Management\n\n```python\n# Add forward proxy token (synchronous)\ntoken = server.add_forward_token(\"custom_token\")  # or auto-generate with None\n\n# Add forward proxy token (asynchronous - recommended)\ntoken = await server.async_add_forward_token(\"custom_token\")\n\n# Add reverse proxy token\nresult = server.add_reverse_token(\n    token=\"custom_token\",        # optional, auto-generated if None\n    port=9870,                   # optional, auto-allocated if None\n    username=\"socks_user\",       # optional, SOCKS5 auth username\n    password=\"socks_pass\",       # optional, SOCKS5 auth password\n    allow_manage_connector=True  # optional, allow client connector management\n)\nprint(f\"Token: {result.token}, Port: {result.port}\")\n\n# Add connector token  \nconnector_token = server.add_connector_token(\"connector_token\", \"reverse_token\")\n\n# Remove any token\nsuccess = server.remove_token(\"token_to_remove\")\n```\n\n#### Running the Server\n\n```python\n# Asynchronous (recommended) - automatically waits for ready\nasync with server:\n    print(\"Server is ready!\")  # No need for async_wait_ready()\n    # Server runs while in context\n\n# Synchronous - requires manual wait\nserver.wait_ready()  # Blocks until ready\n# Server runs in background\nserver.close()  # Clean shutdown\n\n# Manual wait with timeout (only needed for synchronous usage)\nserver.wait_ready(timeout=30.0)  # 30 second timeout\nawait server.async_wait_ready(timeout=\"30s\")  # Go duration string (rarely needed)\n```\n\n### Client Class\n\nThe `Client` class connects to WebSocket servers and provides SOCKS5 functionality.\n\n```python\nfrom linksocks import Client\n\n# Create client with options\nclient = Client(\n    token=\"your_token\",          # Authentication token (required)\n    ws_url=\"ws://localhost:8765\", # WebSocket server URL\n    reverse=False,               # Enable reverse proxy mode\n    socks_host=\"127.0.0.1\",      # SOCKS5 listen address (forward mode)\n    socks_port=9870,             # SOCKS5 listen port (forward mode)\n    socks_username=\"user\",       # SOCKS5 auth username\n    socks_password=\"pass\",       # SOCKS5 auth password\n    socks_wait_server=True,      # Wait for server before starting SOCKS5\n    reconnect=True,              # Auto-reconnect on disconnect\n    reconnect_delay=5.0,         # Reconnect delay (seconds)\n    buffer_size=32768,           # Buffer size for data transfer\n    channel_timeout=30.0,        # WebSocket channel timeout\n    connect_timeout=10.0,        # Connection timeout\n    threads=4,                   # Number of processing threads\n    fast_open=False,             # Enable fast open optimization\n    upstream_proxy=\"socks5://proxy:1080\",  # Upstream proxy\n    upstream_username=\"proxy_user\",        # Upstream proxy username\n    upstream_password=\"proxy_pass\",        # Upstream proxy password\n    no_env_proxy=False           # Ignore proxy environment variables\n)\n```\n\n#### Running the Client\n\n```python\n# Asynchronous (recommended) - automatically waits for ready\nasync with client:\n    print(f\"Client ready! SOCKS5 port: {client.socks_port}\")\n    print(f\"Connected: {client.is_connected}\")\n    # Client runs while in context\n\n# Synchronous - requires manual wait\nclient.wait_ready()\nprint(f\"Connected: {client.is_connected}\")\nclient.close()  # Clean shutdown\n```\n\n#### Connector Management (Reverse Mode)\n\n```python\n# Add connector token (reverse mode only)\nconnector_token = client.add_connector(\"my_connector\")  # or auto-generate\nconnector_token = await client.async_add_connector(None)  # async version\n```\n\n### Logging\n\n```python\nimport logging\nfrom linksocks import set_log_level\n\n# Set global log level\nset_log_level(logging.DEBUG)\nset_log_level(\"INFO\")  # String format\n\n# Use custom logger\nlogger = logging.getLogger(\"my_app\")\nlogger.setLevel(logging.DEBUG)\nhandler = logging.StreamHandler()\nhandler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))\nlogger.addHandler(handler)\n\nserver = Server(logger=logger)\nclient = Client(\"token\", logger=logger)\n```\n\n## Advanced Examples\n\n### Agent Proxy with Connector Management\n\n```python\nimport asyncio\nfrom linksocks import Server, Client\n\nasync def agent_proxy():\n    # Server with connector autonomy enabled\n    async with Server(ws_port=8765) as server:\n        result = server.add_reverse_token(allow_manage_connector=True)\n        print(f\"\ud83d\udd11 Provider token: {result.token}\")\n        print(f\"\ud83c\udf10 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}\")\n        \n        # Provider client (provides network access)\n        async with Client(result.token, ws_url=\"ws://localhost:8765\", reverse=True, no_env_proxy=True) as provider:\n            print(\"\u2705 Agent proxy server and provider ready!\")\n            \n            # Provider can manage its own connectors\n            connector_token = await provider.async_add_connector(\"my_connector\")\n            print(f\"\ud83d\udd11 Connector token: {connector_token}\")\n            \n            # Now external connectors can use this token\n            print(f\"\ud83d\udd27 Start connector: linksocks connector -t {connector_token} -u ws://localhost:8765 -p 1180\")\n            \n            await asyncio.sleep(3600)\n\nasyncio.run(agent_proxy())\n```\n\n### Error Handling and Monitoring\n\n```python\nimport asyncio\nimport logging\nfrom linksocks import Client\n\nasync def robust_client():\n    logger = logging.getLogger(\"robust_client\")\n    \n    client = Client(\n        \"your_token\",\n        ws_url=\"ws://server:8765\",\n        reconnect=True,\n        reconnect_delay=5.0,\n        no_env_proxy=True,\n        logger=logger\n    )\n    \n    try:\n        async with client:\n            logger.info(\"\u2705 Client connected successfully\")\n            \n            # Monitor connection status\n            while True:\n                if not client.is_connected:\n                    logger.warning(\"\u26a0\ufe0f  Connection lost, reconnecting...\")\n                    \n                await asyncio.sleep(5)\n                    \n    except asyncio.TimeoutError:\n        logger.error(\"\u274c Connection timeout after 30 seconds\")\n    except Exception as e:\n        logger.error(f\"\u274c Client error: {e}\")\n    finally:\n        logger.info(\"\ud83d\udd04 Client shutting down\")\n\nasyncio.run(robust_client())\n```\n\n### HTTP API Integration\n\n```python\nimport asyncio\nimport aiohttp\nfrom linksocks import Server\n\nasync def api_server_example():\n    # Start server with API enabled\n    server = Server(ws_port=8765, api_key=\"secret_api_key\")\n    \n    async with server:\n        print(\"\u2705 Server with API ready!\")\n        \n        # Use HTTP API to manage tokens\n        async with aiohttp.ClientSession() as session:\n            headers = {\"X-API-Key\": \"secret_api_key\"}\n            \n            # Add forward token via API\n            async with session.post(\n                \"http://localhost:8765/api/token\",\n                headers=headers,\n                json={\"type\": \"forward\", \"token\": \"api_token\"}\n            ) as resp:\n                result = await resp.json()\n                print(f\"\ud83d\udcdd Added token via API: {result}\")\n            \n            # Get server status\n            async with session.get(\n                \"http://localhost:8765/api/status\",\n                headers=headers\n            ) as resp:\n                status = await resp.json()\n                print(f\"\ud83d\udcca Server status: {status}\")\n        \n        await asyncio.sleep(3600)\n\nasyncio.run(api_server_example())\n```\n\n## Type Hints\n\nThe package includes comprehensive type hints for better IDE support:\n\n```python\nfrom typing import Optional\nfrom linksocks import Server, Client, ReverseTokenResult\n\ndef create_proxy_pair(token: str, port: Optional[int] = None) -> tuple[Server, Client]:\n    server = Server(ws_port=8765)\n    server.add_forward_token(token)\n    \n    client = Client(token, ws_url=\"ws://localhost:8765\", socks_port=port or 9870, no_env_proxy=True)\n    return server, client\n\n# ReverseTokenResult is a dataclass\nserver = Server(ws_port=8765)\nresult: ReverseTokenResult = server.add_reverse_token()\nprint(f\"Token: {result.token}, Port: {result.port}\")\n```\n\n## Comparison with CLI Tool\n\n| Feature | Python Bindings | Go CLI Tool |\n|---------|-----------------|-------------|\n| **Integration** | Library for Python apps | Standalone binary |\n| **API Style** | Object-oriented, async/sync | Command-line flags |\n| **Use Cases** | Embedded in applications | Quick setup, scripting |\n| **Performance** | Same (uses Go backend) | Same |\n| **Features** | Full feature parity | Full feature parity |\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Import Error**: Make sure Go 1.19+ is installed when building from source\n2. **Connection Refused**: Check that server is running and ports are correct\n3. **Authentication Failed**: Verify tokens match between server and client\n4. **Port Already in Use**: Choose different ports or check for existing processes\n\n### Debug Logging\n\n```python\nimport logging\nfrom linksocks import set_log_level\n\n# Enable debug logging\nset_log_level(logging.DEBUG)\n\n# Or use environment variable\nimport os\nos.environ[\"LINKSOCKS_LOG_LEVEL\"] = \"DEBUG\"\n```\n\n### Performance Tuning\n\n```python\n# Increase buffer size for high-throughput scenarios\nserver = Server(buffer_size=65536)\nclient = Client(\"token\", buffer_size=65536, threads=8)\n\n# Enable fast open for lower latency\nserver = Server(fast_open=True)\nclient = Client(\"token\", fast_open=True)\n```\n\n## Contributing\n\nWe welcome contributions! Please see the main [LinkSocks repository](https://github.com/linksocks/linksocks) for contribution guidelines.\n\n## License\n\nThis project is licensed under the MIT License.\n\n## Links\n\n- \ud83d\udcda [Full Documentation](https://linksocks.github.io/linksocks/)\n- \ud83d\udc1b [Issue Tracker](https://github.com/linksocks/linksocks/issues)\n- \ud83d\udcac [Discussions](https://github.com/linksocks/linksocks/discussions)\n- \ud83d\udce6 [PyPI Package](https://pypi.org/project/linksocks/)\n- \ud83d\udc33 [Docker Hub](https://hub.docker.com/r/jackzzs/linksocks)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python bindings for LinkSocks - SOCKS proxy over WebSocket",
    "version": "1.7.1",
    "project_urls": {
        "Bug Reports": "https://github.com/linksocks/linksocks/issues",
        "Changelog": "https://github.com/linksocks/linksocks/releases",
        "Documentation": "https://github.com/linksocks/linksocks#readme",
        "Homepage": "https://github.com/linksocks/linksocks",
        "Source": "https://github.com/linksocks/linksocks"
    },
    "split_keywords": [
        "socks",
        "proxy",
        "websocket",
        "network",
        "tunneling",
        "firewall",
        "bypass",
        "load-balancing",
        "go",
        "bindings"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e7448cc59c6dd55c8796066d36e7e1f1ed787144e1145a04fafd09ec0b535391",
                "md5": "4f8f3d1a758db2a4ef7a898e18f8016b",
                "sha256": "19e279b7545b8bd1ee3ed952fe3e8c6cba4d4f32996b91feb61e323a362615f9"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp310-cp310-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "4f8f3d1a758db2a4ef7a898e18f8016b",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 3789103,
            "upload_time": "2025-08-20T10:44:57",
            "upload_time_iso_8601": "2025-08-20T10:44:57.053284Z",
            "url": "https://files.pythonhosted.org/packages/e7/44/8cc59c6dd55c8796066d36e7e1f1ed787144e1145a04fafd09ec0b535391/linksocks-1.7.1-cp310-cp310-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5cbcbde43a191cde265a953449e86ab05aa34943a81acb8f5cddacc758a44ef7",
                "md5": "d0228ef260ce2648b9cd7157e28c6bfa",
                "sha256": "33190b1b4dfb295fafc2ce35e9dd72a137e4ae8d77ec29e02da236032815cb90"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp310-cp310-macosx_14_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "d0228ef260ce2648b9cd7157e28c6bfa",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 3568627,
            "upload_time": "2025-08-20T10:44:59",
            "upload_time_iso_8601": "2025-08-20T10:44:59.400766Z",
            "url": "https://files.pythonhosted.org/packages/5c/bc/bde43a191cde265a953449e86ab05aa34943a81acb8f5cddacc758a44ef7/linksocks-1.7.1-cp310-cp310-macosx_14_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bd8fe5028871849bf5c7b1069d22622c655a852fe94b7e381cbcb1043fc460ed",
                "md5": "d94a1e659596f4567e96bcd2a289e56f",
                "sha256": "adea24b22be7ddef9ddc27e9be62fc7eeb0860392ff492f4d3b0901682f99650"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "has_sig": false,
            "md5_digest": "d94a1e659596f4567e96bcd2a289e56f",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 6821375,
            "upload_time": "2025-08-20T10:45:01",
            "upload_time_iso_8601": "2025-08-20T10:45:01.211000Z",
            "url": "https://files.pythonhosted.org/packages/bd/8f/e5028871849bf5c7b1069d22622c655a852fe94b7e381cbcb1043fc460ed/linksocks-1.7.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "75342094fe53991fb7f924b5cdc76f63b2e3e8bdde0e71bfe09a73a7e1cb9a58",
                "md5": "22266f2426b457ef0fde425f0d73d663",
                "sha256": "7e2dae23d92a19d4fa8a415501872928e10e167584e70714a55bf27b62d9f462"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "22266f2426b457ef0fde425f0d73d663",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 7665446,
            "upload_time": "2025-08-20T10:45:03",
            "upload_time_iso_8601": "2025-08-20T10:45:03.181760Z",
            "url": "https://files.pythonhosted.org/packages/75/34/2094fe53991fb7f924b5cdc76f63b2e3e8bdde0e71bfe09a73a7e1cb9a58/linksocks-1.7.1-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9b2f0841e728500ebc61608b3558d7eaba7cce2c07e7acaba3ee86bfdc06b3f4",
                "md5": "780ddacca89cda028dc4bf507a9496a5",
                "sha256": "890e6a2205dff976e586cc268d44e136cce241d66b1c52622c11f7c6795cf923"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp311-cp311-macosx_13_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "780ddacca89cda028dc4bf507a9496a5",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 3789783,
            "upload_time": "2025-08-20T10:45:04",
            "upload_time_iso_8601": "2025-08-20T10:45:04.998434Z",
            "url": "https://files.pythonhosted.org/packages/9b/2f/0841e728500ebc61608b3558d7eaba7cce2c07e7acaba3ee86bfdc06b3f4/linksocks-1.7.1-cp311-cp311-macosx_13_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0fadfa54497acd0b7166f8ba7ad274f8c3b74e73e5c84f9d2c341f677e8f80d8",
                "md5": "d61cc1b4ca49061906da04309ef1d7ce",
                "sha256": "1ef20203fab420b79fb4a4172d3af0b36bc3aff5ce18ee1746057ff2d447ed8f"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp311-cp311-macosx_14_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "d61cc1b4ca49061906da04309ef1d7ce",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 3570009,
            "upload_time": "2025-08-20T10:45:06",
            "upload_time_iso_8601": "2025-08-20T10:45:06.646915Z",
            "url": "https://files.pythonhosted.org/packages/0f/ad/fa54497acd0b7166f8ba7ad274f8c3b74e73e5c84f9d2c341f677e8f80d8/linksocks-1.7.1-cp311-cp311-macosx_14_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e235048397631fc7dadad3e6300bc5465f17c833186125cefc262c127eecaa49",
                "md5": "46df0ce2948083892e22961d4217636a",
                "sha256": "d860985cda9299825de126b89ea4dd39af01020e5c12c83df4166a644421014b"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "has_sig": false,
            "md5_digest": "46df0ce2948083892e22961d4217636a",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 6824687,
            "upload_time": "2025-08-20T10:45:08",
            "upload_time_iso_8601": "2025-08-20T10:45:08.403035Z",
            "url": "https://files.pythonhosted.org/packages/e2/35/048397631fc7dadad3e6300bc5465f17c833186125cefc262c127eecaa49/linksocks-1.7.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3deaa2039389ede6416eff8f28a4db610fb6365a7ac4ddf6067e7ad8b4adbfdd",
                "md5": "0ce47996187496e2ada2935e6bc60271",
                "sha256": "b2ee1b431e39b65905d499496426e8c949cfb58d0cce0c944339edb193f34a6c"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "0ce47996187496e2ada2935e6bc60271",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 7667648,
            "upload_time": "2025-08-20T10:45:10",
            "upload_time_iso_8601": "2025-08-20T10:45:10.307362Z",
            "url": "https://files.pythonhosted.org/packages/3d/ea/a2039389ede6416eff8f28a4db610fb6365a7ac4ddf6067e7ad8b4adbfdd/linksocks-1.7.1-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "27112d5f93db941783856e55d527f8eab36da325961573a8df55f1e284035206",
                "md5": "e9ca86ffce880dc2559799eb875bd8d1",
                "sha256": "90a80c8d4c702849aac316a69a1106b054bf776ffec71b130a2690aead62ed60"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp312-cp312-macosx_13_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "e9ca86ffce880dc2559799eb875bd8d1",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 3791556,
            "upload_time": "2025-08-20T10:45:12",
            "upload_time_iso_8601": "2025-08-20T10:45:12.461685Z",
            "url": "https://files.pythonhosted.org/packages/27/11/2d5f93db941783856e55d527f8eab36da325961573a8df55f1e284035206/linksocks-1.7.1-cp312-cp312-macosx_13_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "44e9ef81f64ecbd0028f1b12d9c69b4a1d6383cd49f065383434afcce15d793c",
                "md5": "0443a9c251a27dce4f04fdedf9646e82",
                "sha256": "4f2eb02fbebbd4b59ca556a812b2b7251dfad8a4b203eccd64211c3cfe5f8a89"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp312-cp312-macosx_14_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "0443a9c251a27dce4f04fdedf9646e82",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 3569419,
            "upload_time": "2025-08-20T10:45:15",
            "upload_time_iso_8601": "2025-08-20T10:45:15.312799Z",
            "url": "https://files.pythonhosted.org/packages/44/e9/ef81f64ecbd0028f1b12d9c69b4a1d6383cd49f065383434afcce15d793c/linksocks-1.7.1-cp312-cp312-macosx_14_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bb6ba1f13407ff2e65d7d2849c363359c40562e2b22312fc77661918da89e823",
                "md5": "2a23aeac9cb6b135ef0554b903185358",
                "sha256": "f3f535a2901723928ca18641cfb2f121dc6d94ae1571dd25db3235a4366d9431"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2a23aeac9cb6b135ef0554b903185358",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 6822169,
            "upload_time": "2025-08-20T10:45:17",
            "upload_time_iso_8601": "2025-08-20T10:45:17.268407Z",
            "url": "https://files.pythonhosted.org/packages/bb/6b/a1f13407ff2e65d7d2849c363359c40562e2b22312fc77661918da89e823/linksocks-1.7.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "60a7c7950e961ae28963a066340627affdf09f83aa88c4fcdeb62c30ad61a3e9",
                "md5": "a1c2661d03a639285342a2ac7162af85",
                "sha256": "ec3b97523439ebf20adfc62c7124b751d8d47df44bf33f829c964871cc4bd0f7"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "a1c2661d03a639285342a2ac7162af85",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 7667211,
            "upload_time": "2025-08-20T10:45:19",
            "upload_time_iso_8601": "2025-08-20T10:45:19.475178Z",
            "url": "https://files.pythonhosted.org/packages/60/a7/c7950e961ae28963a066340627affdf09f83aa88c4fcdeb62c30ad61a3e9/linksocks-1.7.1-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ac064136d85ed6514a1546063ee06473806cd385f4c41f38346e4d442b5c4a29",
                "md5": "6941d8371d5c06ad7dbe00968f8ec0c5",
                "sha256": "ec53f8af531925f94944f9ec39a040e8d19681809f65f0acc61a1151a91d8cf6"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp313-cp313-macosx_13_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "6941d8371d5c06ad7dbe00968f8ec0c5",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 3789770,
            "upload_time": "2025-08-20T10:45:21",
            "upload_time_iso_8601": "2025-08-20T10:45:21.822376Z",
            "url": "https://files.pythonhosted.org/packages/ac/06/4136d85ed6514a1546063ee06473806cd385f4c41f38346e4d442b5c4a29/linksocks-1.7.1-cp313-cp313-macosx_13_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "27dada4d655aad0439cf5d94d0011c7dd28ea7eb5c135923ad2138c42bd3d4d7",
                "md5": "d6b6bd656bc87c0a4ef8cdecd8f8128e",
                "sha256": "0605f82f1c0af56f81681e72332640d31720956da4d179cc3b3f9e58969b638b"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp313-cp313-macosx_14_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "d6b6bd656bc87c0a4ef8cdecd8f8128e",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 3569914,
            "upload_time": "2025-08-20T10:45:23",
            "upload_time_iso_8601": "2025-08-20T10:45:23.435151Z",
            "url": "https://files.pythonhosted.org/packages/27/da/da4d655aad0439cf5d94d0011c7dd28ea7eb5c135923ad2138c42bd3d4d7/linksocks-1.7.1-cp313-cp313-macosx_14_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "28eb61054c0f6269d5b310d44bf0641348081cdac5b694b8bd8144b64a9fd10e",
                "md5": "18df1b96bc6d6bf02a2e1a524417cee7",
                "sha256": "845688580775b615797c99604d46621452426f0ce34dd20c102e01f6175ca283"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "has_sig": false,
            "md5_digest": "18df1b96bc6d6bf02a2e1a524417cee7",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 6821870,
            "upload_time": "2025-08-20T10:45:25",
            "upload_time_iso_8601": "2025-08-20T10:45:25.159292Z",
            "url": "https://files.pythonhosted.org/packages/28/eb/61054c0f6269d5b310d44bf0641348081cdac5b694b8bd8144b64a9fd10e/linksocks-1.7.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "41cb8366885482ce6bee3dca0f0477606d963304a7052fa7b36db1b4c9dffda4",
                "md5": "c69810dfdc7719cb5d56ed69fdbcba80",
                "sha256": "a76c94964bbbb2ef4735fbdd03fbc59890e6d4530b2a767863ad493c63e53a1c"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp39-cp39-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c69810dfdc7719cb5d56ed69fdbcba80",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 3789050,
            "upload_time": "2025-08-20T10:45:27",
            "upload_time_iso_8601": "2025-08-20T10:45:27.288868Z",
            "url": "https://files.pythonhosted.org/packages/41/cb/8366885482ce6bee3dca0f0477606d963304a7052fa7b36db1b4c9dffda4/linksocks-1.7.1-cp39-cp39-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "486ccb5dc9d78364ace0f33aa74f234b3e5b9a915b5ba1aef2f99142e428a97e",
                "md5": "eab7dd4466258bbee0a92f733baee213",
                "sha256": "b2d4746a0be32ac51be511f17c48b3ba98a2a565f5c0de7f3bbbbe2fba29467d"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp39-cp39-macosx_14_0_universal2.whl",
            "has_sig": false,
            "md5_digest": "eab7dd4466258bbee0a92f733baee213",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 3567949,
            "upload_time": "2025-08-20T10:45:28",
            "upload_time_iso_8601": "2025-08-20T10:45:28.921579Z",
            "url": "https://files.pythonhosted.org/packages/48/6c/cb5dc9d78364ace0f33aa74f234b3e5b9a915b5ba1aef2f99142e428a97e/linksocks-1.7.1-cp39-cp39-macosx_14_0_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "22bdc6d94d2d360efc3f123c76daa0ec26084d840a0acbe472dcb8b32f64771e",
                "md5": "f3024c9d7acf1453ca2ae9b9718ef455",
                "sha256": "c72582a1114a4111884c585613a33053428d75c9ab479e7abee5e3fff3e8f6d8"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp39-cp39-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "has_sig": false,
            "md5_digest": "f3024c9d7acf1453ca2ae9b9718ef455",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 6820295,
            "upload_time": "2025-08-20T10:45:30",
            "upload_time_iso_8601": "2025-08-20T10:45:30.668361Z",
            "url": "https://files.pythonhosted.org/packages/22/bd/c6d94d2d360efc3f123c76daa0ec26084d840a0acbe472dcb8b32f64771e/linksocks-1.7.1-cp39-cp39-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cbdf87d4175dbef23122c8f697bbaf932c4737fa6bb9bde78a3bce79112d7770",
                "md5": "0b24d02391f0dbf8247ee190a7d647de",
                "sha256": "fe65bf3b3bbb1423081158149745fd849219026471840d132e0172aecc6a5f53"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "0b24d02391f0dbf8247ee190a7d647de",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 7665209,
            "upload_time": "2025-08-20T10:45:32",
            "upload_time_iso_8601": "2025-08-20T10:45:32.963201Z",
            "url": "https://files.pythonhosted.org/packages/cb/df/87d4175dbef23122c8f697bbaf932c4737fa6bb9bde78a3bce79112d7770/linksocks-1.7.1-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d77a1f6230fa830021d463cb89b2a983cd46ef85146d9a66f9fd774e269146a5",
                "md5": "ee98b9c3ee29643bafc974e2ec1d67b1",
                "sha256": "2ee2c00b936d7819c47670134696b2b2f2c08c561b95ba8d837a2bc9c4f35e88"
            },
            "downloads": -1,
            "filename": "linksocks-1.7.1.tar.gz",
            "has_sig": false,
            "md5_digest": "ee98b9c3ee29643bafc974e2ec1d67b1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 88170,
            "upload_time": "2025-08-20T10:45:34",
            "upload_time_iso_8601": "2025-08-20T10:45:34.778312Z",
            "url": "https://files.pythonhosted.org/packages/d7/7a/1f6230fa830021d463cb89b2a983cd46ef85146d9a66f9fd774e269146a5/linksocks-1.7.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-20 10:45:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "linksocks",
    "github_project": "linksocks",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "linksocks"
}
        
Elapsed time: 1.83846s