{"id":40197680,"url":"https://github.com/oeway/hypha-apps-cli","last_synced_at":"2026-01-19T20:05:38.490Z","repository":{"id":306182125,"uuid":"1025265182","full_name":"oeway/hypha-apps-cli","owner":"oeway","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-25T18:13:32.000Z","size":48,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-26T00:55:50.848Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oeway.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-24T02:10:43.000Z","updated_at":"2025-07-25T18:13:35.000Z","dependencies_parsed_at":"2025-07-26T00:55:58.538Z","dependency_job_id":null,"html_url":"https://github.com/oeway/hypha-apps-cli","commit_stats":null,"previous_names":["oeway/hypha-apps-cli-demo","oeway/hypha-apps-cli"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/oeway/hypha-apps-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oeway%2Fhypha-apps-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oeway%2Fhypha-apps-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oeway%2Fhypha-apps-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oeway%2Fhypha-apps-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oeway","download_url":"https://codeload.github.com/oeway/hypha-apps-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oeway%2Fhypha-apps-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28583644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T19:46:29.903Z","status":"ssl_error","status_checked_at":"2026-01-19T19:45:54.560Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-19T20:05:38.432Z","updated_at":"2026-01-19T20:05:38.482Z","avatar_url":"https://github.com/oeway.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hypha Apps CLI Demo\n\nThis repository demonstrates how to use the Hypha Apps CLI to manage applications on a Hypha server. It includes a simple \"Hello World\" app and comprehensive examples of all CLI commands.\n\n## Overview\n\nThe Hypha Apps CLI (`hypha_apps_cli`) is a command-line tool that allows you to:\n- Install apps to a Hypha server\n- Start and stop running apps\n- List installed and running apps\n- Manage app lifecycles\n- View available services\n\nThe exact CLI implementation can be found in the [hypha-rpc repo](https://github.com/oeway/hypha-rpc/blob/main/python/hypha_rpc/utils/hypha_apps_cli.py).\n\nThis CLI is for managing hypha apps and its artifact, for general artifact access, see [hypha-artifact](https://github.com/aicell-lab/hypha-artifact).\n\n## Understanding App IDs vs Session IDs\n\nIt's important to understand the distinction between **App IDs** and **Session IDs**:\n\n- **App ID**: Think of this as a \"class\" - it's the identifier for an installed app definition. When you install an app, you give it an `app_id`. This represents the app template/blueprint stored on the server.\n\n- **Session ID**: Think of this as an \"instance\" - it's the identifier for a running instance of an app. When you start an app using its `app_id`, the server creates a new session and returns a unique `session_id` for that running instance.\n\n**Example workflow:**\n1. Install app with `--app-id=\"my-calculator\"` → App definition stored on server\n2. Start app using `--app-id=\"my-calculator\"` → Returns `session id: \"ws-user-user1/_rapp_abc123def456\"`  \n3. Multiple sessions can run from the same app → Each gets a different session ID\n4. Stop specific session using `--session-id=\"ws-user-user1/_rapp_abc123def456\"` → Stops that specific instance\n5. Use `stop-all` to stop all running sessions at once\n\nThis allows you to have one app definition but multiple running instances of it.\n\n## Prerequisites\n\nBefore using the CLI, ensure you have:\n\n1. **Python 3.10+** installed\n2. **hypha-rpc \u003e= 0.20.73** installed:\n   ```bash\n   pip install \"hypha-rpc\u003e=0.20.73\"\n   ```\n3. Access to a **Hypha server** (e.g., https://hypha.aicell.io or your self-hosted instance)\n4. A valid **authentication token** from your Hypha server\n\n## Environment Setup\n\n### 1. Create a `.env` file\n\nCreate a `.env` file in your project root with the following configuration:\n\n```bash\n# Hypha Server Configuration\nHYPHA_SERVER_URL=https://hypha.aicell.io # or your own server URL\n# HYPHA_TOKEN=your_token_here\nHYPHA_WORKSPACE=your_workspace_name\n# Optional: Control SSL behavior\nHYPHA_DISABLE_SSL=false   # Set to true/1/yes/on to disable SSL (use plain HTTP)\n```\n\n\nNote that the token will typically valid for 1 day.\n\n### 2. Set Your Workspace\n\nYour workspace name should match the workspace you want to deploy apps to on your Hypha server.\n\n## Token Caching Feature (Recommended)\n\nThe Hypha Apps CLI supports local token caching to improve user experience and reduce the need for repeated logins. **We recommend using the dedicated `login` command to enable token caching.**\n\n### How Token Caching Works\n\n1. **Pre-Login (Recommended)**: Run `python -m hypha_apps_cli login` to authenticate and cache your token\n2. **Token Storage**: Your token is saved to `.hypha_token` in your current directory with secure permissions\n3. **Automatic Reuse**: Subsequent CLI commands automatically use the cached token\n4. **Expiration Handling**: The CLI automatically detects expired tokens and removes them\n5. **Fallback**: If no cached token exists or it's expired, the CLI will prompt for interactive login\n\nAlternatively, you can get your authentication token:\n\n1. Visit your Hypha server dashboard (e.g., https://hypha.aicell.io/public/apps/hypha-login/)\n2. Log in to your account\n3. Expand \"Get Access Token\" and copy the existing token, DO NOT click \"Generate New Token\" (otherwise the generated token won't have admin permission)\n6. Add the token to your `.env` file as `HYPHA_TOKEN`\n\n\n\n## CLI Commands Reference\n\nAll commands use the format:\n```bash\npython -m hypha_apps_cli [COMMAND] [OPTIONS]\n```\n\n(Make sure you have the `hypha_apps_cli` module under your current working directory).\n\n### Global Options\n\n- `--disable-ssl`: Disable SSL (use plain HTTP). Equivalent to setting `HYPHA_DISABLE_SSL=true` in your environment. When set, the CLI will connect to the server without SSL (`ssl=False`).\n\n\u003e **Note:** CLI flags take precedence over environment variables. This option has to be added before the subcommands.\n\n### Example usage\n\n```bash\npython -m hypha_apps_cli --disable-ssl install --app-id hello --manifest=manifest.yaml --source=main.py\n```\n\nor using environment variables:\n\n```bash\nexport HYPHA_DISABLE_SSL=true\npython -m hypha_apps_cli install --app-id hello --manifest=manifest.yaml --source=main.py\n```\n\n### SSL Behavior\n\n- By default, SSL is **enabled** (`ssl=None`), and the CLI will connect using HTTPS.\n- If you pass `--disable-ssl` or set `HYPHA_DISABLE_SSL=true`, SSL is **disabled** (`ssl=False`), and the CLI will connect using plain HTTP.\n\n### Authentication Behavior\n\nThe CLI uses a simple two-step authentication approach:\n\n1. **Environment Variable**: If `HYPHA_TOKEN` is set in your environment, it will be used\n2. **Cached Token**: If no environment token exists, the CLI will try to load a cached token from `.hypha_token` file\n3. **Error**: If neither exists, the CLI will display an error message instructing you to use the `login` command\n\n**No automatic login prompts** - you must explicitly authenticate using the `login` command.\n\n### Login and Cache Token (Recommended First Step)\n\nAuthenticate and cache your token for subsequent commands:\n\n```bash\n# Interactive login and token caching\npython -m hypha_apps_cli login\n```\n\n**Benefits:**\n- **One-time setup**: Login once, use multiple commands without re-authentication\n- **Secure caching**: Token stored with proper file permissions (600)\n- **Automatic expiration**: Expired tokens are automatically detected and removed\n- **Offline-friendly**: No need for interactive login on every command\n\n**Note:** This is the recommended first step before using other CLI commands. The cached token will be automatically used by all subsequent commands unless you have `HYPHA_TOKEN` set in your environment.\n\n### Install an App\n\nInstall an app to the Hypha server:\n\n```bash\n# Basic installation\npython -m hypha_apps_cli install \\\n  --app-id hello \\\n  --manifest=manifest.yaml \\\n  --source=main.py\n\n# Installation with additional files\npython -m hypha_apps_cli install \\\n  --app-id my-complex-app \\\n  --manifest=manifest.yaml \\\n  --source=main.py \\\n  --files=./static\n\n# Installation with overwrite (replace existing app)\npython -m hypha_apps_cli install \\\n  --app-id hello \\\n  --manifest=manifest.yaml \\\n  --source=main.py \\\n  --overwrite\n```\n\n**Options:**\n- `--app-id`: Unique identifier for your app (required)\n- `--source`: Path to your main Python file (required)\n- `--manifest`: Path to your manifest.yaml file (required)\n- `--files`: Path to directory containing additional files (optional)\n- `--overwrite`: Replace existing app if it exists (optional)\n\n### Start an App\n\nStart a previously installed app (creates a new running session):\n\n```bash\npython -m hypha_apps_cli start --app-id hello\n```\n\n**Note:** You can start multiple sessions from the same `app_id`. Each will get a unique `session_id`.\n\n### Stop an App Session\n\nStop a specific running app session using its session ID:\n\n```bash\npython -m hypha_apps_cli stop --session-id \"ws-user-auth0|sdf229udfj234sf/_rapp_cactus-tugboat-90335059__rlb\"\n```\n\n**Note:** You need the `session_id` (not `app_id`) to stop a specific running instance. Get the session ID from `list-running` command.\n\n### Get Logs\n\nGet the logs for the app session:\n```bash\npython -m hypha_apps_cli logs --session-id \"ws-user-auth0|sdf229udfj234sf/_rapp_cactus-tugboat-90335059__rlb\"\n```\n\n**Note:** You need the `session_id` (not `app_id`) to get the logs of a running instance.\n\n### Stop All Apps\n\nStop all currently running apps (stops all sessions regardless of session ID):\n\n```bash\npython -m hypha_apps_cli stop-all\n```\n\n**Note:** This is a convenience command that stops all running sessions without needing individual session IDs.\n\n### Uninstall an App\n\nRemove an app from the server:\n\n```bash\npython -m hypha_apps_cli uninstall --app-id hello\n```\n\n### List Apps\n\nList all installed apps (shows app IDs):\n\n```bash\npython -m hypha_apps_cli list-installed\n```\n\nList all currently running apps (shows session IDs and their corresponding app IDs):\n\n```bash\npython -m hypha_apps_cli list-running\n```\n\n**Output examples:**\n- `list-installed` shows: `Hello World (app_id: hello-demo): A simple hello world app`\n- `list-running` shows: `Hello World (session id: ws-user-hello-demo/fs3abc123, app_id: hello-demo): A simple hello world app`\n\n### List Services\n\nList all available services on the server:\n\n```bash\npython -m hypha_apps_cli list-services\n```\n\n## Working with Additional Files\n\nThe `--files` option allows you to include additional files (static assets, templates, configuration files, etc.) with your Hypha app installation. This is particularly useful for web apps that need CSS, HTML templates, images, or configuration data.\n\n### How File Upload Works\n\nWhen you specify `--files=./directory`, the CLI will:\n\n1. **Recursively scan** the directory for all files\n2. **Automatically detect** file types using MIME types\n3. **Process files** based on their type:\n   - **JSON files** (`.json`): Parsed as JSON objects\n   - **Text files** (`.txt`, `.html`, `.css`, `.js`, `.py`, etc.): Read as text strings\n   - **Binary files** (`.png`, `.jpg`, `.pdf`, etc.): Base64 encoded\n4. **Upload files** with relative paths preserved\n\n\n### File Size and Limitations\n\n**Small files only**: In the CLI, however, since we serialize all the data in one rpc call, it is not recommended to upload large files. The typical use of this is to upload source code files along with some assets.\n**For uploading large files**: You should use [hypha-artifact](https://github.com/aicell-lab/hypha-artifact).\n\n### Tips and Best Practices\n\n1. **Organize files logically** in subdirectories (static/, templates/, data/, etc.)\n2. **Use JSON files** for configuration that your app needs to parse\n3. **Keep binary files small** or consider external hosting for large assets\n4. **Test file uploads** with small examples before deploying large file sets\n5. **Use relative paths** in your HTML/CSS since the directory structure is preserved\n\n## Testing the Demo App\n\nThis repository includes a simple \"Hello World\" app that you can use to test the CLI.\n\n### Automated Test Workflow\n\nFor a quick end-to-end test, use the provided test script:\n\n```bash\npython test_workflow.py\n```\n\nThis script will automatically:\n1. Install the demo app\n2. Start the app\n3. List running apps\n4. Stop the app\n5. Uninstall the app\n\n### Manual Testing Steps\n\nYou can also test manually step by step:\n\n#### 1. Install the demo app (creates app definition with app_id):\n\nBasic installation:\n```bash\npython -m hypha_apps_cli install \\\n  --app-id hello-demo \\\n  --manifest=manifest.yaml \\\n  --source=main.py\n```\n\nOr with example files:\n```bash\npython -m hypha_apps_cli install \\\n  --app-id hello-demo \\\n  --manifest=manifest.yaml \\\n  --source=main.py \\\n  --files=example-files\n```\n\n#### 2. Start the app (creates running instance with session_id):\n```bash\npython -m hypha_apps_cli start --app-id hello-demo\n```\nThis will show you the session ID of the running instance.\n\n#### 3. List running apps to verify (shows both session IDs and app IDs):\n```bash\npython -m hypha_apps_cli list-running\n```\n\n#### 4. Stop the app session when done (using the session ID from step 3):\n```bash\n# First get the session ID from list-running, then use it to stop\npython -m hypha_apps_cli stop --session-id ws-user-user1/_rapp_abc123def456__rlbabc123def456\n```\n\n#### 5. Uninstall the app (removes the app definition):\n```bash\npython -m hypha_apps_cli uninstall --app-id hello-demo\n```\n\n## Example Output\n\nWhen you install and start an app, you'll see output like:\n\n```\n📦 Installing app 'hello-demo' from main.py with manifest manifest.yaml...\n✅ App installation completed\n📦 App info: {\n  \"id\": \"hello-demo\",\n  \"name\": \"Hello World\",\n  \"version\": \"1.0.0\",\n  \"status\": \"installed\"\n}\n✅ App 'hello-demo' successfully installed\n\n🚀 Starting app 'hello-demo'...\n✅ Available services:\n  - setup (): No description\n🚀 Started app 'hello-demo' with session ID: `ws-user-user1/_rapp_abc123def456__rlbabc123def456`\n```\n\nNotice how:\n- The **app ID** is `hello-demo` (the installed app definition)\n- The **session ID** is `ws-user-user1/_rapp_abc123def456__rlbabc123def456` (the running instance)\n\n## Project Structure\n\n```\nmy-hypha-app/\n├── main.py                     # Demo app source code\n├── manifest.yaml               # App configuration\n├── requirements.txt            # Python dependencies\n├── test_workflow.py            # Automated test script\n├── README.md                  # This file\n├── ref-hypha_apps_cli.py      # Reference CLI implementation\n└── example-files/             # Example files for --files option\n    ├── static/\n    │   ├── style.css          # Example CSS file\n    │   └── icon.png           # Example image (binary)\n    ├── templates/\n    │   └── index.html         # Example HTML template\n    └── data/\n        └── config.json        # Example JSON configuration\n```\n\n## Files Explained\n\n### `main.py`\nSimple Hypha app that exports a `setup` function:\n```python\nfrom hypha_rpc import api\n\nasync def setup():\n    print(\"hello\")\n\napi.export({\n    \"config\": {\n        \"visibility\": \"public\",\n    },\n    \"setup\": setup\n})\n```\n\nNote 1: You can add other functions to the export, but `setup` is required which will be called automatically by hypha.\nYou can register or run other function inside `setup`.\nNote 2: The exported function can be sync/async python function `def func` or `async def`.\n\n### `manifest.yaml`\nApp configuration file:\n```yaml\ntype: \"web-python\"\nname: \"Hello World\"\nversion: \"1.0.0\"\nrequirements:\n  - \"hypha-rpc\"\n  - \"pandas\"\n```\n\n## About Hypha Token\n\n### Token Precedence Order\n\nThe CLI attempts to get authentication tokens in this order:\n1. **Environment Variable**: `HYPHA_TOKEN` from your `.env` file or environment\n2. **Cached Token**: Valid token from `.hypha_token` file (created by `login` command)\n3. **Interactive Login**: Prompts for login if no valid token is found\n\n### Recommended Usage Pattern\n\n**Step 1: Pre-authenticate (recommended)**\n```bash\n# Run this once to login and cache your token\npython -m hypha_apps_cli login\n```\n\n**Step 2: Use any CLI commands**\n```bash\n# These will automatically use your cached token\npython -m hypha_apps_cli list-installed\npython -m hypha_apps_cli start --app-id my-app\npython -m hypha_apps_cli stop --session-id \"session_123\"\n```\n\n### Security Features\n\n- **Secure Permissions**: Token files are created with `600` permissions (readable only by owner)\n- **Automatic Cleanup**: Expired tokens are automatically detected and removed\n- **No Version Control**: `.hypha_token` is automatically ignored by git (added to `.gitignore`)\n- **JWT Validation**: Tokens are validated by parsing the JWT payload and checking expiration time\n\n### Token Caching Behavior\n\n- **Only the `login` command saves tokens** - other commands will prompt for login but won't cache the token\n- **Environment tokens take precedence** - if `HYPHA_TOKEN` is set, cached tokens are ignored\n- **Automatic expiration** - expired cached tokens are automatically removed\n\n### Fresh Login\n\nTo get a fresh token (updating your cached token), simply run the login command again:\n\n```bash\n# Get a fresh token and update cache\npython -m hypha_apps_cli login\n```\n\n### Managing Token Files\n\n```bash\n# Pre-login and cache token (recommended)\npython -m hypha_apps_cli login\n\n# View current token file location\nls -la .hypha_token\n\n# Manually remove cached token (forces re-login)\nrm .hypha_token\n\n# Check token file permissions\nls -l .hypha_token\n# Should show: -rw------- (600 permissions)\n```\n\n### Troubleshooting Token Issues\n\n**No cached token:**\n```bash\n# Run the login command to create one\npython -m hypha_apps_cli login\n```\n\n**Token Permission Errors:**\n```bash\n# Fix permissions if needed\nchmod 600 .hypha_token\n```\n\n**Corrupted Token File:**\n```bash\n# Remove corrupted token file and re-login\nrm .hypha_token\npython -m hypha_apps_cli login\n```\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Missing environment variables:**\n   ```\n   ❌ Missing environment variables. Set HYPHA_SERVER_URL, HYPHA_TOKEN, HYPHA_WORKSPACE\n   ```\n   **Solution:** Ensure your `.env` file contains all required variables.\n\n2. **Connection errors:**\n   - Check your `HYPHA_SERVER_URL` is correct\n   - Verify your token is valid and not expired\n   - Ensure your workspace name exists\n\n3. **Permission errors:**\n   - Verify your token has the necessary permissions\n   - Check that you're using the correct workspace\n\n4. **App installation fails:**\n   - Ensure your `manifest.yaml` is valid YAML or JSON\n   - Check that your source file exists and is readable\n   - Try using `--overwrite` if the app already exists\n\n5. **Cannot stop a specific app session:**\n   - The `stop` command requires a `session_id`, not an `app_id`\n   - Get the session ID by running: `python -m hypha_apps_cli list-running`\n   - Use the full session ID (e.g., `ws-user-github|sf3a262/_rapp_cactus-tugboat-90335059__rlb`) with `--session-id` and you need to quote it.\n   - To stop all sessions, use `stop-all` instead\n\n6. **Token caching issues:**\n   - **No cached token**: Run `python -m hypha_apps_cli login` to authenticate and cache your token\n   - **Expired cached token**: The CLI automatically detects and removes expired tokens, but if you encounter issues, manually remove: `rm .hypha_token`\n   - **Permission errors on token file**: Fix with: `chmod 600 .hypha_token`\n   - **Need fresh token**: Run `python -m hypha_apps_cli login` to get a new token\n\n### Getting Help\n\nFor detailed help on any command:\n```bash\npython -m hypha_apps_cli [COMMAND] --help\n```\n\nFor general CLI help:\n```bash\npython -m hypha_apps_cli --help\n```\n\n## Advanced Usage\n\n### Working with Files\n\nWhen using `--files`, you can include additional static files or resources. See the [Working with Additional Files](#working-with-additional-files) section above for comprehensive details.\n\nQuick example:\n```bash\npython -m hypha_apps_cli install \\\n  --app-id my-app \\\n  --manifest=manifest.yaml \\\n  --source=main.py \\\n  --files=./assets\n```\n\nThis will recursively include all files in the `./assets` directory, automatically detecting and processing different file types (text, JSON, binary).\n\n## License\n\nThis demo is provided as-is for educational purposes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foeway%2Fhypha-apps-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foeway%2Fhypha-apps-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foeway%2Fhypha-apps-cli/lists"}