envloop-cli 0.1.0__tar.gz → 0.1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: envloop-cli
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Standalone el command-line client for EnvLoop
5
5
  Project-URL: Repository, https://github.com/EnvLoop/envloop
6
6
  Requires-Python: >=3.11
@@ -8,7 +8,7 @@ Description-Content-Type: text/markdown
8
8
 
9
9
  # envloop-cli
10
10
 
11
- Independent Python 3.11+ project providing the existing `el` CLI, version 0.1.0.
11
+ Independent Python 3.11+ project providing the existing `el` CLI, version 0.1.1.
12
12
  It builds and installs without the envloop SDK checkout or any third-party runtime
13
13
  dependencies. The distribution is `envloop-cli`; its private implementation package
14
14
  is `el_cli`, so it does not overwrite the `envloop` SDK namespace.
@@ -16,12 +16,16 @@ is `el_cli`, so it does not overwrite the `envloop` SDK namespace.
16
16
  After publication:
17
17
 
18
18
  ```bash
19
- pip install envloop-cli==0.1.0
19
+ pip install envloop-cli==0.1.1
20
20
  el --help
21
21
  el train --help
22
22
  el --api-url https://api.envloop.ai --workspace-id YOUR_WORKSPACE train job list
23
23
  ```
24
24
 
25
+ HTTP requests use system proxies by default (`HTTPS_PROXY` / `HTTP_PROXY`,
26
+ with `ALL_PROXY` as a fallback); lowercase equivalents and `NO_PROXY` are
27
+ honored. Without a configured proxy, requests connect directly.
28
+
25
29
  Set `ENVLOOP_API_KEY` privately in your environment. Existing command names,
26
30
  arguments, JSON output, error codes and `envloop/0.1` User-Agent are preserved.
27
31
  Local Task/Profile commands still require a separately installed compatible
@@ -65,7 +69,7 @@ uv run --locked pytest -q --ignore=tests/test_jobs_http.py
65
69
  uv run --locked ruff check .
66
70
  uv build
67
71
  python -m venv /tmp/el-cli-clean
68
- /tmp/el-cli-clean/bin/python -m pip install dist/envloop_cli-0.1.0-py3-none-any.whl
72
+ /tmp/el-cli-clean/bin/python -m pip install dist/envloop_cli-0.1.1-py3-none-any.whl
69
73
  /tmp/el-cli-clean/bin/el --help
70
74
  /tmp/el-cli-clean/bin/el train --help
71
75
  ```
@@ -1,6 +1,6 @@
1
1
  # envloop-cli
2
2
 
3
- Independent Python 3.11+ project providing the existing `el` CLI, version 0.1.0.
3
+ Independent Python 3.11+ project providing the existing `el` CLI, version 0.1.1.
4
4
  It builds and installs without the envloop SDK checkout or any third-party runtime
5
5
  dependencies. The distribution is `envloop-cli`; its private implementation package
6
6
  is `el_cli`, so it does not overwrite the `envloop` SDK namespace.
@@ -8,12 +8,16 @@ is `el_cli`, so it does not overwrite the `envloop` SDK namespace.
8
8
  After publication:
9
9
 
10
10
  ```bash
11
- pip install envloop-cli==0.1.0
11
+ pip install envloop-cli==0.1.1
12
12
  el --help
13
13
  el train --help
14
14
  el --api-url https://api.envloop.ai --workspace-id YOUR_WORKSPACE train job list
15
15
  ```
16
16
 
17
+ HTTP requests use system proxies by default (`HTTPS_PROXY` / `HTTP_PROXY`,
18
+ with `ALL_PROXY` as a fallback); lowercase equivalents and `NO_PROXY` are
19
+ honored. Without a configured proxy, requests connect directly.
20
+
17
21
  Set `ENVLOOP_API_KEY` privately in your environment. Existing command names,
18
22
  arguments, JSON output, error codes and `envloop/0.1` User-Agent are preserved.
19
23
  Local Task/Profile commands still require a separately installed compatible
@@ -57,7 +61,7 @@ uv run --locked pytest -q --ignore=tests/test_jobs_http.py
57
61
  uv run --locked ruff check .
58
62
  uv build
59
63
  python -m venv /tmp/el-cli-clean
60
- /tmp/el-cli-clean/bin/python -m pip install dist/envloop_cli-0.1.0-py3-none-any.whl
64
+ /tmp/el-cli-clean/bin/python -m pip install dist/envloop_cli-0.1.1-py3-none-any.whl
61
65
  /tmp/el-cli-clean/bin/el --help
62
66
  /tmp/el-cli-clean/bin/el train --help
63
67
  ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "envloop-cli"
3
- version = "0.1.0"
3
+ version = "0.1.1"
4
4
  description = "Standalone el command-line client for EnvLoop"
5
5
  requires-python = ">=3.11"
6
6
  readme = "README.md"
@@ -7,7 +7,13 @@ import os
7
7
  import re
8
8
  from urllib.error import HTTPError, URLError
9
9
  from urllib.parse import quote, urlencode, urlsplit
10
- from urllib.request import HTTPRedirectHandler, ProxyHandler, Request, build_opener
10
+ from urllib.request import (
11
+ HTTPRedirectHandler,
12
+ ProxyHandler,
13
+ Request,
14
+ build_opener,
15
+ getproxies,
16
+ )
11
17
 
12
18
 
13
19
  class RemoteError(RuntimeError):
@@ -50,7 +56,12 @@ class HttpService:
50
56
  self.headers["X-Workspace-ID"] = workspace
51
57
  self.base = base_url.rstrip("/").removesuffix("/v1")
52
58
  self.timeout = timeout
53
- self.opener = build_opener(ProxyHandler({}), NoRedirect())
59
+ proxies = getproxies()
60
+ # urllib discovers ALL_PROXY but does not apply it to HTTP(S).
61
+ if proxies.get("all"):
62
+ for scheme in ("http", "https"):
63
+ proxies.setdefault(scheme, proxies["all"])
64
+ self.opener = build_opener(ProxyHandler(proxies), NoRedirect())
54
65
 
55
66
  def request(self, method, path, body=None):
56
67
  request = Request(self.base + path,
@@ -0,0 +1,59 @@
1
+ """Regression coverage using a local proxy/API at the network boundary."""
2
+
3
+ import json
4
+ import os
5
+ import threading
6
+ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
7
+
8
+ import pytest
9
+
10
+ from el_cli.cli import main
11
+
12
+
13
+ @pytest.mark.parametrize('proxy_variable', ['HTTP_PROXY', 'http_proxy', 'ALL_PROXY'])
14
+ def test_train_list_uses_environment_proxy(proxy_variable, monkeypatch, capsys):
15
+ run_list(monkeypatch, capsys, proxy_variable=proxy_variable)
16
+
17
+
18
+ @pytest.mark.parametrize('bypass', [False, True])
19
+ def test_train_list_connects_directly(monkeypatch, capsys, bypass):
20
+ run_list(monkeypatch, capsys, bypass=bypass)
21
+
22
+
23
+ def run_list(monkeypatch, capsys, *, proxy_variable=None, bypass=False):
24
+ for name in os.environ:
25
+ if name.lower().endswith('_proxy'):
26
+ monkeypatch.delenv(name)
27
+ monkeypatch.setenv('NO_PROXY', '127.0.0.1' if bypass else '')
28
+ seen = []
29
+
30
+ class Handler(BaseHTTPRequestHandler):
31
+ def do_GET(self):
32
+ seen.append(self.path)
33
+ self.send_response(200)
34
+ self.end_headers()
35
+ self.wfile.write(b'{"items":[]}')
36
+
37
+ def log_message(self, *args):
38
+ pass
39
+
40
+ server = ThreadingHTTPServer(('127.0.0.1', 0), Handler)
41
+ thread = threading.Thread(target=server.serve_forever, daemon=True)
42
+ thread.start()
43
+ base = f'http://127.0.0.1:{server.server_port}'
44
+ if proxy_variable:
45
+ monkeypatch.setenv(proxy_variable, base)
46
+ origin = 'http://127.0.0.1:1'
47
+ else:
48
+ origin = base
49
+ if bypass:
50
+ monkeypatch.setenv('HTTP_PROXY', 'http://127.0.0.1:1')
51
+ try:
52
+ assert main(['--api-url', origin, 'train', 'job', 'list']) == 0
53
+ assert json.loads(capsys.readouterr().out) == {'items': []}
54
+ path = '/v1/train/jobs?limit=25'
55
+ assert seen == [origin + path if proxy_variable else path]
56
+ finally:
57
+ server.shutdown()
58
+ server.server_close()
59
+ thread.join()
File without changes