shadow-tools 0.2.2__tar.gz → 0.2.3__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.
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/PKG-INFO +4 -1
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/README.md +3 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/pyproject.toml +1 -1
- shadow_tools-0.2.3/release-0.2.2/shadow_tools-0.2.2-py3-none-any.whl +0 -0
- shadow_tools-0.2.3/release-0.2.2/shadow_tools-0.2.2.tar.gz +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/__init__.py +1 -1
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/network.py +5 -2
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/tests/test_core.py +1 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/.gitignore +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/LICENSE +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/release-0.2.0/shadow_tools-0.2.0-py3-none-any.whl +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/release-0.2.0/shadow_tools-0.2.0.tar.gz +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/release-0.2.1/shadow_tools-0.2.1-py3-none-any.whl +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/release-0.2.1/shadow_tools-0.2.1.tar.gz +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/ai.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/async_tools.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/cli.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/data.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/files.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/http.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/validation.py +0 -0
- {shadow_tools-0.2.2 → shadow_tools-0.2.3}/src/shadowtools/websocket.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: shadow-tools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A practical all-in-one Python toolkit for HTTP, WebSockets, files, data, validation, async work, and CLIs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WilliamLaurento/shadow-tools
|
|
6
6
|
Project-URL: Issues, https://github.com/WilliamLaurento/shadow-tools/issues
|
|
@@ -75,6 +75,9 @@ from shadowtools import generate_random_ips, reverse_dns
|
|
|
75
75
|
|
|
76
76
|
for ip in generate_random_ips(5):
|
|
77
77
|
print(reverse_dns(ip))
|
|
78
|
+
|
|
79
|
+
# Or look up every generated IP at once.
|
|
80
|
+
print(reverse_dns(generate_random_ips(5)))
|
|
78
81
|
```
|
|
79
82
|
|
|
80
83
|
## AI app helpers
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "shadow-tools"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "A practical all-in-one Python toolkit for HTTP, WebSockets, files, data, validation, async work, and CLIs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
Binary file
|
|
Binary file
|
|
@@ -6,7 +6,7 @@ from .http import get, request
|
|
|
6
6
|
from .network import generate_random_ips, generate_test_ips, is_subdomain_of, make_subdomain, resolve_dns, reverse_dns
|
|
7
7
|
from .validation import is_email, is_url, require_keys
|
|
8
8
|
|
|
9
|
-
__version__ = "0.2.
|
|
9
|
+
__version__ = "0.2.3"
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"append_text", "ensure_dir", "generate_random_ips", "generate_test_ips", "get", "is_email", "is_subdomain_of", "is_url", "make_subdomain", "read_csv",
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
import ipaddress
|
|
5
5
|
import random
|
|
6
6
|
import socket
|
|
7
|
+
from collections.abc import Iterable
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def resolve_dns(hostname: str) -> dict[str, list[str]]:
|
|
@@ -17,12 +18,14 @@ def resolve_dns(hostname: str) -> dict[str, list[str]]:
|
|
|
17
18
|
return {kind: sorted(addresses) for kind, addresses in results.items()}
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
def reverse_dns(ip: str) -> dict[str, object]:
|
|
21
|
-
"""Look up
|
|
21
|
+
def reverse_dns(ip: str | Iterable[str]) -> dict[str, object] | list[dict[str, object]]:
|
|
22
|
+
"""Look up DNS names for one IP address or each address in a list.
|
|
22
23
|
|
|
23
24
|
An address without a PTR record returns ``hostname: None`` instead of
|
|
24
25
|
raising an exception.
|
|
25
26
|
"""
|
|
27
|
+
if not isinstance(ip, str):
|
|
28
|
+
return [reverse_dns(one_ip) for one_ip in ip]
|
|
26
29
|
address = ipaddress.ip_address(ip)
|
|
27
30
|
try:
|
|
28
31
|
hostname, aliases, _ = socket.gethostbyaddr(str(address))
|
|
@@ -44,5 +44,6 @@ def test_network_and_ai_helpers():
|
|
|
44
44
|
assert len(generate_random_ips(3)) == 3
|
|
45
45
|
assert len(generate_random_ips(2, family=6)) == 2
|
|
46
46
|
assert reverse_dns("0.0.0.0")["hostname"] is None
|
|
47
|
+
assert len(reverse_dns(["0.0.0.0", "127.0.0.1"])) == 2
|
|
47
48
|
assert prompt("Hi {name}", name="Will") == "Hi Will"
|
|
48
49
|
assert tool_schema("lookup_dns", "Lookup DNS", {"host": {"type": "string"}})["name"] == "lookup_dns"
|
|
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
|