domaintools-api 2.3.0__tar.gz → 2.4.0__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.
Files changed (42) hide show
  1. {domaintools_api-2.3.0/domaintools_api.egg-info → domaintools_api-2.4.0}/PKG-INFO +4 -3
  2. domaintools_api-2.4.0/VERSION +1 -0
  3. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/_version.py +1 -1
  4. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/api.py +95 -36
  5. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/__init__.py +0 -1
  6. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/feeds.py +80 -0
  7. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/constants.py +1 -4
  8. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/utils.py +1 -21
  9. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/constants.py +2 -0
  10. {domaintools_api-2.3.0 → domaintools_api-2.4.0/domaintools_api.egg-info}/PKG-INFO +4 -3
  11. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_api.egg-info/SOURCES.txt +0 -1
  12. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_api.egg-info/requires.txt +1 -1
  13. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/pyproject.toml +5 -1
  14. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/tests/test_api.py +16 -28
  15. domaintools_api-2.3.0/VERSION +0 -1
  16. domaintools_api-2.3.0/domaintools/cli/commands/phisheye.py +0 -100
  17. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/LICENSE +0 -0
  18. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/README.md +0 -0
  19. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/__init__.py +0 -0
  20. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/base_results.py +0 -0
  21. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/__init__.py +0 -0
  22. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/api.py +0 -0
  23. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/accounts.py +0 -0
  24. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/detects.py +0 -0
  25. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/domains.py +0 -0
  26. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/ips.py +0 -0
  27. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/commands/iris.py +0 -0
  28. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/cli/main.py +0 -0
  29. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/exceptions.py +0 -0
  30. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/filters.py +0 -0
  31. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/results.py +0 -0
  32. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools/utils.py +0 -0
  33. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_api.egg-info/dependency_links.txt +0 -0
  34. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_api.egg-info/entry_points.txt +0 -0
  35. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_api.egg-info/top_level.txt +0 -0
  36. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/domaintools_async/__init__.py +0 -0
  37. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/setup.cfg +0 -0
  38. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/setup.py +0 -0
  39. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/tests/test_async.py +0 -0
  40. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/tests/test_cli.py +0 -0
  41. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/tests/test_filters.py +0 -0
  42. {domaintools_api-2.3.0 → domaintools_api-2.4.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: domaintools_api
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: DomainTools Official Python API
5
5
  Author-email: DomainTools <integrations@domaintools.com>
6
6
  License: The MIT License (MIT)
@@ -40,12 +40,13 @@ 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
47
47
  Requires-Dist: pytest; extra == "test"
48
48
  Requires-Dist: mock; extra == "test"
49
+ Dynamic: license-file
49
50
 
50
51
  ![domaintools](https://github.com/DomainTools/python_api/raw/main/artwork/logo.png)
51
52
  ===================
@@ -0,0 +1 @@
1
+ 2.4.0
@@ -20,4 +20,4 @@ OTHER DEALINGS IN THE SOFTWARE.
20
20
 
21
21
  """
22
22
 
23
- current = "2.3.0"
23
+ current = "2.4.0"
@@ -411,38 +411,6 @@ class API(object):
411
411
  **kwargs,
412
412
  )
413
413
 
414
- def phisheye(self, query, days_back=None, **kwargs):
415
- """Returns domain results for the specified term for today or the specified number of days_back.
416
- Terms must be setup for monitoring via the web interface: https://research.domaintools.com/phisheye.
417
-
418
- NOTE: Properties of a domain are only provided if we have been able to obtain them.
419
- Many domains will have incomplete data because that information isn't available in their Whois records,
420
- or they don't have DNS results for a name server or IP address.
421
- """
422
- return self._results(
423
- "phisheye",
424
- "/v1/phisheye",
425
- query=query,
426
- days_back=days_back,
427
- items_path=("domains",),
428
- **kwargs,
429
- )
430
-
431
- def phisheye_term_list(self, include_inactive=False, **kwargs):
432
- """Provides a list of terms that are set up for this account.
433
- This call is not charged against your API usage limit.
434
-
435
- NOTE: The terms must be configured in the PhishEye web interface: https://research.domaintools.com/phisheye.
436
- There is no API call to set up the terms.
437
- """
438
- return self._results(
439
- "phisheye_term_list",
440
- "/v1/phisheye/term-list",
441
- include_inactive=include_inactive,
442
- items_path=("terms",),
443
- **kwargs,
444
- )
445
-
446
414
  def iris(
447
415
  self,
448
416
  domain=None,
@@ -1065,7 +1033,21 @@ class API(object):
1065
1033
  )
1066
1034
 
1067
1035
  def nod(self, **kwargs) -> FeedsResults:
1068
- """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
+ """
1069
1051
  validate_feeds_parameters(kwargs)
1070
1052
  endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1071
1053
  source = ENDPOINT_TO_SOURCE_MAP.get(endpoint)
@@ -1082,7 +1064,22 @@ class API(object):
1082
1064
  )
1083
1065
 
1084
1066
  def nad(self, **kwargs) -> FeedsResults:
1085
- """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
+ """
1086
1083
  validate_feeds_parameters(kwargs)
1087
1084
  endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1088
1085
  source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
@@ -1099,7 +1096,22 @@ class API(object):
1099
1096
  )
1100
1097
 
1101
1098
  def domainrdap(self, **kwargs) -> FeedsResults:
1102
- """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
+ """
1103
1115
  validate_feeds_parameters(kwargs)
1104
1116
  endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1105
1117
  source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
@@ -1113,7 +1125,22 @@ class API(object):
1113
1125
  )
1114
1126
 
1115
1127
  def domaindiscovery(self, **kwargs) -> FeedsResults:
1116
- """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
+ """
1117
1144
  validate_feeds_parameters(kwargs)
1118
1145
  endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1119
1146
  source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
@@ -1128,3 +1155,35 @@ class API(object):
1128
1155
  cls=FeedsResults,
1129
1156
  **kwargs,
1130
1157
  )
1158
+
1159
+ def noh(self, **kwargs) -> FeedsResults:
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
+ """
1176
+ validate_feeds_parameters(kwargs)
1177
+ endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1178
+ source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
1179
+ if endpoint == Endpoint.DOWNLOAD.value or kwargs.get("output_format", OutputFormat.JSONL.value) != OutputFormat.CSV.value:
1180
+ # headers param is allowed only in Feed API and CSV format
1181
+ kwargs.pop("headers", None)
1182
+
1183
+ return self._results(
1184
+ f"newly-observed-hosts-feed-({source})",
1185
+ f"v1/{endpoint}/noh/",
1186
+ response_path=(),
1187
+ cls=FeedsResults,
1188
+ **kwargs,
1189
+ )
@@ -2,6 +2,5 @@ from .accounts import *
2
2
  from .iris import *
3
3
  from .domains import *
4
4
  from .ips import *
5
- from .phisheye import *
6
5
  from .detects import *
7
6
  from .feeds import *
@@ -314,3 +314,83 @@ def feeds_domaindiscovery(
314
314
  ),
315
315
  ):
316
316
  DTCLICommand.run(name=c.FEEDS_DOMAINDISCOVERY, params=ctx.params)
317
+
318
+
319
+ @dt_cli.command(
320
+ name=c.FEEDS_NOH,
321
+ help=get_cli_helptext_by_name(command_name=c.FEEDS_NOH),
322
+ )
323
+ def feeds_noh(
324
+ ctx: typer.Context,
325
+ user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
326
+ key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
327
+ creds_file: str = typer.Option(
328
+ "~/.dtapi",
329
+ "-c",
330
+ "--credfile",
331
+ help="Optional file with API username and API key, one per line.",
332
+ ),
333
+ no_verify_ssl: bool = typer.Option(
334
+ False,
335
+ "--no-verify-ssl",
336
+ help="Skip verification of SSL certificate when making HTTPs API calls",
337
+ ),
338
+ no_sign_api_key: bool = typer.Option(
339
+ False,
340
+ "--no-sign-api-key",
341
+ help="Skip signing of api key",
342
+ ),
343
+ header_authentication: bool = typer.Option(
344
+ True,
345
+ "--no-header-auth",
346
+ help="Don't use header authentication",
347
+ ),
348
+ output_format: str = typer.Option(
349
+ "jsonl",
350
+ "-f",
351
+ "--format",
352
+ help=f"Output format in [{OutputFormat.JSONL.value}, {OutputFormat.CSV.value}]",
353
+ callback=DTCLICommand.validate_feeds_format_input,
354
+ ),
355
+ endpoint: str = typer.Option(
356
+ Endpoint.FEED.value,
357
+ "-e",
358
+ "--endpoint",
359
+ help=f"Valid endpoints: [{Endpoint.FEED.value}, {Endpoint.DOWNLOAD.value}]",
360
+ callback=DTCLICommand.validate_endpoint_input,
361
+ ),
362
+ sessionID: str = typer.Option(
363
+ None,
364
+ "--session-id",
365
+ help="Unique identifier for the session",
366
+ ),
367
+ after: str = typer.Option(
368
+ None,
369
+ "--after",
370
+ help="Start of the time window, relative to the current time in seconds, for which data will be provided",
371
+ callback=DTCLICommand.validate_after_or_before_input,
372
+ ),
373
+ before: str = typer.Option(
374
+ None,
375
+ "--before",
376
+ help="The end of the query window in seconds, relative to the current time, inclusive",
377
+ callback=DTCLICommand.validate_after_or_before_input,
378
+ ),
379
+ domain: str = typer.Option(
380
+ None,
381
+ "-d",
382
+ "--domain",
383
+ help="A string value used to filter feed results",
384
+ ),
385
+ headers: bool = typer.Option(
386
+ False,
387
+ "--headers",
388
+ help="Adds a header to the first line of response when text/csv is set in header parameters",
389
+ ),
390
+ top: str = typer.Option(
391
+ None,
392
+ "--top",
393
+ help="Number of results to return in the response payload. This is ignored in download endpoint",
394
+ ),
395
+ ):
396
+ DTCLICommand.run(name=c.FEEDS_NOH, params=ctx.params)
@@ -39,12 +39,9 @@ IRIS_DETECT_MANAGE_WATCHLIST_DOMAINS = "iris_detect_manage_watchlist_domains"
39
39
  IRIS_DETECT_ESCALATE_DOMAINS = "iris_detect_escalate_domains"
40
40
  IRIS_DETECT_IGNORED_DOMAINS = "iris_detect_ignored_domains"
41
41
 
42
- # phisheye
43
- PHISHEYE = "phisheye"
44
- PHISHEYE_TERM_LIST = "phisheye_term_list"
45
-
46
42
  # feeds
47
43
  FEEDS_NAD = "nad"
48
44
  FEEDS_NOD = "nod"
45
+ FEEDS_NOH = "noh"
49
46
  FEEDS_DOMAINRDAP = "domainrdap"
50
47
  FEEDS_DOMAINDISCOVERY = "domaindiscovery"
@@ -29,25 +29,6 @@ def _iris_investigate_helptext():
29
29
  """
30
30
 
31
31
 
32
- def _phisheye_helptext():
33
- return """
34
- Returns domain results for the specified term for today or the specified number of days_back. Terms must be setup for monitoring via the web interface: https://research.domaintools.com/phisheye. \n
35
-
36
- NOTE: Properties of a domain are only provided if we have been able to obtain them. \n
37
- Many domains will have incomplete data because that information isn't available in their Whois records,
38
- or they don't have DNS results for a name server or IP address.
39
- """
40
-
41
-
42
- def _phisheye_termlist():
43
- return """
44
- Provides a list of terms that are set up for this account. This call is not charged against your API usage limit.
45
-
46
- NOTE: The terms must be configured in the PhishEye web interface: https://research.domaintools.com/phisheye. \n
47
- There is no API call to set up the terms.
48
- """
49
-
50
-
51
32
  _command_help_mapper = {
52
33
  c.ACCOUNT_INFORMATION: "Provides a snapshot of your accounts current API usage.",
53
34
  c.AVAILABLE_API_CALLS: "Provides a list of api calls that you can use based on your account information.",
@@ -71,8 +52,6 @@ _command_help_mapper = {
71
52
  c.REVERSE_WHOIS: "Provides list of one or more terms to search for in the Whois record, as a Python list or separated with the pipe character ( | ).",
72
53
  c.WHOIS: "Pass in a domain name or an IP address to perform a whois lookup.",
73
54
  c.WHOIS_HISTORY: "Retrieve historical Whois records of a given domain name.",
74
- c.PHISHEYE: _phisheye_helptext(),
75
- c.PHISHEYE_TERM_LIST: _phisheye_termlist(),
76
55
  c.IRIS: "Performs a search for the provided search terms ANDed together, returning the pivot engine row data for the resulting domains.",
77
56
  c.RISK: "Returns back the risk score for a given domain.",
78
57
  c.RISK_EVIDENCE: "Returns back the detailed risk evidence associated with a given domain.",
@@ -84,6 +63,7 @@ _command_help_mapper = {
84
63
  c.IRIS_DETECT_IGNORED_DOMAINS: "Returns back a list of ignored domains in Iris Detect based on the provided filters.",
85
64
  c.FEEDS_NAD: "Returns back newly active domains feed.",
86
65
  c.FEEDS_NOD: "Returns back newly observed domains feed.",
66
+ c.FEEDS_NOH: "Returns back newly observed hosts feed.",
87
67
  c.FEEDS_DOMAINRDAP: "Returns changes to global domain registration information, populated by the Registration Data Access Protocol (RDAP).",
88
68
  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.",
89
69
  }
@@ -28,6 +28,8 @@ FEEDS_PRODUCTS_LIST = [
28
28
  "newly-active-domains-feed-(s3)",
29
29
  "newly-observed-domains-feed-(api)",
30
30
  "newly-observed-domains-feed-(s3)",
31
+ "newly-observed-hosts-feed-(api)",
32
+ "newly-observed-hosts-feed-(s3)",
31
33
  "domain-registration-data-access-protocol-feed-(api)",
32
34
  "domain-registration-data-access-protocol-feed-(s3)",
33
35
  "real-time-domain-discovery-feed-(api)",
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: domaintools_api
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: DomainTools Official Python API
5
5
  Author-email: DomainTools <integrations@domaintools.com>
6
6
  License: The MIT License (MIT)
@@ -40,12 +40,13 @@ 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
47
47
  Requires-Dist: pytest; extra == "test"
48
48
  Requires-Dist: mock; extra == "test"
49
+ Dynamic: license-file
49
50
 
50
51
  ![domaintools](https://github.com/DomainTools/python_api/raw/main/artwork/logo.png)
51
52
  ===================
@@ -25,7 +25,6 @@ domaintools/cli/commands/domains.py
25
25
  domaintools/cli/commands/feeds.py
26
26
  domaintools/cli/commands/ips.py
27
27
  domaintools/cli/commands/iris.py
28
- domaintools/cli/commands/phisheye.py
29
28
  domaintools_api.egg-info/PKG-INFO
30
29
  domaintools_api.egg-info/SOURCES.txt
31
30
  domaintools_api.egg-info/dependency_links.txt
@@ -1,4 +1,4 @@
1
- httpx
1
+ httpx==0.28.1
2
2
  rich
3
3
  typer
4
4
 
@@ -4,7 +4,11 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "domaintools_api"
7
- dependencies = ["httpx", "rich", "typer"]
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"
@@ -322,16 +322,6 @@ def test_dict_like_behaviour():
322
322
  assert isinstance(whois_google.pop("whois", {}), dict)
323
323
 
324
324
 
325
- @vcr.use_cassette
326
- def test_list_like_behaviour():
327
- with api.phisheye("google") as data:
328
- data.insert(0, {"domain": "woot", "tld": "com"})
329
- assert data["term"] == "google"
330
- for result in data:
331
- assert result["domain"]
332
- assert result["tld"]
333
-
334
-
335
325
  @vcr.use_cassette
336
326
  def test_exception_handling():
337
327
  exception = None
@@ -386,24 +376,6 @@ def test_formats():
386
376
  assert "\n" in str(data.as_list())
387
377
 
388
378
 
389
- @vcr.use_cassette
390
- def test_phisheye():
391
- with api.phisheye("google") as data:
392
- assert data["term"] == "google"
393
- for result in data:
394
- assert result["domain"]
395
- assert result["tld"]
396
-
397
-
398
- @vcr.use_cassette
399
- def test_phisheye_term_list():
400
- with api.phisheye_term_list() as data:
401
- assert data
402
- for term in data:
403
- assert "term" in term
404
- assert type(term["active"]) == bool
405
-
406
-
407
379
  @vcr.use_cassette
408
380
  def test_iris():
409
381
  with pytest.raises(ValueError):
@@ -545,6 +517,22 @@ def test_newly_observed_domains_feed():
545
517
  assert "domain" in feed_result.keys()
546
518
 
547
519
 
520
+ @vcr.use_cassette
521
+ def test_newly_observed_hosts_feed():
522
+ results = feeds_api.noh(after="-60", header_authentication=False)
523
+ for response in results.response():
524
+ assert results.status == 200
525
+
526
+ rows = response.strip().split("\n")
527
+ assert response is not None
528
+ assert len(rows) >= 1
529
+
530
+ for row in rows:
531
+ feed_result = json.loads(row)
532
+ assert "timestamp" in feed_result.keys()
533
+ assert "domain" in feed_result.keys()
534
+
535
+
548
536
  @vcr.use_cassette
549
537
  def test_newly_observed_domains_feed_pagination():
550
538
  results = feeds_api.nod(sessionID="integrations-testing", after="2025-01-16T10:20:00Z")
@@ -1 +0,0 @@
1
- 2.3.0
@@ -1,100 +0,0 @@
1
- import sys
2
- import typer
3
-
4
-
5
- from domaintools.cli.main import dt_cli
6
- from domaintools.cli.api import DTCLICommand
7
- from domaintools.cli.utils import get_cli_helptext_by_name
8
- from domaintools.cli import constants as c
9
-
10
-
11
- @dt_cli.command(
12
- name=c.PHISHEYE,
13
- help=get_cli_helptext_by_name(command_name=c.PHISHEYE),
14
- )
15
- def phisheye(
16
- ctx: typer.Context,
17
- query: str = typer.Option(..., "-q", "--query", help="The domain to query."),
18
- days_back: str = typer.Option(
19
- None,
20
- "--days-back",
21
- help="Use this parameter in exceptional circumstances where you need to search domains registered up to six days prior to the current date. Set the value to an integer in the range of 1-6.",
22
- ),
23
- user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
24
- key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
25
- creds_file: str = typer.Option(
26
- "~/.dtapi",
27
- "-c",
28
- "--credfile",
29
- help="Optional file with API username and API key, one per line.",
30
- ),
31
- rate_limit: bool = typer.Option(
32
- False,
33
- "-l",
34
- "--rate-limit",
35
- help="Rate limit API calls against the API based on per minute limits.",
36
- ),
37
- format: str = typer.Option(
38
- "json",
39
- "-f",
40
- "--format",
41
- help="Output format in {'list', 'json', 'xml', 'html'}",
42
- callback=DTCLICommand.validate_format_input,
43
- ),
44
- out_file: typer.FileTextWrite = typer.Option(
45
- sys.stdout, "-o", "--out-file", help="Output file (defaults to stdout)"
46
- ),
47
- no_verify_ssl: bool = typer.Option(
48
- False,
49
- "--no-verify-ssl",
50
- help="Skip verification of SSL certificate when making HTTPs API calls",
51
- ),
52
- ):
53
- DTCLICommand.run(name=c.PHISHEYE, params=ctx.params)
54
-
55
-
56
- @dt_cli.command(
57
- name=c.PHISHEYE_TERM_LIST,
58
- help=get_cli_helptext_by_name(command_name=c.PHISHEYE_TERM_LIST),
59
- )
60
- def phisheye_termlist(
61
- ctx: typer.Context,
62
- include_inactive: bool = typer.Option(
63
- False,
64
- "--include-inactive",
65
- help="Use this parameter to display terms that may have been inactivated in users' lists.",
66
- ),
67
- user: str = typer.Option(None, "-u", "--user", help="Domaintools API Username."),
68
- key: str = typer.Option(None, "-k", "--key", help="DomainTools API key"),
69
- creds_file: str = typer.Option(
70
- "~/.dtapi",
71
- "-c",
72
- "--credfile",
73
- help="Optional file with API username and API key, one per line.",
74
- ),
75
- rate_limit: bool = typer.Option(
76
- False,
77
- "-l",
78
- "--rate-limit",
79
- help="Rate limit API calls against the API based on per minute limits.",
80
- ),
81
- format: str = typer.Option(
82
- "json",
83
- "-f",
84
- "--format",
85
- help="Output format in {'list', 'json', 'xml', 'html'}",
86
- callback=DTCLICommand.validate_format_input,
87
- ),
88
- out_file: typer.FileTextWrite = typer.Option(
89
- sys.stdout, "-o", "--out-file", help="Output file (defaults to stdout)"
90
- ),
91
- no_verify_ssl: bool = typer.Option(
92
- False,
93
- "--no-verify-ssl",
94
- help="Skip verification of SSL certificate when making HTTPs API calls",
95
- ),
96
- ):
97
- DTCLICommand.run(name=c.PHISHEYE_TERM_LIST, params=ctx.params)
98
-
99
-
100
- __all__ = ["phisheye", "phisheye_termlist"]
File without changes