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.
- hle_client-0.4.0/.github/workflows/homebrew.yml +85 -0
- hle_client-0.4.0/.github/workflows/publish.yml +61 -0
- hle_client-0.4.0/.github/workflows/test.yml +48 -0
- hle_client-0.4.0/.gitignore +34 -0
- hle_client-0.4.0/CHANGELOG.md +15 -0
- hle_client-0.4.0/LICENSE +21 -0
- hle_client-0.4.0/PKG-INFO +190 -0
- hle_client-0.4.0/README.md +155 -0
- hle_client-0.4.0/install.sh +141 -0
- hle_client-0.4.0/pyproject.toml +80 -0
- hle_client-0.4.0/src/hle_client/__init__.py +3 -0
- hle_client-0.4.0/src/hle_client/api.py +140 -0
- hle_client-0.4.0/src/hle_client/cli.py +594 -0
- hle_client-0.4.0/src/hle_client/proxy.py +135 -0
- hle_client-0.4.0/src/hle_client/tunnel.py +551 -0
- hle_client-0.4.0/src/hle_common/__init__.py +3 -0
- hle_client-0.4.0/src/hle_common/models.py +132 -0
- hle_client-0.4.0/src/hle_common/protocol.py +107 -0
- hle_client-0.4.0/tests/__init__.py +0 -0
- hle_client-0.4.0/tests/unit/__init__.py +0 -0
- hle_client-0.4.0/tests/unit/test_api_client.py +125 -0
- hle_client-0.4.0/tests/unit/test_cli_commands.py +278 -0
- hle_client-0.4.0/tests/unit/test_client.py +903 -0
|
@@ -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
|
hle_client-0.4.0/LICENSE
ADDED
|
@@ -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
|
+
[](https://pypi.org/project/hle-client/)
|
|
39
|
+
[](https://pypi.org/project/hle-client/)
|
|
40
|
+
[](LICENSE)
|
|
41
|
+
[](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
|
+
[](https://pypi.org/project/hle-client/)
|
|
4
|
+
[](https://pypi.org/project/hle-client/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](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).
|