devnomads 0.2.3__tar.gz → 0.2.4__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.
- {devnomads-0.2.3 → devnomads-0.2.4}/PKG-INFO +13 -13
- {devnomads-0.2.3 → devnomads-0.2.4}/README.md +11 -11
- {devnomads-0.2.3 → devnomads-0.2.4}/pyproject.toml +2 -2
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/api/credentials.py +8 -8
- {devnomads-0.2.3 → devnomads-0.2.4}/uv.lock +1 -1
- {devnomads-0.2.3 → devnomads-0.2.4}/.flake8 +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/.gitignore +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/.gitlab-ci.yml +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/Makefile +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/openapi.json +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/__init__.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/__init__.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/challenge_server.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/client.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/dns01.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/errors.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/http01.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/keys.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/acme/verify.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/api/__init__.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/api/_services.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/api/client.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/api/errors.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/dns/__init__.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/dns/errors.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/dns/names.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/dns/zones.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/src/devnomads/py.typed +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/conftest.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_acme_challenges.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_acme_client.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_acme_keys.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_client.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_credentials.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_dns.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_names.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tests/test_services.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tools/bump_version.py +0 -0
- {devnomads-0.2.3 → devnomads-0.2.4}/tools/generate.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devnomads
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Python client library for the DevNomads API (transport, DNS, ACME)
|
|
5
5
|
Project-URL: Homepage, https://devnomads.nl
|
|
6
|
-
Author-email:
|
|
6
|
+
Author-email: DevNomads <support@devnomads.nl>
|
|
7
7
|
License: MIT
|
|
8
8
|
Keywords: acme,api,devnomads,dns,powerdns
|
|
9
9
|
Requires-Python: >=3.10
|
|
@@ -21,9 +21,9 @@ Python client library for the [DevNomads](https://devnomads.nl) API:
|
|
|
21
21
|
HTTP transport, a generated resource SDK covering the whole API, DNS
|
|
22
22
|
zone/record management, and ACME certificate issuance.
|
|
23
23
|
|
|
24
|
-
It is the shared foundation of the DevNomads command-line
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
It is the shared foundation of the DevNomads command-line tool `dncli`,
|
|
25
|
+
exposed so you can build against the same primitives directly instead of
|
|
26
|
+
reimplementing them.
|
|
27
27
|
|
|
28
28
|
## Contents
|
|
29
29
|
|
|
@@ -54,7 +54,7 @@ directly instead of reimplementing them.
|
|
|
54
54
|
wildcards and per-identifier challenge mixing in a single order.
|
|
55
55
|
- Two HTTP-01 strategies: write challenge files to a web root, or answer
|
|
56
56
|
from a built-in standalone server.
|
|
57
|
-
- One credential scheme,
|
|
57
|
+
- One credential scheme, shared with the `dncli` command-line tool.
|
|
58
58
|
- Typed exceptions, standard-library logging, full type hints
|
|
59
59
|
(`py.typed`). No printing, no `sys.exit`.
|
|
60
60
|
|
|
@@ -135,8 +135,8 @@ The API key is resolved as:
|
|
|
135
135
|
|
|
136
136
|
The credentials file is `DN_CREDENTIALS_FILE` if set, otherwise the first
|
|
137
137
|
of `/etc/devnomads/credentials` and `<config dir>/credentials`. The config
|
|
138
|
-
directory is `DN_CONFIG_DIR`, else `$XDG_CONFIG_HOME/
|
|
139
|
-
`~/.config/
|
|
138
|
+
directory is `DN_CONFIG_DIR`, else `$XDG_CONFIG_HOME/dncli`, else
|
|
139
|
+
`~/.config/dncli` - i.e. the file `dncli configure` writes. The profile is
|
|
140
140
|
`DN_PROFILE`, else `default`.
|
|
141
141
|
|
|
142
142
|
### Credentials file
|
|
@@ -156,7 +156,7 @@ api_url = https://api.devnomads.nl
|
|
|
156
156
|
- `DN_API_URL` / `DEVNOMADS_API_URL` - base URL override.
|
|
157
157
|
- `DN_PROFILE` / `DEVNOMADS_PROFILE` - profile name (default `default`).
|
|
158
158
|
- `DN_CREDENTIALS_FILE` - explicit credentials file path.
|
|
159
|
-
- `DN_CONFIG_DIR` - config directory (default `~/.config/
|
|
159
|
+
- `DN_CONFIG_DIR` - config directory (default `~/.config/dncli`).
|
|
160
160
|
|
|
161
161
|
`config_dir()` and `credentials_path()` expose the resolved paths.
|
|
162
162
|
|
|
@@ -315,7 +315,7 @@ AcmeClient(
|
|
|
315
315
|
account_key_path,
|
|
316
316
|
*,
|
|
317
317
|
directory_url=DEFAULT_DIRECTORY_URL, # Let's Encrypt production
|
|
318
|
-
account_key_algorithm="ec256", # rsa2048/rsa4096/ec256/ec384
|
|
318
|
+
account_key_algorithm="ec256", # rsa2048/rsa4096/ec256/ec384/ec521
|
|
319
319
|
contact_email=None,
|
|
320
320
|
preferred_chain=None, # match alternate chain by CN
|
|
321
321
|
recursive_nameservers=None, # resolvers for propagation
|
|
@@ -429,7 +429,7 @@ from devnomads.acme import (
|
|
|
429
429
|
load_or_create_account_key,
|
|
430
430
|
)
|
|
431
431
|
|
|
432
|
-
key = generate_key("rsa4096") # rsa2048/rsa4096/ec256/ec384
|
|
432
|
+
key = generate_key("rsa4096") # rsa2048/rsa4096/ec256/ec384/ec521
|
|
433
433
|
pem = serialize_key(key) # unencrypted PEM bytes
|
|
434
434
|
csr = build_csr(key, ["example.com", "www.example.com"])
|
|
435
435
|
jwk = load_or_create_account_key("/etc/devnomads/account.key", "ec256")
|
|
@@ -504,8 +504,8 @@ logging.getLogger("devnomads").setLevel(logging.INFO)
|
|
|
504
504
|
presentation.
|
|
505
505
|
- **Layered by dependency weight.** DNS-only consumers never pull the
|
|
506
506
|
ACME stack; the heavy dependencies live behind the `acme` extra.
|
|
507
|
-
- **One credential scheme** shared with the DevNomads
|
|
508
|
-
configured for `
|
|
507
|
+
- **One credential scheme** shared with the DevNomads CLI, so a host
|
|
508
|
+
configured for `dncli` works unchanged.
|
|
509
509
|
|
|
510
510
|
## Development
|
|
511
511
|
|
|
@@ -4,9 +4,9 @@ Python client library for the [DevNomads](https://devnomads.nl) API:
|
|
|
4
4
|
HTTP transport, a generated resource SDK covering the whole API, DNS
|
|
5
5
|
zone/record management, and ACME certificate issuance.
|
|
6
6
|
|
|
7
|
-
It is the shared foundation of the DevNomads command-line
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
It is the shared foundation of the DevNomads command-line tool `dncli`,
|
|
8
|
+
exposed so you can build against the same primitives directly instead of
|
|
9
|
+
reimplementing them.
|
|
10
10
|
|
|
11
11
|
## Contents
|
|
12
12
|
|
|
@@ -37,7 +37,7 @@ directly instead of reimplementing them.
|
|
|
37
37
|
wildcards and per-identifier challenge mixing in a single order.
|
|
38
38
|
- Two HTTP-01 strategies: write challenge files to a web root, or answer
|
|
39
39
|
from a built-in standalone server.
|
|
40
|
-
- One credential scheme,
|
|
40
|
+
- One credential scheme, shared with the `dncli` command-line tool.
|
|
41
41
|
- Typed exceptions, standard-library logging, full type hints
|
|
42
42
|
(`py.typed`). No printing, no `sys.exit`.
|
|
43
43
|
|
|
@@ -118,8 +118,8 @@ The API key is resolved as:
|
|
|
118
118
|
|
|
119
119
|
The credentials file is `DN_CREDENTIALS_FILE` if set, otherwise the first
|
|
120
120
|
of `/etc/devnomads/credentials` and `<config dir>/credentials`. The config
|
|
121
|
-
directory is `DN_CONFIG_DIR`, else `$XDG_CONFIG_HOME/
|
|
122
|
-
`~/.config/
|
|
121
|
+
directory is `DN_CONFIG_DIR`, else `$XDG_CONFIG_HOME/dncli`, else
|
|
122
|
+
`~/.config/dncli` - i.e. the file `dncli configure` writes. The profile is
|
|
123
123
|
`DN_PROFILE`, else `default`.
|
|
124
124
|
|
|
125
125
|
### Credentials file
|
|
@@ -139,7 +139,7 @@ api_url = https://api.devnomads.nl
|
|
|
139
139
|
- `DN_API_URL` / `DEVNOMADS_API_URL` - base URL override.
|
|
140
140
|
- `DN_PROFILE` / `DEVNOMADS_PROFILE` - profile name (default `default`).
|
|
141
141
|
- `DN_CREDENTIALS_FILE` - explicit credentials file path.
|
|
142
|
-
- `DN_CONFIG_DIR` - config directory (default `~/.config/
|
|
142
|
+
- `DN_CONFIG_DIR` - config directory (default `~/.config/dncli`).
|
|
143
143
|
|
|
144
144
|
`config_dir()` and `credentials_path()` expose the resolved paths.
|
|
145
145
|
|
|
@@ -298,7 +298,7 @@ AcmeClient(
|
|
|
298
298
|
account_key_path,
|
|
299
299
|
*,
|
|
300
300
|
directory_url=DEFAULT_DIRECTORY_URL, # Let's Encrypt production
|
|
301
|
-
account_key_algorithm="ec256", # rsa2048/rsa4096/ec256/ec384
|
|
301
|
+
account_key_algorithm="ec256", # rsa2048/rsa4096/ec256/ec384/ec521
|
|
302
302
|
contact_email=None,
|
|
303
303
|
preferred_chain=None, # match alternate chain by CN
|
|
304
304
|
recursive_nameservers=None, # resolvers for propagation
|
|
@@ -412,7 +412,7 @@ from devnomads.acme import (
|
|
|
412
412
|
load_or_create_account_key,
|
|
413
413
|
)
|
|
414
414
|
|
|
415
|
-
key = generate_key("rsa4096") # rsa2048/rsa4096/ec256/ec384
|
|
415
|
+
key = generate_key("rsa4096") # rsa2048/rsa4096/ec256/ec384/ec521
|
|
416
416
|
pem = serialize_key(key) # unencrypted PEM bytes
|
|
417
417
|
csr = build_csr(key, ["example.com", "www.example.com"])
|
|
418
418
|
jwk = load_or_create_account_key("/etc/devnomads/account.key", "ec256")
|
|
@@ -487,8 +487,8 @@ logging.getLogger("devnomads").setLevel(logging.INFO)
|
|
|
487
487
|
presentation.
|
|
488
488
|
- **Layered by dependency weight.** DNS-only consumers never pull the
|
|
489
489
|
ACME stack; the heavy dependencies live behind the `acme` extra.
|
|
490
|
-
- **One credential scheme** shared with the DevNomads
|
|
491
|
-
configured for `
|
|
490
|
+
- **One credential scheme** shared with the DevNomads CLI, so a host
|
|
491
|
+
configured for `dncli` works unchanged.
|
|
492
492
|
|
|
493
493
|
## Development
|
|
494
494
|
|
|
@@ -4,12 +4,12 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "devnomads"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.4"
|
|
8
8
|
description = "Python client library for the DevNomads API (transport, DNS, ACME)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { text = "MIT" }
|
|
12
|
-
authors = [{ name = "
|
|
12
|
+
authors = [{ name = "DevNomads", email = "support@devnomads.nl" }]
|
|
13
13
|
keywords = ["devnomads", "dns", "acme", "powerdns", "api"]
|
|
14
14
|
dependencies = ["httpx>=0.27"]
|
|
15
15
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Credential resolution shared by every DevNomads tool.
|
|
2
2
|
|
|
3
|
-
The scheme matches what ``
|
|
4
|
-
up for
|
|
3
|
+
The scheme matches what ``dncli configure`` writes, so a host already set
|
|
4
|
+
up for dncli works with no extra configuration. Resolution order for the
|
|
5
5
|
API key:
|
|
6
6
|
|
|
7
7
|
1. an explicit value passed by the caller,
|
|
@@ -10,7 +10,7 @@ API key:
|
|
|
10
10
|
|
|
11
11
|
The credentials file is found at ``DN_CREDENTIALS_FILE`` if set, otherwise
|
|
12
12
|
the first that exists of ``/etc/devnomads/credentials`` and
|
|
13
|
-
``<config dir>/credentials`` (the
|
|
13
|
+
``<config dir>/credentials`` (the dncli config dir). The profile is the
|
|
14
14
|
caller's argument, else ``DN_PROFILE``, else ``default``.
|
|
15
15
|
"""
|
|
16
16
|
|
|
@@ -56,10 +56,10 @@ def _first_env(names: tuple[str, ...]) -> str | None:
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def config_dir() -> Path:
|
|
59
|
-
"""The
|
|
59
|
+
"""The dncli config directory, matching dncli's own resolution.
|
|
60
60
|
|
|
61
|
-
``DN_CONFIG_DIR`` wins, then ``$XDG_CONFIG_HOME/
|
|
62
|
-
``~/.config/
|
|
61
|
+
``DN_CONFIG_DIR`` wins, then ``$XDG_CONFIG_HOME/dncli``, then
|
|
62
|
+
``~/.config/dncli``.
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
override = os.environ.get(ENV_CONFIG_DIR)
|
|
@@ -67,7 +67,7 @@ def config_dir() -> Path:
|
|
|
67
67
|
return Path(override)
|
|
68
68
|
xdg = os.environ.get("XDG_CONFIG_HOME")
|
|
69
69
|
base = Path(xdg) if xdg else Path.home() / ".config"
|
|
70
|
-
return base / "
|
|
70
|
+
return base / "dncli"
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def credentials_path() -> Path:
|
|
@@ -119,7 +119,7 @@ def resolve(
|
|
|
119
119
|
if not resolved_key:
|
|
120
120
|
searched = ", ".join(str(p) for p in candidates)
|
|
121
121
|
raise ConfigError(
|
|
122
|
-
"no API key found - set DN_API_KEY or run '
|
|
122
|
+
"no API key found - set DN_API_KEY or run 'dncli configure' to "
|
|
123
123
|
f"create a credentials file (searched: {searched})"
|
|
124
124
|
)
|
|
125
125
|
return Credentials(api_key=resolved_key.strip(), api_url=resolved_url)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|