Skip to content

refactor: call urllib3 directly instead of through requests.packages - #25

Merged
cigamit merged 1 commit into
ctrliq:mainfrom
blaipr:refactor/use-urllib3-directly
Sep 13, 2026
Merged

cigamit merged 1 commit into
ctrliq:mainfrom
blaipr:refactor/use-urllib3-directly

Conversation

@blaipr

@blaipr blaipr commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

requests.packages is a compatibility shim from when requests vendored its dependencies. It has been an alias for the real top-level packages for years, and reaching urllib3 through it means the call depends on a requests internal rather than on the library it actually wants.

ascenderkit/cli/__init__.py:16 already does this the direct way:

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

api/client.py now matches it. urllib3 is already a declared dependency in setup.py, where the comment says it is "imported directly by the CLI to silence insecure-request warnings", so this also makes the second call site agree with what the packaging already claims.

One narrowing that comes with it. requests.packages.urllib3.disable_warnings() with no argument suppresses every urllib3 warning category. The intent here is the insecure-request one, which is the only warning an unverified connection raises, so the category is now named. Anything else urllib3 has to say, a deprecation or a connection-pool warning, is no longer swallowed.

Note for whoever merges: #26 also touches this constructor, so whichever lands second needs a rebase.

Verified with black --check, flake8 and the unit suite, 355 passing.

`requests.packages` is a compatibility shim from when requests vendored its
dependencies. It has been an alias for the real top-level packages for years,
and reaching urllib3 through it means the call depends on a requests internal
rather than on the library it actually wants.

`ascenderkit/cli/__init__.py:16` already does this the direct way:

    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

`api/client.py` now matches it. `urllib3` is already a declared dependency in
`setup.py`, where the comment says it is "imported directly by the CLI to
silence insecure-request warnings", so this also makes the second call site
agree with what the packaging already claims.

One narrowing that comes with it. `requests.packages.urllib3.disable_warnings()`
with no argument suppresses **every** urllib3 warning category. The intent here
is the insecure-request one, which is the only warning an unverified connection
raises, so the category is now named. Anything else urllib3 has to say, a
deprecation or a connection-pool warning, is no longer swallowed.

Note for whoever merges: ctrliq#25 also touches this constructor, so whichever lands
second needs a rebase.

Verified with `black --check`, `flake8` and the unit suite, 355 passing.
@ciq-it-service-account

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cigamit
cigamit merged commit a8e220e into ctrliq:main Sep 13, 2026
1 check passed
cigamit pushed a commit that referenced this pull request Sep 13, 2026
Using this package as a library meant unverified TLS, silently.

`Connection.__init__` took `verify=False`, and the value that actually governs
the normal path, `config.assume_untrusted`, defaulted to `True`. So
`Page(...)` built a connection with verification off, and the constructor then
called `disable_warnings()` so nothing said as much. A library that talks to
an Ascender over HTTPS was not checking who answered.

Two defaults flip:

- `Connection(server, verify=True)`.
- `config.assume_untrusted` now defaults to `False`, and reads
  `ASCENDERKIT_ASSUME_UNTRUSTED` for the opt-out, following the same pattern as
  `ASCENDERKIT_SESSIONS` and `ASCENDERKIT_PREVENT_TEARDOWN`. There was no
  environment variable for it before, only the config dictionary.

This is a behaviour change for library consumers and is in the changelog as one.
Anyone pointed at an Ascender with a self-signed certificate sets the variable,
or passes `verify=False` explicitly, and is back where they were.

**The CLI is unaffected.** `CLI.connect()` already sets
`config.assume_untrusted = False` and only sets it `True` for
`-k` / `--conf.insecure`, so it has always verified by default. This brings the
library in line with the CLI rather than changing the CLI.

Out of scope, and worth its own change: `ascenderkit/cli/__init__.py:16` calls
`urllib3.disable_warnings(InsecureRequestWarning)` unconditionally at import, so
even a verifying connection has the warning suppressed. And `ws.py` hardcodes
`ssl.CERT_NONE` regardless of any of this, which #27 covers.

Note for whoever merges: #25 also touches this constructor, so whichever lands
second needs a rebase.

Verified with `black --check`, `flake8` and the unit suite, 355 passing.
blaipr added a commit to blaipr/ascender-kit that referenced this pull request Sep 13, 2026
Two places reach a submodule through its parent package without importing it:

```python
import requests
...
class Token_Auth(requests.auth.AuthBase):
```

```python
import yaml
...
raise yaml.constructor.ConstructorError
```

Both work today, and only because `requests` and `yaml` happen to import those submodules themselves as part of their own initialisation. Nothing in the language guarantees that: `import requests` binds the package, not its children, and a release that stops importing `auth` eagerly turns this into an `AttributeError` at class definition time, which is to say at import of `ascenderkit`.

Imported by name instead, which is what the code means and what a reader would expect:

```python
from requests.auth import AuthBase
from yaml.constructor import ConstructorError
```

This also clears the two `possibly-missing-submodule` warnings the type checker reports, which is how it surfaced.

Note for whoever merges: ctrliq#25 and ctrliq#26 also edit `api/client.py`, so whichever lands after them needs a rebase.

Verified with `black --check`, `flake8` and the unit suite, 355 passing.
cigamit pushed a commit that referenced this pull request Sep 13, 2026
Two places reach a submodule through its parent package without importing it:

```python
import requests
...
class Token_Auth(requests.auth.AuthBase):
```

```python
import yaml
...
raise yaml.constructor.ConstructorError
```

Both work today, and only because `requests` and `yaml` happen to import those submodules themselves as part of their own initialisation. Nothing in the language guarantees that: `import requests` binds the package, not its children, and a release that stops importing `auth` eagerly turns this into an `AttributeError` at class definition time, which is to say at import of `ascenderkit`.

Imported by name instead, which is what the code means and what a reader would expect:

```python
from requests.auth import AuthBase
from yaml.constructor import ConstructorError
```

This also clears the two `possibly-missing-submodule` warnings the type checker reports, which is how it surfaced.

Note for whoever merges: #25 and #26 also edit `api/client.py`, so whichever lands after them needs a rebase.

Verified with `black --check`, `flake8` and the unit suite, 355 passing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

3 participants