lanscape 2.0.0a1__tar.gz → 2.0.0b1__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.
Potentially problematic release.
This version of lanscape might be problematic. Click here for more details.
- {lanscape-2.0.0a1/lanscape.egg-info → lanscape-2.0.0b1}/PKG-INFO +5 -2
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/README.md +1 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/__init__.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/__main__.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/app_scope.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/decorators.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/device_alive.py +1 -2
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/errors.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/ip_parser.py +1 -26
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/logger.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/mac_lookup.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/net_tools.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/port_manager.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/runtime_args.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/scan_config.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/service_scan.py +3 -21
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/subnet_scan.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/version_manager.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/web_browser.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/mac_addresses/convert_csv.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/convert_csv.py +0 -1
- lanscape-2.0.0b1/lanscape/resources/ports/test_port_list_scan.json +4 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/app.py +13 -2
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/__init__.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/__init__.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/port.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/scan.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/api/tools.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/web/__init__.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/blueprints/web/routes.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/main.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/shutdown_handler.py +0 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/config.html +1 -1
- {lanscape-2.0.0a1 → lanscape-2.0.0b1/lanscape.egg-info}/PKG-INFO +5 -2
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/SOURCES.txt +1 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/requires.txt +4 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/pyproject.toml +7 -1
- lanscape-2.0.0b1/tests/test_api.py +281 -0
- lanscape-2.0.0b1/tests/test_decorators.py +333 -0
- lanscape-2.0.0b1/tests/test_env.py +147 -0
- lanscape-2.0.0b1/tests/test_library.py +108 -0
- lanscape-2.0.0b1/tests/test_logging.py +102 -0
- lanscape-2.0.0b1/tests/test_port_scan.py +277 -0
- lanscape-2.0.0b1/tests/test_service_scan.py +270 -0
- lanscape-2.0.0b1/tests/test_utils.py +160 -0
- lanscape-2.0.0a1/tests/test_api.py +0 -244
- lanscape-2.0.0a1/tests/test_decorators.py +0 -283
- lanscape-2.0.0a1/tests/test_env.py +0 -46
- lanscape-2.0.0a1/tests/test_library.py +0 -105
- lanscape-2.0.0a1/tests/test_logging.py +0 -79
- lanscape-2.0.0a1/tests/test_port_scan.py +0 -251
- lanscape-2.0.0a1/tests/test_service_scan.py +0 -253
- lanscape-2.0.0a1/tests/test_utils.py +0 -110
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/LICENSE +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/MANIFEST.in +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/core/__init__.py +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/mac_addresses/mac_db.json +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/full.json +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/large.json +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/medium.json +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/ports/small.json +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/resources/services/definitions.jsonc +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/__init__.py +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/css/style.css +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/android-chrome-192x192.png +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/android-chrome-512x512.png +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/apple-touch-icon.png +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon-16x16.png +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon-32x32.png +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/favicon.ico +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/img/ico/site.webmanifest +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/core.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/layout-sizing.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/main.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/on-tab-close.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/quietReload.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/scan-config.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/shutdown-server.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/subnet-info.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/js/subnet-selector.js +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/static/lanscape.webmanifest +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/base.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/core/head.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/core/scripts.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/error.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/info.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/main.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/device-detail.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/export.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/ip-table-row.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/ip-table.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/overview.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan/scan-error.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/scan.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape/ui/templates/shutdown.html +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/dependency_links.txt +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/entry_points.txt +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/lanscape.egg-info/top_level.txt +0 -0
- {lanscape-2.0.0a1 → lanscape-2.0.0b1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0b1
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -25,6 +25,9 @@ Requires-Dist: scapy<3.0,>=2.3.2
|
|
|
25
25
|
Requires-Dist: tabulate==0.9.0
|
|
26
26
|
Requires-Dist: pydantic
|
|
27
27
|
Requires-Dist: icmplib
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
28
31
|
Dynamic: license-file
|
|
29
32
|
|
|
30
33
|
# LANscape
|
|
@@ -85,7 +88,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
|
|
|
85
88
|
Recommendations:
|
|
86
89
|
|
|
87
90
|
- Adjust scan configuration
|
|
88
|
-
- Configure ARP lookup [ARP lookup setup](./
|
|
91
|
+
- Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
|
|
89
92
|
- Create a bug
|
|
90
93
|
|
|
91
94
|
|
|
@@ -56,7 +56,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
|
|
|
56
56
|
Recommendations:
|
|
57
57
|
|
|
58
58
|
- Adjust scan configuration
|
|
59
|
-
- Configure ARP lookup [ARP lookup setup](./
|
|
59
|
+
- Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
|
|
60
60
|
- Create a bug
|
|
61
61
|
|
|
62
62
|
|
|
@@ -156,7 +156,7 @@ class ArpLookup():
|
|
|
156
156
|
NOTE: This lookup method requires elevated privileges to access the ARP cache.
|
|
157
157
|
|
|
158
158
|
|
|
159
|
-
[Arp Lookup Requirements](/
|
|
159
|
+
[Arp Lookup Requirements](/docs/arp-issues.md)
|
|
160
160
|
"""
|
|
161
161
|
|
|
162
162
|
@classmethod
|
|
@@ -227,4 +227,3 @@ class Poker():
|
|
|
227
227
|
sock.close()
|
|
228
228
|
|
|
229
229
|
do_poke()
|
|
230
|
-
|
|
@@ -10,7 +10,6 @@ This module provides utilities for parsing various IP address formats including:
|
|
|
10
10
|
It also includes validation to prevent processing excessively large IP ranges.
|
|
11
11
|
"""
|
|
12
12
|
import ipaddress
|
|
13
|
-
import re
|
|
14
13
|
|
|
15
14
|
from lanscape.core.errors import SubnetTooLargeError
|
|
16
15
|
|
|
@@ -50,14 +49,10 @@ def parse_ip_input(ip_input):
|
|
|
50
49
|
for ip in net.hosts():
|
|
51
50
|
ip_ranges.append(ip)
|
|
52
51
|
|
|
53
|
-
# Handle IP range (e.g., 10.0.0.15-10.0.0.25)
|
|
52
|
+
# Handle IP range (e.g., 10.0.0.15-10.0.0.25) and (e.g., 10.0.9.1-253)
|
|
54
53
|
elif '-' in entry:
|
|
55
54
|
ip_ranges += parse_ip_range(entry)
|
|
56
55
|
|
|
57
|
-
# Handle shorthand IP range (e.g., 10.0.9.1-253)
|
|
58
|
-
elif re.search(r'\d+\-\d+', entry):
|
|
59
|
-
ip_ranges += parse_shorthand_ip_range(entry)
|
|
60
|
-
|
|
61
56
|
# If no CIDR or range, assume a single IP
|
|
62
57
|
else:
|
|
63
58
|
ip_ranges.append(ipaddress.IPv4Address(entry))
|
|
@@ -106,25 +101,6 @@ def parse_ip_range(entry):
|
|
|
106
101
|
return list(ip_range_to_list(start_ip, end_ip))
|
|
107
102
|
|
|
108
103
|
|
|
109
|
-
def parse_shorthand_ip_range(entry):
|
|
110
|
-
"""
|
|
111
|
-
Parse a shorthand IP range (e.g., 192.168.1.1-10).
|
|
112
|
-
|
|
113
|
-
In this format, only the last octet of the end IP is specified.
|
|
114
|
-
|
|
115
|
-
Args:
|
|
116
|
-
entry (str): String containing a shorthand IP range
|
|
117
|
-
|
|
118
|
-
Returns:
|
|
119
|
-
list: List of IPv4Address objects in the range (inclusive)
|
|
120
|
-
"""
|
|
121
|
-
start_ip, end_part = entry.split('-')
|
|
122
|
-
start_ip = ipaddress.IPv4Address(start_ip.strip())
|
|
123
|
-
end_ip = start_ip.exploded.rsplit('.', 1)[0] + '.' + end_part.strip()
|
|
124
|
-
|
|
125
|
-
return list(ip_range_to_list(start_ip, ipaddress.IPv4Address(end_ip)))
|
|
126
|
-
|
|
127
|
-
|
|
128
104
|
def ip_range_to_list(start_ip, end_ip):
|
|
129
105
|
"""
|
|
130
106
|
Convert an IP range defined by start and end addresses to a list of addresses.
|
|
@@ -139,4 +115,3 @@ def ip_range_to_list(start_ip, end_ip):
|
|
|
139
115
|
# Yield the range of IPs
|
|
140
116
|
for ip_int in range(int(start_ip), int(end_ip) + 1):
|
|
141
117
|
yield ipaddress.IPv4Address(ip_int)
|
|
142
|
-
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
"""
|
|
3
3
|
|
|
4
4
|
from typing import Optional, Union
|
|
5
|
-
import sys
|
|
6
5
|
import asyncio
|
|
7
6
|
import logging
|
|
8
7
|
import traceback
|
|
@@ -10,6 +9,9 @@ import traceback
|
|
|
10
9
|
from lanscape.core.app_scope import ResourceManager
|
|
11
10
|
from lanscape.core.scan_config import ServiceScanConfig, ServiceScanStrategy
|
|
12
11
|
|
|
12
|
+
# asyncio complains more than it needs to
|
|
13
|
+
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
|
14
|
+
|
|
13
15
|
log = logging.getLogger('ServiceScan')
|
|
14
16
|
SERVICES = ResourceManager('services').get_jsonc('definitions.jsonc')
|
|
15
17
|
|
|
@@ -183,23 +185,3 @@ def scan_service(ip: str, port: int, cfg: ServiceScanConfig) -> str:
|
|
|
183
185
|
|
|
184
186
|
# Use asyncio.run to execute the asynchronous logic synchronously
|
|
185
187
|
return asyncio.run(_async_scan_service(ip, port, cfg=cfg))
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def asyncio_logger_suppression():
|
|
189
|
-
"""Suppress the noisy asyncio transport errors since they are expected in service scanning."""
|
|
190
|
-
|
|
191
|
-
# Reduce noisy asyncio transport errors on Windows by switching to Selector policy
|
|
192
|
-
if sys.platform.startswith("win"):
|
|
193
|
-
try:
|
|
194
|
-
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
195
|
-
except Exception:
|
|
196
|
-
pass
|
|
197
|
-
# Also tone down asyncio logger noise from transport callbacks
|
|
198
|
-
try:
|
|
199
|
-
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
|
200
|
-
except Exception:
|
|
201
|
-
pass
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
asyncio_logger_suppression()
|
|
205
|
-
|
|
@@ -51,6 +51,18 @@ app.jinja_env.filters['is_substring_in_values'] = is_substring_in_values
|
|
|
51
51
|
################################
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def get_runtime_args_safe():
|
|
55
|
+
"""
|
|
56
|
+
Safely get runtime args, returning empty dict if parsing fails.
|
|
57
|
+
This prevents conflicts when the module is imported during testing.
|
|
58
|
+
"""
|
|
59
|
+
try:
|
|
60
|
+
return vars(parse_args())
|
|
61
|
+
except SystemExit:
|
|
62
|
+
# This happens when pytest tries to import the module
|
|
63
|
+
return {}
|
|
64
|
+
|
|
65
|
+
|
|
54
66
|
def set_global_safe(key: str, value):
|
|
55
67
|
""" Safely set global vars without worrying about an exception """
|
|
56
68
|
app_globals = app.jinja_env.globals
|
|
@@ -73,7 +85,7 @@ def set_global_safe(key: str, value):
|
|
|
73
85
|
set_global_safe('app_version', get_installed_version)
|
|
74
86
|
set_global_safe('update_available', is_update_available)
|
|
75
87
|
set_global_safe('latest_version', lookup_latest_version)
|
|
76
|
-
set_global_safe('runtime_args',
|
|
88
|
+
set_global_safe('runtime_args', get_runtime_args_safe)
|
|
77
89
|
set_global_safe('is_local', is_local_run)
|
|
78
90
|
set_global_safe('is_arp_supported', is_arp_supported)
|
|
79
91
|
|
|
@@ -122,4 +134,3 @@ def start_webserver(args: RuntimeArgs) -> int:
|
|
|
122
134
|
'use_reloader': args.reloader
|
|
123
135
|
}
|
|
124
136
|
app.run(**run_args)
|
|
125
|
-
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
data-bs-toggle="tooltip"
|
|
57
57
|
data-bs-placement="top"
|
|
58
58
|
title="ARP lookup is not supported on this system, click for more info"
|
|
59
|
-
onclick="window.open('https://github.com/mdennis281/LANscape/blob/main/
|
|
59
|
+
onclick="window.open('https://github.com/mdennis281/LANscape/blob/main/docs/arp-issues.md', '_blank')"
|
|
60
60
|
>
|
|
61
61
|
help
|
|
62
62
|
</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0b1
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -25,6 +25,9 @@ Requires-Dist: scapy<3.0,>=2.3.2
|
|
|
25
25
|
Requires-Dist: tabulate==0.9.0
|
|
26
26
|
Requires-Dist: pydantic
|
|
27
27
|
Requires-Dist: icmplib
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
28
31
|
Dynamic: license-file
|
|
29
32
|
|
|
30
33
|
# LANscape
|
|
@@ -85,7 +88,7 @@ I use a combination of ARP, ICMP & port testing to determine if a device is onli
|
|
|
85
88
|
Recommendations:
|
|
86
89
|
|
|
87
90
|
- Adjust scan configuration
|
|
88
|
-
- Configure ARP lookup [ARP lookup setup](./
|
|
91
|
+
- Configure ARP lookup [ARP lookup setup](./docs/arp-issues.md)
|
|
89
92
|
- Create a bug
|
|
90
93
|
|
|
91
94
|
|
|
@@ -33,6 +33,7 @@ lanscape/resources/ports/full.json
|
|
|
33
33
|
lanscape/resources/ports/large.json
|
|
34
34
|
lanscape/resources/ports/medium.json
|
|
35
35
|
lanscape/resources/ports/small.json
|
|
36
|
+
lanscape/resources/ports/test_port_list_scan.json
|
|
36
37
|
lanscape/resources/services/definitions.jsonc
|
|
37
38
|
lanscape/ui/__init__.py
|
|
38
39
|
lanscape/ui/app.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lanscape"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.0b1"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Michael Dennis", email="michael@dipduo.com" },
|
|
6
6
|
]
|
|
@@ -29,6 +29,12 @@ dependencies = [
|
|
|
29
29
|
"pydantic",
|
|
30
30
|
"icmplib"
|
|
31
31
|
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=8.0",
|
|
36
|
+
"pytest-cov>=5.0"
|
|
37
|
+
]
|
|
32
38
|
[project.urls]
|
|
33
39
|
Homepage = "https://github.com/mdennis281/py-lanscape"
|
|
34
40
|
Issues = "https://github.com/mdennis281/py-lanscape/issues"
|