guapy


Nameguapy JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryPython implementation of Guacamole WebSocket proxy server
upload_time2025-08-28 19:41:24
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords guacamole proxy rdp remote-desktop ssh vnc websocket
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Guapy

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

Guapy is a modern, async Python implementation of the Apache Guacamole WebSocket proxy server. It enables secure, clientless remote desktop access via web browsers, bridging web clients and remote desktop servers using the Guacamole protocol.

---

## Features

- **Multi-Protocol**: RDP, VNC, SSH, Telnet
- **WebSocket Communication**: Real-time, bidirectional
- **Token-Based Security**: AES-encrypted connection tokens
- **Async & Scalable**: Built with FastAPI and asyncio
- **RESTful API**: Health, stats, and management endpoints
- **Flexible Usage**: Use as a library, standalone server, or integrate with your FastAPI app

---

## Installation

```bash
pip install guapy
```

---

## Usage

### 1. Standalone Server See [`examples/standalone_server.py`](examples/standalone_server.py):

```python
import asyncio
import logging

import uvicorn

from guapy import create_server
from guapy.models import ClientOptions, CryptConfig, GuacdOptions

logging.basicConfig(
    level=logging.DEBUG, format="%(asctime)s %(levelname)s %(name)s %(message)s"
)
logger = logging.getLogger(__name__)


async def main():
    """Main function to start the Guapy server."""
    client_options = ClientOptions(
        crypt=CryptConfig(
            cypher="AES-256-CBC",
            key="MySuperSecretKeyForParamsToken12",
        ),
        cors_allow_origins=[
            "http://localhost:3000",  # React dev server
        ],
        cors_allow_credentials=True,
        cors_allow_methods=["GET", "POST", "OPTIONS"],
        cors_allow_headers=["Content-Type", "Authorization"],
    )
    guacd_options = GuacdOptions(host="10.21.34.133", port=4822)
    # guacd_options = GuacdOptions(host="127.0.0.1", port=4822)
    server = create_server(client_options, guacd_options)
    logger.info("Starting Guapy server...")
    logger.info("WebSocket endpoint: ws://localhost:8080/")
    logger.info("Health check: http://localhost:8080/health")
    logger.info("Stats: http://localhost:8080/stats")
    logger.info("Press Ctrl+C to stop")
    config = uvicorn.Config(app=server.app, host="0.0.0.0", port=8080)  # noqa: S104
    server_instance = uvicorn.Server(config)
    await server_instance.serve()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logger.info("Server stopped by user")
    except Exception as e:
        logger.error(f"Server error: {e}")
        raise

```

### 2. CLI Server

Run with flexible config using Typer CLI:

```bash
python -m guapy.cli run --host 0.0.0.0 --port 8080 --guacd-host 127.0.0.1 --guacd-port 4822 --secret-key MySuperSecretKeyForParamsToken12
```

See `python -m guapy.cli --help` for all options.

### 3. Integrate with Your FastAPI App See [`examples/integrated_fastapi_app.py`](examples/integrated_fastapi_app.py):

```python
from fastapi import FastAPI
from guapy import create_server
from guapy.models import ClientOptions, CryptConfig, GuacdOptions

app = FastAPI()

@app.get("/root")
async def root():
    return {"message": "Hello, World!"}

client_options = ClientOptions(
    crypt=CryptConfig(
        cypher="AES-256-CBC",
        key="MySuperSecretKeyForParamsToken12",
    ),
    max_inactivity_time=10000,
)
guacd_options = GuacdOptions(host="127.0.0.1", port=4822)
guapy_server = create_server(client_options, guacd_options)
app.mount("/guapy", guapy_server.app)
```

---

## Configuration

- Use CLI options, environment variables, or a config file (`config.json` or `.env`).
- See `src/guapy/config.py` for details.

---

## API Endpoints

- WebSocket: `ws://localhost:8080/webSocket?token=...`
- REST: `/`, `/health`, `/stats` (or `/guapy/...` if mounted)
- Swagger docs: `/docs` (main app), `/guapy/docs` (mounted Guapy)

---

## Security

- Use strong encryption keys and HTTPS/WSS in production
- Restrict guacd access with firewalls
- Monitor logs for suspicious activity

---

## Development & Examples

- See the `examples/` directory for usage patterns
- Run tests: `uv run pytest`
- Lint: `uv run ruff check .`
- Format: `uv run ruff format .`
- Security audit: `uv run pip-audit`
- Full verification: `uv run python scripts/verify_package.py`

### CI/CD

This project uses GitHub Actions for:
- **Continuous Integration**: Automated testing across Python 3.9-3.13 on Linux, Windows, and macOS
- **Security Scanning**: Dependency vulnerability checks with pip-audit
- **Automated Publishing**: Secure releases to TestPyPI and PyPI using Trusted Publishing
- **Pre-release Support**: Alpha/beta/rc versions automatically go to TestPyPI only

See [PUBLISHING_SETUP.md](PUBLISHING_SETUP.md) for complete setup instructions.

---

## License

MIT. See [LICENSE](LICENSE).

---

## Acknowledgments

- Apache Guacamole project
- FastAPI
- Python asyncio community

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "guapy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "Adithya <adithyakokkirala@gmail.com>",
    "keywords": "guacamole, proxy, rdp, remote-desktop, ssh, vnc, websocket",
    "author": null,
    "author_email": "Adithya <adithyakokkirala@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ec/15/47a29ae3650181d1d7cf42249d196c036059137efc9637a980e7063822d2/guapy-1.0.0.tar.gz",
    "platform": null,
    "description": "# Guapy\n\n[![PyPI version](https://badge.fury.io/py/guapy.svg)](https://badge.fury.io/py/guapy)\n[![Python Support](https://img.shields.io/pypi/pyversions/guapy.svg)](https://pypi.org/project/guapy/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nGuapy is a modern, async Python implementation of the Apache Guacamole WebSocket proxy server. It enables secure, clientless remote desktop access via web browsers, bridging web clients and remote desktop servers using the Guacamole protocol.\n\n---\n\n## Features\n\n- **Multi-Protocol**: RDP, VNC, SSH, Telnet\n- **WebSocket Communication**: Real-time, bidirectional\n- **Token-Based Security**: AES-encrypted connection tokens\n- **Async & Scalable**: Built with FastAPI and asyncio\n- **RESTful API**: Health, stats, and management endpoints\n- **Flexible Usage**: Use as a library, standalone server, or integrate with your FastAPI app\n\n---\n\n## Installation\n\n```bash\npip install guapy\n```\n\n---\n\n## Usage\n\n### 1. Standalone Server See [`examples/standalone_server.py`](examples/standalone_server.py):\n\n```python\nimport asyncio\nimport logging\n\nimport uvicorn\n\nfrom guapy import create_server\nfrom guapy.models import ClientOptions, CryptConfig, GuacdOptions\n\nlogging.basicConfig(\n    level=logging.DEBUG, format=\"%(asctime)s %(levelname)s %(name)s %(message)s\"\n)\nlogger = logging.getLogger(__name__)\n\n\nasync def main():\n    \"\"\"Main function to start the Guapy server.\"\"\"\n    client_options = ClientOptions(\n        crypt=CryptConfig(\n            cypher=\"AES-256-CBC\",\n            key=\"MySuperSecretKeyForParamsToken12\",\n        ),\n        cors_allow_origins=[\n            \"http://localhost:3000\",  # React dev server\n        ],\n        cors_allow_credentials=True,\n        cors_allow_methods=[\"GET\", \"POST\", \"OPTIONS\"],\n        cors_allow_headers=[\"Content-Type\", \"Authorization\"],\n    )\n    guacd_options = GuacdOptions(host=\"10.21.34.133\", port=4822)\n    # guacd_options = GuacdOptions(host=\"127.0.0.1\", port=4822)\n    server = create_server(client_options, guacd_options)\n    logger.info(\"Starting Guapy server...\")\n    logger.info(\"WebSocket endpoint: ws://localhost:8080/\")\n    logger.info(\"Health check: http://localhost:8080/health\")\n    logger.info(\"Stats: http://localhost:8080/stats\")\n    logger.info(\"Press Ctrl+C to stop\")\n    config = uvicorn.Config(app=server.app, host=\"0.0.0.0\", port=8080)  # noqa: S104\n    server_instance = uvicorn.Server(config)\n    await server_instance.serve()\n\n\nif __name__ == \"__main__\":\n    try:\n        asyncio.run(main())\n    except KeyboardInterrupt:\n        logger.info(\"Server stopped by user\")\n    except Exception as e:\n        logger.error(f\"Server error: {e}\")\n        raise\n\n```\n\n### 2. CLI Server\n\nRun with flexible config using Typer CLI:\n\n```bash\npython -m guapy.cli run --host 0.0.0.0 --port 8080 --guacd-host 127.0.0.1 --guacd-port 4822 --secret-key MySuperSecretKeyForParamsToken12\n```\n\nSee `python -m guapy.cli --help` for all options.\n\n### 3. Integrate with Your FastAPI App See [`examples/integrated_fastapi_app.py`](examples/integrated_fastapi_app.py):\n\n```python\nfrom fastapi import FastAPI\nfrom guapy import create_server\nfrom guapy.models import ClientOptions, CryptConfig, GuacdOptions\n\napp = FastAPI()\n\n@app.get(\"/root\")\nasync def root():\n    return {\"message\": \"Hello, World!\"}\n\nclient_options = ClientOptions(\n    crypt=CryptConfig(\n        cypher=\"AES-256-CBC\",\n        key=\"MySuperSecretKeyForParamsToken12\",\n    ),\n    max_inactivity_time=10000,\n)\nguacd_options = GuacdOptions(host=\"127.0.0.1\", port=4822)\nguapy_server = create_server(client_options, guacd_options)\napp.mount(\"/guapy\", guapy_server.app)\n```\n\n---\n\n## Configuration\n\n- Use CLI options, environment variables, or a config file (`config.json` or `.env`).\n- See `src/guapy/config.py` for details.\n\n---\n\n## API Endpoints\n\n- WebSocket: `ws://localhost:8080/webSocket?token=...`\n- REST: `/`, `/health`, `/stats` (or `/guapy/...` if mounted)\n- Swagger docs: `/docs` (main app), `/guapy/docs` (mounted Guapy)\n\n---\n\n## Security\n\n- Use strong encryption keys and HTTPS/WSS in production\n- Restrict guacd access with firewalls\n- Monitor logs for suspicious activity\n\n---\n\n## Development & Examples\n\n- See the `examples/` directory for usage patterns\n- Run tests: `uv run pytest`\n- Lint: `uv run ruff check .`\n- Format: `uv run ruff format .`\n- Security audit: `uv run pip-audit`\n- Full verification: `uv run python scripts/verify_package.py`\n\n### CI/CD\n\nThis project uses GitHub Actions for:\n- **Continuous Integration**: Automated testing across Python 3.9-3.13 on Linux, Windows, and macOS\n- **Security Scanning**: Dependency vulnerability checks with pip-audit\n- **Automated Publishing**: Secure releases to TestPyPI and PyPI using Trusted Publishing\n- **Pre-release Support**: Alpha/beta/rc versions automatically go to TestPyPI only\n\nSee [PUBLISHING_SETUP.md](PUBLISHING_SETUP.md) for complete setup instructions.\n\n---\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n---\n\n## Acknowledgments\n\n- Apache Guacamole project\n- FastAPI\n- Python asyncio community\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python implementation of Guacamole WebSocket proxy server",
    "version": "1.0.0",
    "project_urls": {
        "Changelog": "https://github.com/Adithya1331/guapy/blob/main/CHANGELOG.md",
        "Documentation": "https://guapy.readthedocs.io",
        "Homepage": "https://github.com/Adithya1331/guapy",
        "Issues": "https://github.com/Adithya1331/guapy/issues",
        "Repository": "https://github.com/Adithya1331/guapy.git"
    },
    "split_keywords": [
        "guacamole",
        " proxy",
        " rdp",
        " remote-desktop",
        " ssh",
        " vnc",
        " websocket"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bfe5a67eb9ccf9b8a1745a317c8c43ee4247363810c91f6a242877050a33f5fb",
                "md5": "b0b6f2621ce98c2d672f8cb0a8b68375",
                "sha256": "5c09d3ddf83d6628fdedf6466b2e17d862a1bc107e8516e6b5eba01f97feac71"
            },
            "downloads": -1,
            "filename": "guapy-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b0b6f2621ce98c2d672f8cb0a8b68375",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 26156,
            "upload_time": "2025-08-28T19:41:23",
            "upload_time_iso_8601": "2025-08-28T19:41:23.466147Z",
            "url": "https://files.pythonhosted.org/packages/bf/e5/a67eb9ccf9b8a1745a317c8c43ee4247363810c91f6a242877050a33f5fb/guapy-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ec1547a29ae3650181d1d7cf42249d196c036059137efc9637a980e7063822d2",
                "md5": "79aa0a8b9302b786da690a5e691372fd",
                "sha256": "7e1aad73662f301a99a3b628b149f41d00491f489f3faf227cf77c413214608f"
            },
            "downloads": -1,
            "filename": "guapy-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "79aa0a8b9302b786da690a5e691372fd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 160607,
            "upload_time": "2025-08-28T19:41:24",
            "upload_time_iso_8601": "2025-08-28T19:41:24.879553Z",
            "url": "https://files.pythonhosted.org/packages/ec/15/47a29ae3650181d1d7cf42249d196c036059137efc9637a980e7063822d2/guapy-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-28 19:41:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Adithya1331",
    "github_project": "guapy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "guapy"
}
        
Elapsed time: 1.41775s