hle-client 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ name: Update Homebrew Formula
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ update-formula:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - name: Derive version from tag
13
+ run: |
14
+ VERSION="${GITHUB_REF_NAME#v}"
15
+ echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
16
+
17
+ - name: Wait for PyPI availability
18
+ run: |
19
+ echo "Waiting for hle-client==${VERSION} on PyPI..."
20
+ for i in $(seq 1 30); do
21
+ if pip index versions hle-client 2>/dev/null | grep -q "$VERSION"; then
22
+ echo "Package available on PyPI"
23
+ exit 0
24
+ fi
25
+ echo "Attempt $i/30 — waiting 20s..."
26
+ sleep 20
27
+ done
28
+ echo "Timed out waiting for PyPI"
29
+ exit 1
30
+
31
+ - name: Checkout homebrew-tap
32
+ uses: actions/checkout@v4
33
+ with:
34
+ repository: hle-world/homebrew-tap
35
+ token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
36
+
37
+ - name: Set up Python
38
+ uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.13"
41
+
42
+ - name: Update formula
43
+ run: |
44
+ pip install homebrew-pypi-poet "hle-client==${VERSION}"
45
+
46
+ # Generate resource stanzas
47
+ RESOURCES=$(poet hle-client 2>/dev/null | sed -n '/^ resource/,/^ end$/p')
48
+
49
+ # Get sdist SHA256
50
+ pip download "hle-client==${VERSION}" --no-deps --no-binary :all: -d /tmp/hle-sdist
51
+ SHA256=$(sha256sum /tmp/hle-sdist/*.tar.gz | cut -d' ' -f1)
52
+ SDIST_URL="https://files.pythonhosted.org/packages/source/h/hle-client/hle_client-${VERSION}.tar.gz"
53
+
54
+ mkdir -p Formula
55
+ cat > Formula/hle-client.rb << FORMULA
56
+ class HleClient < Formula
57
+ include Language::Python::Virtualenv
58
+
59
+ desc "Home Lab Everywhere — Expose homelab services with built-in SSO"
60
+ homepage "https://hle.world"
61
+ url "${SDIST_URL}"
62
+ sha256 "${SHA256}"
63
+ license "MIT"
64
+
65
+ depends_on "python@3.13"
66
+
67
+ ${RESOURCES}
68
+
69
+ def install
70
+ virtualenv_install_with_resources
71
+ end
72
+
73
+ test do
74
+ assert_match version.to_s, shell_output("#{bin}/hle --version")
75
+ end
76
+ end
77
+ FORMULA
78
+
79
+ - name: Commit and push
80
+ run: |
81
+ git config user.name "github-actions[bot]"
82
+ git config user.email "github-actions[bot]@users.noreply.github.com"
83
+ git add Formula/hle-client.rb
84
+ git commit -m "Update hle-client to ${VERSION}"
85
+ git push
@@ -0,0 +1,61 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.13"
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v4
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ uv venv
28
+ uv pip install -e ".[dev]"
29
+
30
+ - name: Lint
31
+ run: |
32
+ source .venv/bin/activate
33
+ ruff check src/ tests/
34
+ ruff format --check src/ tests/
35
+
36
+ - name: Test
37
+ run: |
38
+ source .venv/bin/activate
39
+ pytest tests/ -v
40
+
41
+ publish:
42
+ needs: test
43
+ runs-on: ubuntu-latest
44
+ environment: pypi
45
+
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+
49
+ - name: Set up Python
50
+ uses: actions/setup-python@v5
51
+ with:
52
+ python-version: "3.13"
53
+
54
+ - name: Install build tools
55
+ run: pip install build
56
+
57
+ - name: Build sdist and wheel
58
+ run: python -m build
59
+
60
+ - name: Publish to PyPI
61
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,48 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v4
26
+
27
+ - name: Install dependencies
28
+ run: |
29
+ uv venv
30
+ uv pip install -e ".[dev]"
31
+
32
+ - name: Lint
33
+ run: |
34
+ source .venv/bin/activate
35
+ ruff check src/ tests/
36
+ ruff format --check src/ tests/
37
+
38
+ - name: Test
39
+ run: |
40
+ source .venv/bin/activate
41
+ pytest tests/ -v
42
+
43
+ - name: Verify imports
44
+ run: |
45
+ source .venv/bin/activate
46
+ python -c "from hle_client.cli import main; print('CLI import OK')"
47
+ python -c "from hle_common.protocol import MessageType; print('Protocol import OK')"
48
+ python -c "from hle_common.models import TunnelRegistration; print('Models import OK')"
@@ -0,0 +1,34 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ dist/
8
+ build/
9
+ *.whl
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+ ENV/
15
+
16
+ # IDE
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+ *~
22
+
23
+ # OS
24
+ .DS_Store
25
+ Thumbs.db
26
+
27
+ # Testing
28
+ .pytest_cache/
29
+ .coverage
30
+ htmlcov/
31
+ .mypy_cache/
32
+
33
+ # Distribution
34
+ *.tar.gz
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## v0.4.0 — 2026-02-19
4
+
5
+ Initial public release of the HLE client, extracted from the monorepo as a standalone package.
6
+
7
+ - First PyPI release with `pip install hle-client`
8
+ - Curl installer script at `https://get.hle.world`
9
+ - Homebrew tap at `hle-world/tap/hle-client`
10
+ - Fixed race condition in WebSocket stream handling (`_ws_streams` now protected by `asyncio.Lock`)
11
+ - Fixed empty body handling: `is not None` checks instead of truthiness for base64 bodies
12
+ - CLI commands: `expose`, `tunnels`, `access` (list/add/remove), `pin` (set/remove/status), `share` (create/list/revoke), `webhook` (placeholder)
13
+ - API key resolution: `--api-key` flag > `HLE_API_KEY` env var > `~/.config/hle/config.toml`
14
+ - WebSocket multiplexing with automatic reconnection and exponential backoff
15
+ - CI with Python 3.11/3.12/3.13 matrix testing
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Home Lab Everywhere
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.4
2
+ Name: hle-client
3
+ Version: 0.4.0
4
+ Summary: Home Lab Everywhere — Expose homelab services to the internet with built-in SSO
5
+ Project-URL: Homepage, https://hle.world
6
+ Project-URL: Repository, https://github.com/hle-world/hle-client
7
+ Project-URL: Issues, https://github.com/hle-world/hle-client/issues
8
+ Author: Home Lab Everywhere
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: homelab,reverse-proxy,sso,tunnel,webhook
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: System :: Networking
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: click>=8.1
21
+ Requires-Dist: cryptography>=43.0
22
+ Requires-Dist: httpx>=0.27
23
+ Requires-Dist: pydantic-settings>=2.0
24
+ Requires-Dist: pydantic>=2.0
25
+ Requires-Dist: pyjwt>=2.9
26
+ Requires-Dist: rich>=13.0
27
+ Requires-Dist: websockets>=13.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.13; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=6.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.8; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # HLE Client
37
+
38
+ [![PyPI](https://img.shields.io/pypi/v/hle-client)](https://pypi.org/project/hle-client/)
39
+ [![Python](https://img.shields.io/pypi/pyversions/hle-client)](https://pypi.org/project/hle-client/)
40
+ [![License](https://img.shields.io/github/license/hle-world/hle-client)](LICENSE)
41
+ [![CI](https://github.com/hle-world/hle-client/actions/workflows/test.yml/badge.svg)](https://github.com/hle-world/hle-client/actions/workflows/test.yml)
42
+
43
+ **Home Lab Everywhere** — Expose homelab services to the internet with built-in SSO authentication and WebSocket support.
44
+
45
+ One command: `hle expose --service http://localhost:8080`
46
+
47
+ Your local service gets a public URL like `myapp-x7k.hle.world` with automatic HTTPS and SSO protection.
48
+
49
+ ## Install
50
+
51
+ ### pip (or pipx)
52
+
53
+ ```bash
54
+ pip install hle-client
55
+ # or
56
+ pipx install hle-client
57
+ ```
58
+
59
+ ### Curl installer
60
+
61
+ ```bash
62
+ curl -fsSL https://get.hle.world | sh
63
+ ```
64
+
65
+ Installs via pipx (preferred), uv, or pip-in-venv. Supports `--version`:
66
+
67
+ ```bash
68
+ curl -fsSL https://get.hle.world | sh -s -- --version 0.4.0
69
+ ```
70
+
71
+ ### Homebrew
72
+
73
+ ```bash
74
+ brew install hle-world/tap/hle-client
75
+ ```
76
+
77
+ ## Quick Start
78
+
79
+ 1. **Sign up** at [hle.world](https://hle.world) and create an API key in the dashboard.
80
+
81
+ 2. **Expose a service:**
82
+
83
+ ```bash
84
+ hle expose --service http://localhost:8080 --api-key hle_your_key_here
85
+ ```
86
+
87
+ The API key is saved to `~/.config/hle/config.toml` after first use, so you only need to provide it once.
88
+
89
+ ## CLI Usage
90
+
91
+ ### `hle expose`
92
+
93
+ Expose a local service to the internet.
94
+
95
+ ```bash
96
+ hle expose --service http://localhost:8080 # Basic usage
97
+ hle expose --service http://localhost:8080 --label ha # Custom subdomain label
98
+ hle expose --service http://localhost:3000 --auth none # Disable SSO
99
+ hle expose --service http://localhost:8080 --no-websocket # Disable WS proxying
100
+ ```
101
+
102
+ Options:
103
+ - `--service` — Local service URL (required)
104
+ - `--label` — Service label for the subdomain (e.g. `ha` → `ha-x7k.hle.world`)
105
+ - `--auth` — Auth mode: `sso` (default) or `none`
106
+ - `--websocket/--no-websocket` — Enable/disable WebSocket proxying (default: enabled)
107
+ - `--api-key` — API key (also reads `HLE_API_KEY` env var, then config file)
108
+ - `--relay-host` — Relay server host (default: `hle.world`)
109
+ - `--relay-port` — Relay server port (default: `443`)
110
+
111
+ ### `hle tunnels`
112
+
113
+ List your active tunnels.
114
+
115
+ ```bash
116
+ hle tunnels
117
+ ```
118
+
119
+ ### `hle access`
120
+
121
+ Manage per-tunnel email allow-lists for SSO access.
122
+
123
+ ```bash
124
+ hle access list myapp-x7k # List access rules
125
+ hle access add myapp-x7k friend@example.com # Allow an email
126
+ hle access add myapp-x7k dev@co.com --provider github # Require GitHub SSO
127
+ hle access remove myapp-x7k 42 # Remove rule by ID
128
+ ```
129
+
130
+ ### `hle pin`
131
+
132
+ Manage PIN-based access control for tunnels.
133
+
134
+ ```bash
135
+ hle pin set myapp-x7k # Set a PIN (prompts for 4-8 digit PIN)
136
+ hle pin status myapp-x7k # Check PIN status
137
+ hle pin remove myapp-x7k # Remove PIN
138
+ ```
139
+
140
+ ### `hle share`
141
+
142
+ Create and manage temporary share links.
143
+
144
+ ```bash
145
+ hle share create myapp-x7k # 24h link (default)
146
+ hle share create myapp-x7k --duration 1h # 1-hour link
147
+ hle share create myapp-x7k --max-uses 5 # Limited uses
148
+ hle share list myapp-x7k # List share links
149
+ hle share revoke myapp-x7k 42 # Revoke a link
150
+ ```
151
+
152
+ ### Global Options
153
+
154
+ ```bash
155
+ hle --version # Show version
156
+ hle --debug ... # Enable debug logging
157
+ ```
158
+
159
+ ## Configuration
160
+
161
+ The HLE client stores configuration in `~/.config/hle/config.toml`:
162
+
163
+ ```toml
164
+ api_key = "hle_your_key_here"
165
+ ```
166
+
167
+ API key resolution order:
168
+ 1. `--api-key` CLI flag
169
+ 2. `HLE_API_KEY` environment variable
170
+ 3. `~/.config/hle/config.toml`
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ git clone https://github.com/hle-world/hle-client.git
176
+ cd hle-client
177
+ uv venv && source .venv/bin/activate
178
+ uv pip install -e ".[dev]"
179
+
180
+ # Run tests
181
+ pytest
182
+
183
+ # Lint
184
+ ruff check src/ tests/
185
+ ruff format --check src/ tests/
186
+ ```
187
+
188
+ ## License
189
+
190
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,155 @@
1
+ # HLE Client
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/hle-client)](https://pypi.org/project/hle-client/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/hle-client)](https://pypi.org/project/hle-client/)
5
+ [![License](https://img.shields.io/github/license/hle-world/hle-client)](LICENSE)
6
+ [![CI](https://github.com/hle-world/hle-client/actions/workflows/test.yml/badge.svg)](https://github.com/hle-world/hle-client/actions/workflows/test.yml)
7
+
8
+ **Home Lab Everywhere** — Expose homelab services to the internet with built-in SSO authentication and WebSocket support.
9
+
10
+ One command: `hle expose --service http://localhost:8080`
11
+
12
+ Your local service gets a public URL like `myapp-x7k.hle.world` with automatic HTTPS and SSO protection.
13
+
14
+ ## Install
15
+
16
+ ### pip (or pipx)
17
+
18
+ ```bash
19
+ pip install hle-client
20
+ # or
21
+ pipx install hle-client
22
+ ```
23
+
24
+ ### Curl installer
25
+
26
+ ```bash
27
+ curl -fsSL https://get.hle.world | sh
28
+ ```
29
+
30
+ Installs via pipx (preferred), uv, or pip-in-venv. Supports `--version`:
31
+
32
+ ```bash
33
+ curl -fsSL https://get.hle.world | sh -s -- --version 0.4.0
34
+ ```
35
+
36
+ ### Homebrew
37
+
38
+ ```bash
39
+ brew install hle-world/tap/hle-client
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ 1. **Sign up** at [hle.world](https://hle.world) and create an API key in the dashboard.
45
+
46
+ 2. **Expose a service:**
47
+
48
+ ```bash
49
+ hle expose --service http://localhost:8080 --api-key hle_your_key_here
50
+ ```
51
+
52
+ The API key is saved to `~/.config/hle/config.toml` after first use, so you only need to provide it once.
53
+
54
+ ## CLI Usage
55
+
56
+ ### `hle expose`
57
+
58
+ Expose a local service to the internet.
59
+
60
+ ```bash
61
+ hle expose --service http://localhost:8080 # Basic usage
62
+ hle expose --service http://localhost:8080 --label ha # Custom subdomain label
63
+ hle expose --service http://localhost:3000 --auth none # Disable SSO
64
+ hle expose --service http://localhost:8080 --no-websocket # Disable WS proxying
65
+ ```
66
+
67
+ Options:
68
+ - `--service` — Local service URL (required)
69
+ - `--label` — Service label for the subdomain (e.g. `ha` → `ha-x7k.hle.world`)
70
+ - `--auth` — Auth mode: `sso` (default) or `none`
71
+ - `--websocket/--no-websocket` — Enable/disable WebSocket proxying (default: enabled)
72
+ - `--api-key` — API key (also reads `HLE_API_KEY` env var, then config file)
73
+ - `--relay-host` — Relay server host (default: `hle.world`)
74
+ - `--relay-port` — Relay server port (default: `443`)
75
+
76
+ ### `hle tunnels`
77
+
78
+ List your active tunnels.
79
+
80
+ ```bash
81
+ hle tunnels
82
+ ```
83
+
84
+ ### `hle access`
85
+
86
+ Manage per-tunnel email allow-lists for SSO access.
87
+
88
+ ```bash
89
+ hle access list myapp-x7k # List access rules
90
+ hle access add myapp-x7k friend@example.com # Allow an email
91
+ hle access add myapp-x7k dev@co.com --provider github # Require GitHub SSO
92
+ hle access remove myapp-x7k 42 # Remove rule by ID
93
+ ```
94
+
95
+ ### `hle pin`
96
+
97
+ Manage PIN-based access control for tunnels.
98
+
99
+ ```bash
100
+ hle pin set myapp-x7k # Set a PIN (prompts for 4-8 digit PIN)
101
+ hle pin status myapp-x7k # Check PIN status
102
+ hle pin remove myapp-x7k # Remove PIN
103
+ ```
104
+
105
+ ### `hle share`
106
+
107
+ Create and manage temporary share links.
108
+
109
+ ```bash
110
+ hle share create myapp-x7k # 24h link (default)
111
+ hle share create myapp-x7k --duration 1h # 1-hour link
112
+ hle share create myapp-x7k --max-uses 5 # Limited uses
113
+ hle share list myapp-x7k # List share links
114
+ hle share revoke myapp-x7k 42 # Revoke a link
115
+ ```
116
+
117
+ ### Global Options
118
+
119
+ ```bash
120
+ hle --version # Show version
121
+ hle --debug ... # Enable debug logging
122
+ ```
123
+
124
+ ## Configuration
125
+
126
+ The HLE client stores configuration in `~/.config/hle/config.toml`:
127
+
128
+ ```toml
129
+ api_key = "hle_your_key_here"
130
+ ```
131
+
132
+ API key resolution order:
133
+ 1. `--api-key` CLI flag
134
+ 2. `HLE_API_KEY` environment variable
135
+ 3. `~/.config/hle/config.toml`
136
+
137
+ ## Development
138
+
139
+ ```bash
140
+ git clone https://github.com/hle-world/hle-client.git
141
+ cd hle-client
142
+ uv venv && source .venv/bin/activate
143
+ uv pip install -e ".[dev]"
144
+
145
+ # Run tests
146
+ pytest
147
+
148
+ # Lint
149
+ ruff check src/ tests/
150
+ ruff format --check src/ tests/
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT — see [LICENSE](LICENSE).