domaintools-api-test-upload 2.4.0__tar.gz → 2.4.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.
- {domaintools_api_test_upload-2.4.0/domaintools_api_test_upload.egg-info → domaintools_api_test_upload-2.4.1}/PKG-INFO +2 -2
- domaintools_api_test_upload-2.4.1/VERSION +1 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/_version.py +1 -1
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/api.py +142 -6
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/api.py +1 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/feeds.py +160 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/constants.py +2 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/utils.py +2 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/constants.py +4 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1/domaintools_api_test_upload.egg-info}/PKG-INFO +2 -2
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_api_test_upload.egg-info/requires.txt +1 -1
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/pyproject.toml +5 -1
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_api.py +40 -0
- domaintools_api_test_upload-2.4.0/VERSION +0 -1
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/LICENSE +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/README.md +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/__init__.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/base_results.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/__init__.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/__init__.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/accounts.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/detects.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/domains.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/ips.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/commands/iris.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/main.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/exceptions.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/filters.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/results.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/utils.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_api_test_upload.egg-info/SOURCES.txt +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_api_test_upload.egg-info/dependency_links.txt +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_api_test_upload.egg-info/entry_points.txt +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_api_test_upload.egg-info/top_level.txt +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools_async/__init__.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/setup.cfg +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/setup.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_async.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_cli.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_filters.py +0 -0
- {domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: domaintools_api_test_upload
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: DomainTools Official Python API
|
|
5
5
|
Author-email: DomainTools <integrations@domaintools.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -40,7 +40,7 @@ Classifier: Topic :: Utilities
|
|
|
40
40
|
Requires-Python: >=3.9
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE
|
|
43
|
-
Requires-Dist: httpx
|
|
43
|
+
Requires-Dist: httpx==0.28.1
|
|
44
44
|
Requires-Dist: rich
|
|
45
45
|
Requires-Dist: typer
|
|
46
46
|
Provides-Extra: test
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.4.1
|
|
@@ -94,7 +94,7 @@ class API(object):
|
|
|
94
94
|
|
|
95
95
|
def _build_api_url(self, api_url=None, api_port=None):
|
|
96
96
|
"""Build the API url based on the given url and port. Defaults to `https://api.domaintools.com`"""
|
|
97
|
-
rest_api_url = "https://api.domaintools.com"
|
|
97
|
+
rest_api_url = "https://api.domaintools.com.test"
|
|
98
98
|
if api_url:
|
|
99
99
|
rest_api_url = api_url
|
|
100
100
|
|
|
@@ -1033,7 +1033,21 @@ class API(object):
|
|
|
1033
1033
|
)
|
|
1034
1034
|
|
|
1035
1035
|
def nod(self, **kwargs) -> FeedsResults:
|
|
1036
|
-
"""Returns back list of the newly observed domains feed
|
|
1036
|
+
"""Returns back list of the newly observed domains feed.
|
|
1037
|
+
Apex-level domains (e.g. example.com but not www.example.com) that we observe for the first time, and have not observed previously with our global DNS sensor network.
|
|
1038
|
+
|
|
1039
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1040
|
+
|
|
1041
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1042
|
+
|
|
1043
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1044
|
+
|
|
1045
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1046
|
+
|
|
1047
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1048
|
+
|
|
1049
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1050
|
+
"""
|
|
1037
1051
|
validate_feeds_parameters(kwargs)
|
|
1038
1052
|
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1039
1053
|
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint)
|
|
@@ -1050,7 +1064,22 @@ class API(object):
|
|
|
1050
1064
|
)
|
|
1051
1065
|
|
|
1052
1066
|
def nad(self, **kwargs) -> FeedsResults:
|
|
1053
|
-
"""Returns back list of the newly active domains feed
|
|
1067
|
+
"""Returns back list of the newly active domains feed. Contains domains that have been observed after having not been seen for at least 10 days in passive DNS.
|
|
1068
|
+
Apex-level domains (e.g. example.com but not www.example.com) that we observe based on the latest lifecycle of the domain. A domain may be seen either for the first time ever, or again after at least 10 days of inactivity (no observed resolutions in DNS).
|
|
1069
|
+
Populated with our global passive DNS (pDNS) sensor network.
|
|
1070
|
+
|
|
1071
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1072
|
+
|
|
1073
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1074
|
+
|
|
1075
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1076
|
+
|
|
1077
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1078
|
+
|
|
1079
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1080
|
+
|
|
1081
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1082
|
+
"""
|
|
1054
1083
|
validate_feeds_parameters(kwargs)
|
|
1055
1084
|
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1056
1085
|
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
@@ -1067,7 +1096,22 @@ class API(object):
|
|
|
1067
1096
|
)
|
|
1068
1097
|
|
|
1069
1098
|
def domainrdap(self, **kwargs) -> FeedsResults:
|
|
1070
|
-
"""Returns changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP)
|
|
1099
|
+
"""Returns changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP).
|
|
1100
|
+
Compliments the 5-Minute WHOIS Feed as registries and registrars switch from Whois to RDAP.
|
|
1101
|
+
Contains parsed and raw RDAP-format domain registration data, emitted as soon as they are collected and parsed into a normalized structure.
|
|
1102
|
+
|
|
1103
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1104
|
+
|
|
1105
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1106
|
+
|
|
1107
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1108
|
+
|
|
1109
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1110
|
+
|
|
1111
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1112
|
+
|
|
1113
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1114
|
+
"""
|
|
1071
1115
|
validate_feeds_parameters(kwargs)
|
|
1072
1116
|
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1073
1117
|
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
@@ -1081,7 +1125,22 @@ class API(object):
|
|
|
1081
1125
|
)
|
|
1082
1126
|
|
|
1083
1127
|
def domaindiscovery(self, **kwargs) -> FeedsResults:
|
|
1084
|
-
"""Returns new domains as they are either discovered in domain registration information, observed by our global sensor network, or reported by trusted third parties"
|
|
1128
|
+
"""Returns new domains as they are either discovered in domain registration information, observed by our global sensor network, or reported by trusted third parties".
|
|
1129
|
+
Contains domains that are newly-discovered by Domain Tools in both passive and active DNS sources, emitted as soon as they are first observed.
|
|
1130
|
+
New domains as they are either discovered in domain registration information, observed by our global sensor network, or reported by trusted third parties.
|
|
1131
|
+
|
|
1132
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1133
|
+
|
|
1134
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1135
|
+
|
|
1136
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1137
|
+
|
|
1138
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1139
|
+
|
|
1140
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1141
|
+
|
|
1142
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1143
|
+
"""
|
|
1085
1144
|
validate_feeds_parameters(kwargs)
|
|
1086
1145
|
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1087
1146
|
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
@@ -1098,7 +1157,22 @@ class API(object):
|
|
|
1098
1157
|
)
|
|
1099
1158
|
|
|
1100
1159
|
def noh(self, **kwargs) -> FeedsResults:
|
|
1101
|
-
"""Returns back list of the newly observed hostnames feed
|
|
1160
|
+
"""Returns back list of the newly observed hostnames feed.
|
|
1161
|
+
Contains fully qualified domain names (i.e. host names) that have never been seen before in passive DNS, emitted as soon as they are first observed.
|
|
1162
|
+
Hostname resolutions that we observe for the first time with our global DNS sensor network.
|
|
1163
|
+
|
|
1164
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1165
|
+
|
|
1166
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1167
|
+
|
|
1168
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1169
|
+
|
|
1170
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1171
|
+
|
|
1172
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1173
|
+
|
|
1174
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1175
|
+
"""
|
|
1102
1176
|
validate_feeds_parameters(kwargs)
|
|
1103
1177
|
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1104
1178
|
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
@@ -1113,3 +1187,65 @@ class API(object):
|
|
|
1113
1187
|
cls=FeedsResults,
|
|
1114
1188
|
**kwargs,
|
|
1115
1189
|
)
|
|
1190
|
+
|
|
1191
|
+
def realtime_domain_risk(self, **kwargs) -> FeedsResults:
|
|
1192
|
+
"""Returns back list of the realtime domain risk feed.
|
|
1193
|
+
Contains realtime domain risk information for apex-level domains, regardless of observed traffic.
|
|
1194
|
+
|
|
1195
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1196
|
+
|
|
1197
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1198
|
+
|
|
1199
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1200
|
+
|
|
1201
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1202
|
+
|
|
1203
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1204
|
+
|
|
1205
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1206
|
+
"""
|
|
1207
|
+
validate_feeds_parameters(kwargs)
|
|
1208
|
+
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1209
|
+
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
1210
|
+
if endpoint == Endpoint.DOWNLOAD.value or kwargs.get("output_format", OutputFormat.JSONL.value) != OutputFormat.CSV.value:
|
|
1211
|
+
# headers param is allowed only in Feed API and CSV format
|
|
1212
|
+
kwargs.pop("headers", None)
|
|
1213
|
+
|
|
1214
|
+
return self._results(
|
|
1215
|
+
f"domain-risk-({source})",
|
|
1216
|
+
f"v1/{endpoint}/domainrisk/",
|
|
1217
|
+
response_path=(),
|
|
1218
|
+
cls=FeedsResults,
|
|
1219
|
+
**kwargs,
|
|
1220
|
+
)
|
|
1221
|
+
|
|
1222
|
+
def domainhotlist(self, **kwargs) -> FeedsResults:
|
|
1223
|
+
"""Returns back list of domain hotlist feed.
|
|
1224
|
+
Contains high-risk, apex-level domains that are observed by DomainTools' global sensor network to be active within 24 hours.
|
|
1225
|
+
|
|
1226
|
+
domain: str: Filter for an exact domain or a substring contained within a domain by prefixing or suffixing your substring with "*". Check the documentation for examples
|
|
1227
|
+
|
|
1228
|
+
before: str: Filter for records before the given time value inclusive or time offset relative to now
|
|
1229
|
+
|
|
1230
|
+
after: str: Filter for records after the given time value inclusive or time offset relative to now
|
|
1231
|
+
|
|
1232
|
+
headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
|
|
1233
|
+
|
|
1234
|
+
sessionID: str: A custom string to distinguish between different sessions
|
|
1235
|
+
|
|
1236
|
+
top: int: Limit the number of results to the top N, where N is the value of this parameter.
|
|
1237
|
+
"""
|
|
1238
|
+
validate_feeds_parameters(kwargs)
|
|
1239
|
+
endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
|
|
1240
|
+
source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
|
|
1241
|
+
if endpoint == Endpoint.DOWNLOAD.value or kwargs.get("output_format", OutputFormat.JSONL.value) != OutputFormat.CSV.value:
|
|
1242
|
+
# headers param is allowed only in Feed API and CSV format
|
|
1243
|
+
kwargs.pop("headers", None)
|
|
1244
|
+
|
|
1245
|
+
return self._results(
|
|
1246
|
+
f"domain-hotlist-feed-({source})",
|
|
1247
|
+
f"v1/{endpoint}/domainhotlist/",
|
|
1248
|
+
response_path=(),
|
|
1249
|
+
cls=FeedsResults,
|
|
1250
|
+
**kwargs,
|
|
1251
|
+
)
|
|
@@ -394,3 +394,163 @@ def feeds_noh(
|
|
|
394
394
|
),
|
|
395
395
|
):
|
|
396
396
|
DTCLICommand.run(name=c.FEEDS_NOH, params=ctx.params)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
@dt_cli.command(
|
|
400
|
+
name=c.FEEDS_DOMAINHOTLIST,
|
|
401
|
+
help=get_cli_helptext_by_name(command_name=c.FEEDS_DOMAINHOTLIST),
|
|
402
|
+
)
|
|
403
|
+
def feeds_domainhotlist(
|
|
404
|
+
ctx: typer.Context,
|
|
405
|
+
user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
|
|
406
|
+
key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
|
|
407
|
+
creds_file: str = typer.Option(
|
|
408
|
+
"~/.dtapi",
|
|
409
|
+
"-c",
|
|
410
|
+
"--credfile",
|
|
411
|
+
help="Optional file with API username and API key, one per line.",
|
|
412
|
+
),
|
|
413
|
+
no_verify_ssl: bool = typer.Option(
|
|
414
|
+
False,
|
|
415
|
+
"--no-verify-ssl",
|
|
416
|
+
help="Skip verification of SSL certificate when making HTTPs API calls",
|
|
417
|
+
),
|
|
418
|
+
no_sign_api_key: bool = typer.Option(
|
|
419
|
+
False,
|
|
420
|
+
"--no-sign-api-key",
|
|
421
|
+
help="Skip signing of api key",
|
|
422
|
+
),
|
|
423
|
+
header_authentication: bool = typer.Option(
|
|
424
|
+
True,
|
|
425
|
+
"--no-header-auth",
|
|
426
|
+
help="Don't use header authentication",
|
|
427
|
+
),
|
|
428
|
+
output_format: str = typer.Option(
|
|
429
|
+
"jsonl",
|
|
430
|
+
"-f",
|
|
431
|
+
"--format",
|
|
432
|
+
help=f"Output format in [{OutputFormat.JSONL.value}, {OutputFormat.CSV.value}]",
|
|
433
|
+
callback=DTCLICommand.validate_feeds_format_input,
|
|
434
|
+
),
|
|
435
|
+
endpoint: str = typer.Option(
|
|
436
|
+
Endpoint.FEED.value,
|
|
437
|
+
"-e",
|
|
438
|
+
"--endpoint",
|
|
439
|
+
help=f"Valid endpoints: [{Endpoint.FEED.value}, {Endpoint.DOWNLOAD.value}]",
|
|
440
|
+
callback=DTCLICommand.validate_endpoint_input,
|
|
441
|
+
),
|
|
442
|
+
sessionID: str = typer.Option(
|
|
443
|
+
None,
|
|
444
|
+
"--session-id",
|
|
445
|
+
help="Unique identifier for the session",
|
|
446
|
+
),
|
|
447
|
+
after: str = typer.Option(
|
|
448
|
+
None,
|
|
449
|
+
"--after",
|
|
450
|
+
help="Start of the time window, relative to the current time in seconds, for which data will be provided",
|
|
451
|
+
callback=DTCLICommand.validate_after_or_before_input,
|
|
452
|
+
),
|
|
453
|
+
before: str = typer.Option(
|
|
454
|
+
None,
|
|
455
|
+
"--before",
|
|
456
|
+
help="The end of the query window in seconds, relative to the current time, inclusive",
|
|
457
|
+
callback=DTCLICommand.validate_after_or_before_input,
|
|
458
|
+
),
|
|
459
|
+
domain: str = typer.Option(
|
|
460
|
+
None,
|
|
461
|
+
"-d",
|
|
462
|
+
"--domain",
|
|
463
|
+
help="A string value used to filter feed results",
|
|
464
|
+
),
|
|
465
|
+
headers: bool = typer.Option(
|
|
466
|
+
False,
|
|
467
|
+
"--headers",
|
|
468
|
+
help="Adds a header to the first line of response when text/csv is set in header parameters",
|
|
469
|
+
),
|
|
470
|
+
top: str = typer.Option(
|
|
471
|
+
None,
|
|
472
|
+
"--top",
|
|
473
|
+
help="Number of results to return in the response payload. This is ignored in download endpoint",
|
|
474
|
+
),
|
|
475
|
+
):
|
|
476
|
+
DTCLICommand.run(name=c.FEEDS_DOMAINHOTLIST, params=ctx.params)
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
@dt_cli.command(
|
|
480
|
+
name=c.FEEDS_REALTIME_DOMAIN_RISK,
|
|
481
|
+
help=get_cli_helptext_by_name(command_name=c.FEEDS_REALTIME_DOMAIN_RISK),
|
|
482
|
+
)
|
|
483
|
+
def feeds_realtime_domain_risk(
|
|
484
|
+
ctx: typer.Context,
|
|
485
|
+
user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
|
|
486
|
+
key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
|
|
487
|
+
creds_file: str = typer.Option(
|
|
488
|
+
"~/.dtapi",
|
|
489
|
+
"-c",
|
|
490
|
+
"--credfile",
|
|
491
|
+
help="Optional file with API username and API key, one per line.",
|
|
492
|
+
),
|
|
493
|
+
no_verify_ssl: bool = typer.Option(
|
|
494
|
+
False,
|
|
495
|
+
"--no-verify-ssl",
|
|
496
|
+
help="Skip verification of SSL certificate when making HTTPs API calls",
|
|
497
|
+
),
|
|
498
|
+
no_sign_api_key: bool = typer.Option(
|
|
499
|
+
False,
|
|
500
|
+
"--no-sign-api-key",
|
|
501
|
+
help="Skip signing of api key",
|
|
502
|
+
),
|
|
503
|
+
header_authentication: bool = typer.Option(
|
|
504
|
+
True,
|
|
505
|
+
"--no-header-auth",
|
|
506
|
+
help="Don't use header authentication",
|
|
507
|
+
),
|
|
508
|
+
output_format: str = typer.Option(
|
|
509
|
+
"jsonl",
|
|
510
|
+
"-f",
|
|
511
|
+
"--format",
|
|
512
|
+
help=f"Output format in [{OutputFormat.JSONL.value}, {OutputFormat.CSV.value}]",
|
|
513
|
+
callback=DTCLICommand.validate_feeds_format_input,
|
|
514
|
+
),
|
|
515
|
+
endpoint: str = typer.Option(
|
|
516
|
+
Endpoint.FEED.value,
|
|
517
|
+
"-e",
|
|
518
|
+
"--endpoint",
|
|
519
|
+
help=f"Valid endpoints: [{Endpoint.FEED.value}, {Endpoint.DOWNLOAD.value}]",
|
|
520
|
+
callback=DTCLICommand.validate_endpoint_input,
|
|
521
|
+
),
|
|
522
|
+
sessionID: str = typer.Option(
|
|
523
|
+
None,
|
|
524
|
+
"--session-id",
|
|
525
|
+
help="Unique identifier for the session",
|
|
526
|
+
),
|
|
527
|
+
after: str = typer.Option(
|
|
528
|
+
None,
|
|
529
|
+
"--after",
|
|
530
|
+
help="Start of the time window, relative to the current time in seconds, for which data will be provided",
|
|
531
|
+
callback=DTCLICommand.validate_after_or_before_input,
|
|
532
|
+
),
|
|
533
|
+
before: str = typer.Option(
|
|
534
|
+
None,
|
|
535
|
+
"--before",
|
|
536
|
+
help="The end of the query window in seconds, relative to the current time, inclusive",
|
|
537
|
+
callback=DTCLICommand.validate_after_or_before_input,
|
|
538
|
+
),
|
|
539
|
+
domain: str = typer.Option(
|
|
540
|
+
None,
|
|
541
|
+
"-d",
|
|
542
|
+
"--domain",
|
|
543
|
+
help="A string value used to filter feed results",
|
|
544
|
+
),
|
|
545
|
+
headers: bool = typer.Option(
|
|
546
|
+
False,
|
|
547
|
+
"--headers",
|
|
548
|
+
help="Adds a header to the first line of response when text/csv is set in header parameters",
|
|
549
|
+
),
|
|
550
|
+
top: str = typer.Option(
|
|
551
|
+
None,
|
|
552
|
+
"--top",
|
|
553
|
+
help="Number of results to return in the response payload. This is ignored in download endpoint",
|
|
554
|
+
),
|
|
555
|
+
):
|
|
556
|
+
DTCLICommand.run(name=c.FEEDS_REALTIME_DOMAIN_RISK, params=ctx.params)
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/constants.py
RENAMED
|
@@ -43,5 +43,7 @@ IRIS_DETECT_IGNORED_DOMAINS = "iris_detect_ignored_domains"
|
|
|
43
43
|
FEEDS_NAD = "nad"
|
|
44
44
|
FEEDS_NOD = "nod"
|
|
45
45
|
FEEDS_NOH = "noh"
|
|
46
|
+
FEEDS_DOMAINHOTLIST = "domainhotlist"
|
|
46
47
|
FEEDS_DOMAINRDAP = "domainrdap"
|
|
47
48
|
FEEDS_DOMAINDISCOVERY = "domaindiscovery"
|
|
49
|
+
FEEDS_REALTIME_DOMAIN_RISK = "realtime_domain_risk"
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/utils.py
RENAMED
|
@@ -64,8 +64,10 @@ _command_help_mapper = {
|
|
|
64
64
|
c.FEEDS_NAD: "Returns back newly active domains feed.",
|
|
65
65
|
c.FEEDS_NOD: "Returns back newly observed domains feed.",
|
|
66
66
|
c.FEEDS_NOH: "Returns back newly observed hosts feed.",
|
|
67
|
+
c.FEEDS_DOMAINHOTLIST: "Returns domaint hotlist feed.",
|
|
67
68
|
c.FEEDS_DOMAINRDAP: "Returns changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP).",
|
|
68
69
|
c.FEEDS_DOMAINDISCOVERY: "Returns new domains as they are either discovered in domain registration information, observed by our global sensor network, or reported by trusted third parties.",
|
|
70
|
+
c.FEEDS_REALTIME_DOMAIN_RISK: "Returns realtime domain risk information for apex-level domains, regardless of observed traffic.",
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/constants.py
RENAMED
|
@@ -30,8 +30,12 @@ FEEDS_PRODUCTS_LIST = [
|
|
|
30
30
|
"newly-observed-domains-feed-(s3)",
|
|
31
31
|
"newly-observed-hosts-feed-(api)",
|
|
32
32
|
"newly-observed-hosts-feed-(s3)",
|
|
33
|
+
"domain-hotlist-feed-(api)",
|
|
34
|
+
"domain-hotlist-feed-(s3)",
|
|
33
35
|
"domain-registration-data-access-protocol-feed-(api)",
|
|
34
36
|
"domain-registration-data-access-protocol-feed-(s3)",
|
|
37
|
+
"domain-risk-feed-(api)",
|
|
38
|
+
"domain-risk-feed-(s3)",
|
|
35
39
|
"real-time-domain-discovery-feed-(api)",
|
|
36
40
|
"real-time-domain-discovery-feed-(s3)",
|
|
37
41
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: domaintools_api_test_upload
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: DomainTools Official Python API
|
|
5
5
|
Author-email: DomainTools <integrations@domaintools.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -40,7 +40,7 @@ Classifier: Topic :: Utilities
|
|
|
40
40
|
Requires-Python: >=3.9
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE
|
|
43
|
-
Requires-Dist: httpx
|
|
43
|
+
Requires-Dist: httpx==0.28.1
|
|
44
44
|
Requires-Dist: rich
|
|
45
45
|
Requires-Dist: typer
|
|
46
46
|
Provides-Extra: test
|
|
@@ -4,7 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "domaintools_api_test_upload"
|
|
7
|
-
dependencies = [
|
|
7
|
+
dependencies = [
|
|
8
|
+
"httpx==0.28.1",
|
|
9
|
+
"rich",
|
|
10
|
+
"typer"
|
|
11
|
+
]
|
|
8
12
|
requires-python = ">= 3.9"
|
|
9
13
|
authors = [{ name = "DomainTools", email = "integrations@domaintools.com" }]
|
|
10
14
|
description = "DomainTools Official Python API"
|
|
@@ -663,3 +663,43 @@ def test_feeds_endpoint_should_raise_error_if_asked_csv_format_for_download_api(
|
|
|
663
663
|
feeds_api.domaindiscovery(after="-60", output_format="csv", endpoint="download")
|
|
664
664
|
|
|
665
665
|
assert str(excinfo.value) == "csv format is not available in download API."
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
@vcr.use_cassette
|
|
669
|
+
def test_realtime_domain_risk():
|
|
670
|
+
results = feeds_api.realtime_domain_risk(after="-60", header_authentication=False)
|
|
671
|
+
for response in results.response():
|
|
672
|
+
assert results.status == 200
|
|
673
|
+
|
|
674
|
+
rows = response.strip().split("\n")
|
|
675
|
+
assert response is not None
|
|
676
|
+
assert len(rows) >= 1
|
|
677
|
+
|
|
678
|
+
for row in rows:
|
|
679
|
+
feed_result = json.loads(row)
|
|
680
|
+
assert "timestamp" in feed_result.keys()
|
|
681
|
+
assert "domain" in feed_result.keys()
|
|
682
|
+
assert "phishing_risk" in feed_result.keys()
|
|
683
|
+
assert "malware_risk" in feed_result.keys()
|
|
684
|
+
assert "proximity_risk" in feed_result.keys()
|
|
685
|
+
assert "overall_risk" in feed_result.keys()
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
@vcr.use_cassette
|
|
689
|
+
def test_domain_hotlist():
|
|
690
|
+
results = feeds_api.domainhotlist(after="-60", header_authentication=False)
|
|
691
|
+
for response in results.response():
|
|
692
|
+
assert results.status == 200
|
|
693
|
+
|
|
694
|
+
rows = response.strip().split("\n")
|
|
695
|
+
assert response is not None
|
|
696
|
+
assert len(rows) >= 1
|
|
697
|
+
|
|
698
|
+
for row in rows:
|
|
699
|
+
feed_result = json.loads(row)
|
|
700
|
+
assert "timestamp" in feed_result.keys()
|
|
701
|
+
assert "domain" in feed_result.keys()
|
|
702
|
+
assert "phishing_risk" in feed_result.keys()
|
|
703
|
+
assert "malware_risk" in feed_result.keys()
|
|
704
|
+
assert "proximity_risk" in feed_result.keys()
|
|
705
|
+
assert "overall_risk" in feed_result.keys()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.4.0
|
|
File without changes
|
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/__init__.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/base_results.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/cli/main.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/exceptions.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/filters.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/results.py
RENAMED
|
File without changes
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/domaintools/utils.py
RENAMED
|
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
|
{domaintools_api_test_upload-2.4.0 → domaintools_api_test_upload-2.4.1}/tests/test_filters.py
RENAMED
|
File without changes
|
|
File without changes
|