domaintools-api 2.4.0__tar.gz → 2.5.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 (41) hide show
  1. {domaintools_api-2.4.0/domaintools_api.egg-info → domaintools_api-2.5.0}/PKG-INFO +41 -1
  2. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/README.md +41 -1
  3. domaintools_api-2.5.0/VERSION +1 -0
  4. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/_version.py +1 -1
  5. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/api.py +70 -3
  6. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/feeds.py +160 -0
  7. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/constants.py +2 -0
  8. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/utils.py +2 -0
  9. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/constants.py +4 -0
  10. {domaintools_api-2.4.0 → domaintools_api-2.5.0/domaintools_api.egg-info}/PKG-INFO +41 -1
  11. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/tests/test_api.py +51 -1
  12. domaintools_api-2.4.0/VERSION +0 -1
  13. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/LICENSE +0 -0
  14. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/__init__.py +0 -0
  15. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/base_results.py +0 -0
  16. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/__init__.py +0 -0
  17. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/api.py +0 -0
  18. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/__init__.py +0 -0
  19. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/accounts.py +0 -0
  20. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/detects.py +0 -0
  21. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/domains.py +0 -0
  22. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/ips.py +0 -0
  23. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/commands/iris.py +0 -0
  24. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/cli/main.py +0 -0
  25. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/exceptions.py +0 -0
  26. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/filters.py +0 -0
  27. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/results.py +0 -0
  28. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools/utils.py +0 -0
  29. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_api.egg-info/SOURCES.txt +0 -0
  30. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_api.egg-info/dependency_links.txt +0 -0
  31. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_api.egg-info/entry_points.txt +0 -0
  32. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_api.egg-info/requires.txt +0 -0
  33. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_api.egg-info/top_level.txt +0 -0
  34. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/domaintools_async/__init__.py +0 -0
  35. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/pyproject.toml +0 -0
  36. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/setup.cfg +0 -0
  37. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/setup.py +0 -0
  38. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/tests/test_async.py +0 -0
  39. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/tests/test_cli.py +0 -0
  40. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/tests/test_filters.py +0 -0
  41. {domaintools_api-2.4.0 → domaintools_api-2.5.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: domaintools_api
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: DomainTools Official Python API
5
5
  Author-email: DomainTools <integrations@domaintools.com>
6
6
  License: The MIT License (MIT)
@@ -321,3 +321,43 @@ results = api.nod(sessionID="my-session-id", after=-7200)
321
321
  for partial_result in results.response() # generator that holds NOD feeds data for the past 2 hours and is expected to request multiple times
322
322
  # do things to partial_result
323
323
  ```
324
+
325
+
326
+ Running E2E Tests Locally
327
+ ===================
328
+ For now, e2e tests only covers proxy and ssl testing. We are expected to broaden our e2e tests to other scenarios moving forward.
329
+ To add more e2e tests, put these in the `../tests/e2e` folder.
330
+
331
+ ## Preparation
332
+ - Create virtual environment.
333
+ ```bash
334
+ python3 -m venv venv
335
+ ```
336
+
337
+ - Activate virtual environment
338
+ ```bash
339
+ source venv/bin/activate
340
+ ```
341
+
342
+ - Install dependencies.
343
+ ```bash
344
+ pip install -r requirements/development.txt
345
+ ```
346
+
347
+ - From the python_api project root directory, install the package.
348
+ ```bash
349
+ pip install -e .
350
+ ```
351
+
352
+ - Export api credentials to use.
353
+ ```bash
354
+ export TEST_USER=<user-key>
355
+ export TEST_KEY=<api-key>
356
+ ```
357
+
358
+ ## Run the end-to-end test script
359
+ - Before running the test, be sure that docker is running.
360
+ - Execute the e2e test script .
361
+ ```bash
362
+ sh tests/e2e/scripts/test_e2e_runner.sh
363
+ ```
@@ -270,4 +270,44 @@ results = api.nod(sessionID="my-session-id", after=-7200)
270
270
 
271
271
  for partial_result in results.response() # generator that holds NOD feeds data for the past 2 hours and is expected to request multiple times
272
272
  # do things to partial_result
273
- ```
273
+ ```
274
+
275
+
276
+ Running E2E Tests Locally
277
+ ===================
278
+ For now, e2e tests only covers proxy and ssl testing. We are expected to broaden our e2e tests to other scenarios moving forward.
279
+ To add more e2e tests, put these in the `../tests/e2e` folder.
280
+
281
+ ## Preparation
282
+ - Create virtual environment.
283
+ ```bash
284
+ python3 -m venv venv
285
+ ```
286
+
287
+ - Activate virtual environment
288
+ ```bash
289
+ source venv/bin/activate
290
+ ```
291
+
292
+ - Install dependencies.
293
+ ```bash
294
+ pip install -r requirements/development.txt
295
+ ```
296
+
297
+ - From the python_api project root directory, install the package.
298
+ ```bash
299
+ pip install -e .
300
+ ```
301
+
302
+ - Export api credentials to use.
303
+ ```bash
304
+ export TEST_USER=<user-key>
305
+ export TEST_KEY=<api-key>
306
+ ```
307
+
308
+ ## Run the end-to-end test script
309
+ - Before running the test, be sure that docker is running.
310
+ - Execute the e2e test script .
311
+ ```bash
312
+ sh tests/e2e/scripts/test_e2e_runner.sh
313
+ ```
@@ -0,0 +1 @@
1
+ 2.5.0
@@ -20,4 +20,4 @@ OTHER DEALINGS IN THE SOFTWARE.
20
20
 
21
21
  """
22
22
 
23
- current = "2.4.0"
23
+ current = "2.5.0"
@@ -1,8 +1,10 @@
1
1
  from datetime import datetime, timedelta, timezone
2
- from hashlib import sha1, sha256, md5
2
+ from hashlib import sha1, sha256
3
3
  from hmac import new as hmac
4
+ from typing import Union
4
5
 
5
6
  import re
7
+ import ssl
6
8
 
7
9
  from domaintools.constants import Endpoint, ENDPOINT_TO_SOURCE_MAP, FEEDS_PRODUCTS_LIST, OutputFormat
8
10
  from domaintools._version import current as version
@@ -24,7 +26,7 @@ from domaintools.filters import (
24
26
  from domaintools.utils import validate_feeds_parameters
25
27
 
26
28
 
27
- AVAILABLE_KEY_SIGN_HASHES = ["sha1", "sha256", "md5"]
29
+ AVAILABLE_KEY_SIGN_HASHES = ["sha1", "sha256"]
28
30
 
29
31
 
30
32
  def delimited(items, character="|"):
@@ -76,7 +78,7 @@ class API(object):
76
78
  self.username = username
77
79
  self.key = key
78
80
  self.https = https
79
- self.verify_ssl = verify_ssl
81
+ self.verify_ssl = self._get_ssl_default_context(verify_ssl)
80
82
  self.rate_limit = rate_limit
81
83
  self.proxy_url = proxy_url
82
84
  self.extra_request_params = {}
@@ -92,6 +94,9 @@ class API(object):
92
94
  if proxy_url and not isinstance(proxy_url, str):
93
95
  raise Exception("Proxy URL must be a string. For example: '127.0.0.1:8888'")
94
96
 
97
+ def _get_ssl_default_context(self, verify_ssl: Union[str, bool]):
98
+ return ssl.create_default_context(cafile=verify_ssl) if isinstance(verify_ssl, str) else verify_ssl
99
+
95
100
  def _build_api_url(self, api_url=None, api_port=None):
96
101
  """Build the API url based on the given url and port. Defaults to `https://api.domaintools.com`"""
97
102
  rest_api_url = "https://api.domaintools.com"
@@ -1187,3 +1192,65 @@ class API(object):
1187
1192
  cls=FeedsResults,
1188
1193
  **kwargs,
1189
1194
  )
1195
+
1196
+ def realtime_domain_risk(self, **kwargs) -> FeedsResults:
1197
+ """Returns back list of the realtime domain risk feed.
1198
+ Contains realtime domain risk information for apex-level domains, regardless of observed traffic.
1199
+
1200
+ 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
1201
+
1202
+ before: str: Filter for records before the given time value inclusive or time offset relative to now
1203
+
1204
+ after: str: Filter for records after the given time value inclusive or time offset relative to now
1205
+
1206
+ headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
1207
+
1208
+ sessionID: str: A custom string to distinguish between different sessions
1209
+
1210
+ top: int: Limit the number of results to the top N, where N is the value of this parameter.
1211
+ """
1212
+ validate_feeds_parameters(kwargs)
1213
+ endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1214
+ source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
1215
+ if endpoint == Endpoint.DOWNLOAD.value or kwargs.get("output_format", OutputFormat.JSONL.value) != OutputFormat.CSV.value:
1216
+ # headers param is allowed only in Feed API and CSV format
1217
+ kwargs.pop("headers", None)
1218
+
1219
+ return self._results(
1220
+ f"domain-risk-({source})",
1221
+ f"v1/{endpoint}/domainrisk/",
1222
+ response_path=(),
1223
+ cls=FeedsResults,
1224
+ **kwargs,
1225
+ )
1226
+
1227
+ def domainhotlist(self, **kwargs) -> FeedsResults:
1228
+ """Returns back list of domain hotlist feed.
1229
+ Contains high-risk, apex-level domains that are observed by DomainTools' global sensor network to be active within 24 hours.
1230
+
1231
+ 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
1232
+
1233
+ before: str: Filter for records before the given time value inclusive or time offset relative to now
1234
+
1235
+ after: str: Filter for records after the given time value inclusive or time offset relative to now
1236
+
1237
+ headers: bool: Use in combination with Accept: text/csv headers to control if headers are sent or not
1238
+
1239
+ sessionID: str: A custom string to distinguish between different sessions
1240
+
1241
+ top: int: Limit the number of results to the top N, where N is the value of this parameter.
1242
+ """
1243
+ validate_feeds_parameters(kwargs)
1244
+ endpoint = kwargs.pop("endpoint", Endpoint.FEED.value)
1245
+ source = ENDPOINT_TO_SOURCE_MAP.get(endpoint).value
1246
+ if endpoint == Endpoint.DOWNLOAD.value or kwargs.get("output_format", OutputFormat.JSONL.value) != OutputFormat.CSV.value:
1247
+ # headers param is allowed only in Feed API and CSV format
1248
+ kwargs.pop("headers", None)
1249
+
1250
+ return self._results(
1251
+ f"domain-hotlist-feed-({source})",
1252
+ f"v1/{endpoint}/domainhotlist/",
1253
+ response_path=(),
1254
+ cls=FeedsResults,
1255
+ **kwargs,
1256
+ )
@@ -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)
@@ -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"
@@ -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
 
@@ -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
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: DomainTools Official Python API
5
5
  Author-email: DomainTools <integrations@domaintools.com>
6
6
  License: The MIT License (MIT)
@@ -321,3 +321,43 @@ results = api.nod(sessionID="my-session-id", after=-7200)
321
321
  for partial_result in results.response() # generator that holds NOD feeds data for the past 2 hours and is expected to request multiple times
322
322
  # do things to partial_result
323
323
  ```
324
+
325
+
326
+ Running E2E Tests Locally
327
+ ===================
328
+ For now, e2e tests only covers proxy and ssl testing. We are expected to broaden our e2e tests to other scenarios moving forward.
329
+ To add more e2e tests, put these in the `../tests/e2e` folder.
330
+
331
+ ## Preparation
332
+ - Create virtual environment.
333
+ ```bash
334
+ python3 -m venv venv
335
+ ```
336
+
337
+ - Activate virtual environment
338
+ ```bash
339
+ source venv/bin/activate
340
+ ```
341
+
342
+ - Install dependencies.
343
+ ```bash
344
+ pip install -r requirements/development.txt
345
+ ```
346
+
347
+ - From the python_api project root directory, install the package.
348
+ ```bash
349
+ pip install -e .
350
+ ```
351
+
352
+ - Export api credentials to use.
353
+ ```bash
354
+ export TEST_USER=<user-key>
355
+ export TEST_KEY=<api-key>
356
+ ```
357
+
358
+ ## Run the end-to-end test script
359
+ - Before running the test, be sure that docker is running.
360
+ - Execute the e2e test script .
361
+ ```bash
362
+ sh tests/e2e/scripts/test_e2e_runner.sh
363
+ ```
@@ -342,11 +342,20 @@ def test_exception_handling():
342
342
  API("notauser", "notakey").domain_search("amazon").data()
343
343
  with pytest.raises(
344
344
  ValueError,
345
- match=r"Invalid value 'notahash' for 'key_sign_hash'. Values available are sha1,sha256,md5",
345
+ match=r"Invalid value 'notahash' for 'key_sign_hash'. Values available are sha1,sha256",
346
346
  ):
347
347
  API("notauser", "notakey", always_sign_api_key=True, key_sign_hash="notahash").domain_search("amazon")
348
348
 
349
349
 
350
+ @vcr.use_cassette
351
+ def test_md5_is_not_supported():
352
+ with pytest.raises(
353
+ ValueError,
354
+ match=r"Invalid value 'md5' for 'key_sign_hash'. Values available are sha1,sha256",
355
+ ):
356
+ API("notauser", "notakey", always_sign_api_key=True, key_sign_hash="md5").domain_search("amazon")
357
+
358
+
350
359
  @vcr.use_cassette
351
360
  def test_rate_limiting():
352
361
  domain_searches = ["google"] * 31
@@ -377,6 +386,7 @@ def test_formats():
377
386
 
378
387
 
379
388
  @vcr.use_cassette
389
+ @pytest.mark.skip(reason="Iris endpoint is already deprecated in light of enrich and investigate")
380
390
  def test_iris():
381
391
  with pytest.raises(ValueError):
382
392
  api.iris()
@@ -663,3 +673,43 @@ def test_feeds_endpoint_should_raise_error_if_asked_csv_format_for_download_api(
663
673
  feeds_api.domaindiscovery(after="-60", output_format="csv", endpoint="download")
664
674
 
665
675
  assert str(excinfo.value) == "csv format is not available in download API."
676
+
677
+
678
+ @vcr.use_cassette
679
+ def test_realtime_domain_risk():
680
+ results = feeds_api.realtime_domain_risk(after="-60", header_authentication=False)
681
+ for response in results.response():
682
+ assert results.status == 200
683
+
684
+ rows = response.strip().split("\n")
685
+ assert response is not None
686
+ assert len(rows) >= 1
687
+
688
+ for row in rows:
689
+ feed_result = json.loads(row)
690
+ assert "timestamp" in feed_result.keys()
691
+ assert "domain" in feed_result.keys()
692
+ assert "phishing_risk" in feed_result.keys()
693
+ assert "malware_risk" in feed_result.keys()
694
+ assert "proximity_risk" in feed_result.keys()
695
+ assert "overall_risk" in feed_result.keys()
696
+
697
+
698
+ @vcr.use_cassette
699
+ def test_domain_hotlist():
700
+ results = feeds_api.domainhotlist(after="-60", header_authentication=False)
701
+ for response in results.response():
702
+ assert results.status == 200
703
+
704
+ rows = response.strip().split("\n")
705
+ assert response is not None
706
+ assert len(rows) >= 1
707
+
708
+ for row in rows:
709
+ feed_result = json.loads(row)
710
+ assert "timestamp" in feed_result.keys()
711
+ assert "domain" in feed_result.keys()
712
+ assert "phishing_risk" in feed_result.keys()
713
+ assert "malware_risk" in feed_result.keys()
714
+ assert "proximity_risk" in feed_result.keys()
715
+ assert "overall_risk" in feed_result.keys()
@@ -1 +0,0 @@
1
- 2.4.0
File without changes