greynoise 3.0.3__tar.gz → 3.2.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.
- {greynoise-3.0.3 → greynoise-3.2.0}/.bumpversion.cfg +3 -3
- {greynoise-3.0.3 → greynoise-3.2.0}/.circleci/config.yml +1 -1
- {greynoise-3.0.3 → greynoise-3.2.0}/.gitignore +3 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.pre-commit-config.yaml +1 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/CHANGELOG.rst +73 -1
- {greynoise-3.0.3 → greynoise-3.2.0}/PKG-INFO +25 -13
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/conf.py +2 -2
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/sample.py +1 -3
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/tutorial.rst +145 -28
- {greynoise-3.0.3 → greynoise-3.2.0}/pyproject.toml +29 -13
- greynoise-3.2.0/requirements/common.txt +24 -0
- greynoise-3.2.0/requirements/dev.txt +11 -0
- greynoise-3.2.0/requirements/docs.txt +12 -0
- greynoise-3.2.0/requirements/test.txt +25 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/reset_changelog.py +3 -4
- {greynoise-3.0.3 → greynoise-3.2.0}/setup.cfg +3 -3
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/__init__.py +6 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/__version__.py +1 -1
- greynoise-3.2.0/src/greynoise/api/__init__.py +2174 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/api/filter.py +6 -12
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/__init__.py +8 -1
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/decorator.py +52 -88
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/formatter.py +85 -35
- greynoise-3.2.0/src/greynoise/cli/subcommand.py +806 -0
- greynoise-3.2.0/src/greynoise/cli/templates/callback_ip.txt.j2 +73 -0
- greynoise-3.2.0/src/greynoise/cli/templates/feeds_consumers.txt.j2 +40 -0
- greynoise-3.2.0/src/greynoise/cli/templates/feeds_events.txt.j2 +78 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_context_result.txt.j2 +24 -2
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/macros.txt.j2 +11 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/personadetails.txt.j2 +3 -1
- greynoise-3.2.0/src/greynoise/cli/templates/recall_stats.txt.j2 +63 -0
- greynoise-3.2.0/src/greynoise/cli/templates/recall_timeseries.txt.j2 +38 -0
- greynoise-3.2.0/src/greynoise/cli/templates/timelinedaily.txt.j2 +23 -0
- greynoise-3.2.0/src/greynoise/exceptions.py +53 -0
- greynoise-3.2.0/src/greynoise/greynoise_timeline.py +527 -0
- greynoise-3.2.0/src/greynoise/psychic.py +1257 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/util.py +207 -31
- {greynoise-3.0.3 → greynoise-3.2.0}/tests/cli/test_formatter.py +138 -140
- {greynoise-3.0.3 → greynoise-3.2.0}/tests/cli/test_subcommand.py +435 -331
- greynoise-3.2.0/tests/test_api.py +1834 -0
- greynoise-3.2.0/tests/test_exceptions.py +63 -0
- greynoise-3.2.0/tests/test_greynoise_timeline.py +75 -0
- greynoise-3.2.0/tests/test_psychic.py +589 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/tests/test_util.py +191 -40
- greynoise-3.0.3/requirements/common.txt +0 -11
- greynoise-3.0.3/requirements/dev.txt +0 -5
- greynoise-3.0.3/requirements/docs.txt +0 -5
- greynoise-3.0.3/requirements/test.txt +0 -16
- greynoise-3.0.3/src/greynoise/api/__init__.py +0 -1124
- greynoise-3.0.3/src/greynoise/cli/subcommand.py +0 -505
- greynoise-3.0.3/src/greynoise/cli/templates/ip_community.txt.j2 +0 -16
- greynoise-3.0.3/src/greynoise/cli/templates/riot.txt.j2 +0 -32
- greynoise-3.0.3/src/greynoise/cli/templates/sensoractivity.txt.j2 +0 -25
- greynoise-3.0.3/src/greynoise/cli/templates/similarity.txt.j2 +0 -28
- greynoise-3.0.3/src/greynoise/cli/templates/timelinehourly.txt.j2 +0 -26
- greynoise-3.0.3/src/greynoise/exceptions.py +0 -13
- greynoise-3.0.3/tests/test_api.py +0 -1228
- {greynoise-3.0.3 → greynoise-3.2.0}/.dockerignore +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.editorconfig +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.github/CODEOWNERS +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.github/dependabot.yml +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.github/workflows/slack_release_notice.yml +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.readthedocs.yml +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/.yamllint +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/Dockerfile +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/LICENSE +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/MANIFEST.in +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/Makefile +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/README.rst +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/Makefile +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/changelog.rst +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/index.rst +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/introduction.rst +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/docs/source/reference.rst +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/pytest.ini +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/release.md +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/sonar-project.properties +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/helper.py +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/parameter.py +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/analyze.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/cvedetails.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/gnql_query.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/gnql_stats.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_context.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_multi_context.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_quick_check.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/sensorlist.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/stats.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/src/greynoise/cli/templates/timeline.txt.j2 +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/tests/cli/test_init.py +0 -0
- {greynoise-3.0.3 → greynoise-3.2.0}/tox.ini +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[bumpversion]
|
|
2
|
-
current_version = 3.0
|
|
2
|
+
current_version = 3.2.0
|
|
3
3
|
tag = False
|
|
4
4
|
commit = False
|
|
5
5
|
|
|
6
6
|
[bumpversion:file:pyproject.toml]
|
|
7
|
-
search = version="{current_version}"
|
|
8
|
-
replace = version="{new_version}"
|
|
7
|
+
search = version = "{current_version}"
|
|
8
|
+
replace = version = "{new_version}"
|
|
9
9
|
|
|
10
10
|
[bumpversion:file:src/greynoise/__version__.py]
|
|
11
11
|
search = __version__ = "{current_version}"
|
|
@@ -68,7 +68,7 @@ jobs:
|
|
|
68
68
|
command: yamllint .
|
|
69
69
|
- run:
|
|
70
70
|
name: Style check (black)
|
|
71
|
-
command: black --check src tests docs
|
|
71
|
+
command: black --check --target-version py310 src tests docs
|
|
72
72
|
- run:
|
|
73
73
|
name: Style check (isort)
|
|
74
74
|
command: isort --check-only src/**/*.py tests/**/*.py docs/**/*.py
|
|
@@ -2,6 +2,76 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version `3.2.0`_
|
|
6
|
+
================
|
|
7
|
+
**Date**: November 4, 2026
|
|
8
|
+
|
|
9
|
+
* API client:
|
|
10
|
+
|
|
11
|
+
* Corrected proxy settings for Psychic downloads/generation and IP Timeline
|
|
12
|
+
* Psychic downloads and daily timeline lookups use the configured API server
|
|
13
|
+
* `RateLimitError` now includes the API's 429 explanation, and the CLI prints it
|
|
14
|
+
* Added Event Feed search, pull (fetch and optional acknowledge), and consumer management
|
|
15
|
+
* `ip`, `quick`, and `ip_multi` send `workspace_labels`, defaulting to `greynoise,community`
|
|
16
|
+
* Added `callback_file` and `gnql_file` functions to download the pre-built callback and GNQL SIEM files
|
|
17
|
+
* Added `callback_file_metadata` and `gnql_file_metadata` functions to describe the pre-built files without downloading them
|
|
18
|
+
|
|
19
|
+
* CLI:
|
|
20
|
+
|
|
21
|
+
* `feeds search` searches retained feed history without moving a consumer checkpoint
|
|
22
|
+
* `feeds pull` fetches the next batch for a feed consumer and can acknowledge that batch
|
|
23
|
+
* `feeds consumers` lists consumers, or creates, resets, or deletes one checkpoint
|
|
24
|
+
* `ip`, `quick`, and `ip-multi` accept `--workspace-labels` and pass the value through to the API
|
|
25
|
+
* IP text output lists the `source_workspaces` returned for the scopes that were queried
|
|
26
|
+
* `ip --psychic --days` looks up an IP in a Psychic bitmap covering the last N days
|
|
27
|
+
* Psychic text output shows the bitmap date, and says when the IP was not in that file
|
|
28
|
+
* `psychic-download` and `psychic-generate` accept any model number and warn when it is not 1, 2, or 3
|
|
29
|
+
|
|
30
|
+
* Dependencies:
|
|
31
|
+
|
|
32
|
+
* Runtime dependencies now declare a minimum version instead of an exact pin, so applications can install a newer compatible release
|
|
33
|
+
* Updated `Click` to 8.5.0 on Python 3.10 and newer
|
|
34
|
+
* Updated `click-repl` to 0.4.1 on Python 3.9 and newer
|
|
35
|
+
* Updated `cachetools` to 7.2.8 on Python 3.10 and newer
|
|
36
|
+
* Updated `maxminddb` to 3.2.0 on Python 3.10 and newer
|
|
37
|
+
* Updated `more-itertools` to 11.2.1 on Python 3.11 and newer
|
|
38
|
+
|
|
39
|
+
Version `3.1.0`_
|
|
40
|
+
================
|
|
41
|
+
**Date**: July 9, 2026
|
|
42
|
+
|
|
43
|
+
* API client:
|
|
44
|
+
|
|
45
|
+
* Added `psychic_lookup`, `psychic_lookup_ips`, `psychic_stats` functions to support Psychic API endpoints
|
|
46
|
+
* Added `psychic_download_mmdb`, `psychic_download_bin`, `psychic_download_csv`, `psychic_generate_bitmap` functions to support Psychic file downloads
|
|
47
|
+
* Added `cves` function to support bulk CVE lookup API endpoints
|
|
48
|
+
* Added `callback_ip`, `callback_list`, `callback_export_ips`, `callback_overview` functions to support Callback API endpoints
|
|
49
|
+
* Added `recall`, `recall_stats`, `recall_timeseries` functions to support Recall API endpoints
|
|
50
|
+
* Updated the `timeline` and `timelinehourly` function
|
|
51
|
+
* Updated the `filter` function to correctly handle v3 API response format
|
|
52
|
+
* The `tags` function is now used instead of `metadata`, but is still available for backwards compatibility.
|
|
53
|
+
* The `similar` function is deprecated and will be removed in a future version.
|
|
54
|
+
* The `sensor_activity` and `sensor_activity_ips` functions are deprecated and will be removed in a future version.
|
|
55
|
+
* The `timelinehourly` function is deprecated and will be removed in a future version.
|
|
56
|
+
|
|
57
|
+
* CLI:
|
|
58
|
+
* Added `psychic-download` and `psychic-generate` commands to support Psychic file downloads
|
|
59
|
+
* Updated `ip` command to support Psychic API endpoints with new `-p/--psychic` option
|
|
60
|
+
* Added `callback` commands to support Callback API endpoints
|
|
61
|
+
* Added `recall` commands to support Recall API endpoints
|
|
62
|
+
* Removed `sensor-activity` command as it is deprecated and will be removed in a future version.
|
|
63
|
+
* Removed `timelinehourly` command as it is deprecated and will be removed in a future version.
|
|
64
|
+
* Removed not implemented commands `alerts`, `account`, `feedback`, `signature`, `interesting`.
|
|
65
|
+
|
|
66
|
+
* Dependencies:
|
|
67
|
+
* Updated `requests` to version 2.34.2
|
|
68
|
+
* Updated `more-itertools` to version 11.1.0
|
|
69
|
+
* Updated `cachetools` to version 7.0.5
|
|
70
|
+
* Updated `Click` to version 8.3.1
|
|
71
|
+
* Updated `ansimarkup` to version 2.2.0
|
|
72
|
+
* Updated `dict2xml` to version 1.7.8
|
|
73
|
+
* Added `maxminddb` to version 3.1.1
|
|
74
|
+
|
|
5
75
|
Version `3.0.3`_
|
|
6
76
|
================
|
|
7
77
|
**Date**: May 15, 2026
|
|
@@ -492,4 +562,6 @@ Version `0.2.0`_
|
|
|
492
562
|
.. _`3.0.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.3.0...v3.0.0
|
|
493
563
|
.. _`3.0.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.0...v3.0.1
|
|
494
564
|
.. _`3.0.2`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.1...v3.0.2
|
|
495
|
-
.. _`3.0.3`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.2...
|
|
565
|
+
.. _`3.0.3`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.2...v3.0.3
|
|
566
|
+
.. _`3.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.3...v3.1.0
|
|
567
|
+
.. _`3.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.1.0...3.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: greynoise
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Abstraction to interact with GreyNoise API.
|
|
5
5
|
Project-URL: Homepage, https://greynoise.io/
|
|
6
6
|
Project-URL: Repository, https://github.com/GreyNoise-Intelligence/pygreynoise
|
|
@@ -22,17 +22,29 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries
|
|
24
24
|
Requires-Python: >=3.8
|
|
25
|
-
Requires-Dist: ansimarkup
|
|
26
|
-
Requires-Dist: cachetools
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: click
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
25
|
+
Requires-Dist: ansimarkup>=2.2.0
|
|
26
|
+
Requires-Dist: cachetools>=5.5.2; python_version == '3.8'
|
|
27
|
+
Requires-Dist: cachetools>=6.2.6; python_version == '3.9'
|
|
28
|
+
Requires-Dist: cachetools>=7.2.8; python_version >= '3.10'
|
|
29
|
+
Requires-Dist: click-default-group>=1.2.4
|
|
30
|
+
Requires-Dist: click-repl>=0.3.0; python_version == '3.8'
|
|
31
|
+
Requires-Dist: click-repl>=0.4.1; python_version >= '3.9'
|
|
32
|
+
Requires-Dist: click<8.2,>=8.1.8; python_version < '3.10'
|
|
33
|
+
Requires-Dist: click>=8.5.0; python_version >= '3.10'
|
|
34
|
+
Requires-Dist: colorama>=0.4.6
|
|
35
|
+
Requires-Dist: dict2xml>=1.7.8
|
|
36
|
+
Requires-Dist: jinja2>=3.1.6
|
|
37
|
+
Requires-Dist: maxminddb>=2.6.3; python_version == '3.8'
|
|
38
|
+
Requires-Dist: maxminddb>=2.8.2; python_version == '3.9'
|
|
39
|
+
Requires-Dist: maxminddb>=3.2.0; python_version >= '3.10'
|
|
40
|
+
Requires-Dist: more-itertools>=10.5.0; python_version == '3.8'
|
|
41
|
+
Requires-Dist: more-itertools>=10.8.0; python_version == '3.9'
|
|
42
|
+
Requires-Dist: more-itertools>=11.1.0; python_version == '3.10'
|
|
43
|
+
Requires-Dist: more-itertools>=11.2.1; python_version >= '3.11'
|
|
44
|
+
Requires-Dist: requests>=2.32.4; python_version == '3.8'
|
|
45
|
+
Requires-Dist: requests>=2.32.5; python_version == '3.9'
|
|
46
|
+
Requires-Dist: requests>=2.34.2; python_version >= '3.10'
|
|
47
|
+
Requires-Dist: six>=1.17.0
|
|
36
48
|
Description-Content-Type: text/x-rst
|
|
37
49
|
|
|
38
50
|
================
|
|
@@ -21,11 +21,11 @@ sys.path.insert(0, os.path.abspath("."))
|
|
|
21
21
|
# -- Project information -----------------------------------------------------
|
|
22
22
|
|
|
23
23
|
project = "greynoise"
|
|
24
|
-
copyright = "2018-
|
|
24
|
+
copyright = "2018-2026, GreyNoise Intelligence"
|
|
25
25
|
author = "GreyNoise Intelligence"
|
|
26
26
|
|
|
27
27
|
# The full version, including alpha/beta/rc tags
|
|
28
|
-
release = "3.0
|
|
28
|
+
release = "3.2.0"
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
# -- General configuration ---------------------------------------------------
|
|
@@ -2,9 +2,7 @@ from greynoise.api import APIConfig, GreyNoise
|
|
|
2
2
|
|
|
3
3
|
api_key = "<enter-api-key-here>"
|
|
4
4
|
ip_addresses = ["108.168.3.151", "8.8.8.8", "318.1.1.1"]
|
|
5
|
-
api_config = APIConfig(
|
|
6
|
-
api_key=api_key, integration_name="greynoise-sampleapp-v1.0.0-beta"
|
|
7
|
-
)
|
|
5
|
+
api_config = APIConfig(api_key=api_key, integration_name="greynoise-sampleapp-v1.0.0-beta")
|
|
8
6
|
api_client = GreyNoise(api_config)
|
|
9
7
|
|
|
10
8
|
for ip_address in ip_addresses:
|
|
@@ -408,6 +408,21 @@ this (this method also supports the include_invalid flag::
|
|
|
408
408
|
}
|
|
409
409
|
]
|
|
410
410
|
|
|
411
|
+
Dataset scopes
|
|
412
|
+
--------------
|
|
413
|
+
|
|
414
|
+
``ip``, ``quick``, and ``ip_multi`` send a ``workspace_labels`` query parameter.
|
|
415
|
+
When the argument is omitted, the client sends ``greynoise,community``. Pass a
|
|
416
|
+
comma-separated string to choose a different set. The values are forwarded as
|
|
417
|
+
given; the API accepts ``greynoise``, ``community``, and ``personal``::
|
|
418
|
+
|
|
419
|
+
>>> api_client.ip('8.8.8.8', workspace_labels='greynoise')
|
|
420
|
+
|
|
421
|
+
``quick`` and ``ip_multi`` take the same argument. A response includes
|
|
422
|
+
``internet_scanner_intelligence.source_workspaces`` for the scopes that contained
|
|
423
|
+
the IP. Successful lookups are cached by IP address and label set, so a later
|
|
424
|
+
call with a different set is not served from the earlier result.
|
|
425
|
+
|
|
411
426
|
Any IP can also be checked to see if there are any Similar IPs in the Noise Dataset::
|
|
412
427
|
|
|
413
428
|
>>> api_client.similar('45.83.66.65')
|
|
@@ -469,8 +484,10 @@ Run a query
|
|
|
469
484
|
~~~~~~~~~~~
|
|
470
485
|
|
|
471
486
|
A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise
|
|
472
|
-
dataset.
|
|
473
|
-
|
|
487
|
+
dataset. Pass ``exclude_fields`` as a comma-separated string or a list of field names
|
|
488
|
+
to omit those fields from the response (the API ``exclude`` parameter). For example, to
|
|
489
|
+
get context information related to activity that has been classified as malicious and
|
|
490
|
+
tagged as a Bluekeep Exploit::
|
|
474
491
|
|
|
475
492
|
>>> api_client.query('last_seen:1d classification:"suspicious" actor:"NiceCrawler"')
|
|
476
493
|
{
|
|
@@ -741,6 +758,60 @@ operating system, etc.::
|
|
|
741
758
|
}
|
|
742
759
|
}
|
|
743
760
|
|
|
761
|
+
Event feeds
|
|
762
|
+
-----------
|
|
763
|
+
|
|
764
|
+
Retained feed events can be searched without moving a consumer checkpoint. Feeds are
|
|
765
|
+
created in the GreyNoise Visualizer. An empty search covers enabled non-session feeds
|
|
766
|
+
over the previous hour. ``event_types`` is limited to ``ip-classification-change``,
|
|
767
|
+
``cve-status-change``, ``cve-activity-spike``, ``vendor-cve-spike``, ``tag-spike``,
|
|
768
|
+
``new-callback-ip``, ``new-callback-file``, and ``credential-observed``::
|
|
769
|
+
|
|
770
|
+
>>> api_client.feed_search(event_types=['tag-spike'], ip='8.8.8.8', from_time='24h', limit=100)
|
|
771
|
+
|
|
772
|
+
Pass the returned ``cursor`` by itself, with an optional ``limit``, to read the next page.
|
|
773
|
+
``feed_pull`` reads the next batch for one consumer and does not advance that checkpoint
|
|
774
|
+
unless ``ack=True``. ``cursor`` acknowledges a batch that was already fetched::
|
|
775
|
+
|
|
776
|
+
>>> api_client.feed_pull('<feed_uuid>', consumer='worker-1', limit=100, ack=True)
|
|
777
|
+
|
|
778
|
+
``feed_consumers`` lists checkpoints, or creates, resets, or deletes one. A new consumer
|
|
779
|
+
starts at the beginning of retained history. Reset replays that history. Delete removes
|
|
780
|
+
only that checkpoint::
|
|
781
|
+
|
|
782
|
+
>>> api_client.feed_consumers('<feed_uuid>', action='create', consumer='worker-1')
|
|
783
|
+
|
|
784
|
+
These methods are not available with the community offering.
|
|
785
|
+
|
|
786
|
+
Pre-built files
|
|
787
|
+
---------------
|
|
788
|
+
|
|
789
|
+
GreyNoise builds SIEM lookup files server-side and refreshes them hourly. Both downloads
|
|
790
|
+
request the only file the API serves (CSV, NG-SIEM profile), stream the body to a path or
|
|
791
|
+
a binary file object, and return a ``FileResult``. A path is written to a temporary file
|
|
792
|
+
and moved into place only when the status is ``ok``, so a failed download leaves an
|
|
793
|
+
existing file in place.
|
|
794
|
+
|
|
795
|
+
``callback_file`` downloads the callback IP file. ``days`` is the lookback window, from
|
|
796
|
+
1 to 7, and defaults to 7. Callback files do not report ``truncated``::
|
|
797
|
+
|
|
798
|
+
>>> api_client.callback_file('callback.csv', days=7)
|
|
799
|
+
FileResult(status='ok', generated_at='2026-10-29T10:00:00Z', row_count=100000, total_count=None, truncated=None, feed_status=None, retry_after=None)
|
|
800
|
+
|
|
801
|
+
``gnql_file`` downloads the file for a GNQL query::
|
|
802
|
+
|
|
803
|
+
>>> api_client.gnql_file('last_seen:1d -classification:unknown', 'feed.csv', limit=100000)
|
|
804
|
+
FileResult(status='ok', generated_at='2026-10-29T10:00:00Z', row_count=100000, total_count=250000, truncated=True, feed_status='enabled', retry_after=None)
|
|
805
|
+
|
|
806
|
+
The first request for a new query subscribes to it and returns status ``provisioning``
|
|
807
|
+
until the file is built. Nothing is written in that case; retry after
|
|
808
|
+
``result.retry_after`` seconds. Integrations should identify themselves with
|
|
809
|
+
``integration='name/version'``, which is sent as ``X-GreyNoise-Integration``.
|
|
810
|
+
``callback_file_metadata`` and ``gnql_file_metadata`` take the same arguments as the
|
|
811
|
+
download functions (without ``output``) and return the same fields without downloading
|
|
812
|
+
the file. Error responses raise ``RequestFailure`` (``RateLimitError`` for HTTP 429)
|
|
813
|
+
with the status code and the API's explanation.
|
|
814
|
+
|
|
744
815
|
|
|
745
816
|
Command line interface
|
|
746
817
|
======================
|
|
@@ -752,36 +823,33 @@ subcommands, use the *--help* option::
|
|
|
752
823
|
$ greynoise -h
|
|
753
824
|
Usage: greynoise [OPTIONS] COMMAND [ARGS]...
|
|
754
825
|
|
|
755
|
-
|
|
826
|
+
GreyNoise CLI.
|
|
756
827
|
|
|
757
828
|
Options:
|
|
758
829
|
-h, --help Show this message and exit.
|
|
759
830
|
|
|
760
831
|
Commands:
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
ip
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
sensor-list
|
|
777
|
-
setup
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
timelinedaily Query GreyNoise IP Timeline to get daily event details.
|
|
783
|
-
timelinehourly Query GreyNoise IP Timeline to get hourly event details.
|
|
784
|
-
version Get version and OS information for your GreyNoise...
|
|
832
|
+
analyze Analyze the IP addresses in a log file, stdin, etc.
|
|
833
|
+
callback GreyNoise Callback — scanner callback intelligence...
|
|
834
|
+
cve Retrieve Details of a CVE.
|
|
835
|
+
feeds Search retained feed events, pull a batch, or manage...
|
|
836
|
+
filter Filter the noise from a log file, stdin, etc.
|
|
837
|
+
help Show this message and exit.
|
|
838
|
+
ip Query GreyNoise for all information on a given IP.
|
|
839
|
+
ip-multi Perform Context lookup for multiple IPs at once.
|
|
840
|
+
persona-details Retrieve Details of a Sensor Persona.
|
|
841
|
+
psychic-download Download a Psychic bitmap (.bin), MMDB, or CSV file...
|
|
842
|
+
psychic-generate Generate a Psychic bitmap (.bin) for a date range...
|
|
843
|
+
query Run a GNQL (GreyNoise Query Language) query.
|
|
844
|
+
quick Quickly check whether or not one or many IPs are...
|
|
845
|
+
recall GreyNoise Recall — GNQL activity over time.
|
|
846
|
+
repl Start an interactive shell.
|
|
847
|
+
sensor-list Retrieve list of current Sensors in Workspace.
|
|
848
|
+
setup Configure API client.
|
|
849
|
+
stats Get aggregate stats from a given GNQL query.
|
|
850
|
+
timeline Query GreyNoise IP Timeline for events based on a...
|
|
851
|
+
timelinedaily Query GreyNoise IP Timeline to get daily event details.
|
|
852
|
+
version Get version and OS information for your GreyNoise...
|
|
785
853
|
|
|
786
854
|
|
|
787
855
|
Setup
|
|
@@ -942,6 +1010,19 @@ this (a comma separated list is also supported::
|
|
|
942
1010
|
Last Updated: 2025-05-23T13:11:02Z
|
|
943
1011
|
Reference: https://developers.google.com/speed/public-dns/docs/isp#alternative
|
|
944
1012
|
|
|
1013
|
+
``ip``, ``quick``, and ``ip-multi`` accept ``--workspace-labels``. The default is
|
|
1014
|
+
``greynoise,community``. The value is sent unchanged, and text output lists the
|
|
1015
|
+
``source_workspaces`` the API returned::
|
|
1016
|
+
|
|
1017
|
+
$ greynoise ip 8.8.8.8 --workspace-labels greynoise
|
|
1018
|
+
|
|
1019
|
+
``ip --psychic`` looks the address up in a Psychic bitmap instead of calling the IP
|
|
1020
|
+
lookup API. ``--days`` builds that bitmap for the last N days through today and
|
|
1021
|
+
requires ``--psychic``. Text output shows the bitmap date, and says when the IP was
|
|
1022
|
+
not in that file. ``--workspace-labels`` is not applied to a Psychic lookup::
|
|
1023
|
+
|
|
1024
|
+
$ greynoise ip 1.2.3.4 --psychic --days 7
|
|
1025
|
+
|
|
945
1026
|
Check for Similar IPs to a given IP::
|
|
946
1027
|
|
|
947
1028
|
$ greynoise similar 69.160.160.55
|
|
@@ -1008,6 +1089,40 @@ Check the Timeline of a given IP::
|
|
|
1008
1089
|
2025-05-11 1 suspicious
|
|
1009
1090
|
2025-04-27 1 suspicious
|
|
1010
1091
|
|
|
1092
|
+
Event feeds
|
|
1093
|
+
-----------
|
|
1094
|
+
|
|
1095
|
+
``feeds search`` reads retained history and does not move a consumer checkpoint.
|
|
1096
|
+
Repeat ``--feed-id`` and ``--event-type`` to pass more than one value. ``--from``
|
|
1097
|
+
accepts a relative window such as ``24h`` or ``7d``, a UTC date, or an RFC3339
|
|
1098
|
+
timestamp. ``--cursor`` continues a previous page and cannot be combined with
|
|
1099
|
+
other filters::
|
|
1100
|
+
|
|
1101
|
+
$ greynoise feeds search --event-type tag-spike --ip 8.8.8.8 --from 24h --limit 100
|
|
1102
|
+
|
|
1103
|
+
``feeds pull`` fetches the next batch for one consumer. The checkpoint stays put
|
|
1104
|
+
unless ``--ack`` is set. Text output for a pull without ``--ack`` shows the first
|
|
1105
|
+
25 events (100 with ``-v``). An acknowledged pull prints the full batch and states
|
|
1106
|
+
that the checkpoint advanced past every event in it. ``--cursor`` acknowledges a
|
|
1107
|
+
previously fetched batch without fetching again::
|
|
1108
|
+
|
|
1109
|
+
$ greynoise feeds pull <feed_uuid> --consumer worker-1 --limit 100 --ack
|
|
1110
|
+
|
|
1111
|
+
``feeds consumers`` lists checkpoints for a feed. ``--action create`` starts a
|
|
1112
|
+
consumer at the beginning of retained history, ``reset`` replays that history,
|
|
1113
|
+
and ``delete`` removes one checkpoint::
|
|
1114
|
+
|
|
1115
|
+
$ greynoise feeds consumers <feed_uuid> --action create --consumer worker-1
|
|
1116
|
+
|
|
1117
|
+
Psychic files
|
|
1118
|
+
-------------
|
|
1119
|
+
|
|
1120
|
+
``psychic-download`` writes a bitmap (``.bin``), MMDB, or CSV for one date into
|
|
1121
|
+
the current directory. ``psychic-generate`` builds a bitmap for a date range::
|
|
1122
|
+
|
|
1123
|
+
$ greynoise psychic-download --format mmdb --date 2026-10-26
|
|
1124
|
+
$ greynoise psychic-generate --start-date 2026-10-20 --end-date 2026-10-26
|
|
1125
|
+
|
|
1011
1126
|
GNQL
|
|
1012
1127
|
----
|
|
1013
1128
|
|
|
@@ -1015,7 +1130,7 @@ Run a query
|
|
|
1015
1130
|
~~~~~~~~~~~
|
|
1016
1131
|
|
|
1017
1132
|
A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise
|
|
1018
|
-
dataset. For example, to get context information related to activity has been classified
|
|
1133
|
+
dataset. For example, to get context information related to activity that has been classified
|
|
1019
1134
|
as malicious and tagged as a Bluekeep Exploit::
|
|
1020
1135
|
|
|
1021
1136
|
$ greynoise query "classification:malicious tags:Bluekeep Exploit"
|
|
@@ -1073,6 +1188,8 @@ as malicious and tagged as a Bluekeep Exploit::
|
|
|
1073
1188
|
This is the default command, that is, you can save some typing by just
|
|
1074
1189
|
writing ``greynoise <query>`` instead of ``greynoise query <query>``.
|
|
1075
1190
|
|
|
1191
|
+
``--exclude`` is a comma-separated list of fields to omit from the results.
|
|
1192
|
+
|
|
1076
1193
|
|
|
1077
1194
|
Get statistics
|
|
1078
1195
|
~~~~~~~~~~~~~~
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "greynoise"
|
|
7
|
-
version = "3.0
|
|
7
|
+
version = "3.2.0"
|
|
8
8
|
description = "Abstraction to interact with GreyNoise API."
|
|
9
9
|
readme = {file = "README.rst", content-type = "text/x-rst"}
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -28,17 +28,29 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
keywords = ["internet", "scanning", "threat intelligence", "security"]
|
|
30
30
|
dependencies = [
|
|
31
|
-
"Click
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
31
|
+
"Click>=8.1.8,<8.2; python_version < '3.10'",
|
|
32
|
+
"Click>=8.5.0; python_version >= '3.10'",
|
|
33
|
+
"ansimarkup>=2.2.0",
|
|
34
|
+
"cachetools>=5.5.2; python_version == '3.8'",
|
|
35
|
+
"cachetools>=6.2.6; python_version == '3.9'",
|
|
36
|
+
"cachetools>=7.2.8; python_version >= '3.10'",
|
|
37
|
+
"colorama>=0.4.6",
|
|
38
|
+
"click-default-group>=1.2.4",
|
|
39
|
+
"click-repl>=0.3.0; python_version == '3.8'",
|
|
40
|
+
"click-repl>=0.4.1; python_version >= '3.9'",
|
|
41
|
+
"dict2xml>=1.7.8",
|
|
42
|
+
"jinja2>=3.1.6",
|
|
43
|
+
"maxminddb>=2.6.3; python_version == '3.8'",
|
|
44
|
+
"maxminddb>=2.8.2; python_version == '3.9'",
|
|
45
|
+
"maxminddb>=3.2.0; python_version >= '3.10'",
|
|
46
|
+
"more-itertools>=10.5.0; python_version == '3.8'",
|
|
47
|
+
"more-itertools>=10.8.0; python_version == '3.9'",
|
|
48
|
+
"more-itertools>=11.1.0; python_version == '3.10'",
|
|
49
|
+
"more-itertools>=11.2.1; python_version >= '3.11'",
|
|
50
|
+
"requests>=2.32.4; python_version == '3.8'",
|
|
51
|
+
"requests>=2.32.5; python_version == '3.9'",
|
|
52
|
+
"requests>=2.34.2; python_version >= '3.10'",
|
|
53
|
+
"six>=1.17.0",
|
|
42
54
|
]
|
|
43
55
|
|
|
44
56
|
[project.urls]
|
|
@@ -53,4 +65,8 @@ greynoise = "greynoise.cli:main"
|
|
|
53
65
|
packages = ["src/greynoise"]
|
|
54
66
|
|
|
55
67
|
[tool.hatch.build.targets.wheel.shared-data]
|
|
56
|
-
"src/greynoise/cli/templates/*.j2" = "greynoise/cli/templates"
|
|
68
|
+
"src/greynoise/cli/templates/*.j2" = "greynoise/cli/templates"
|
|
69
|
+
|
|
70
|
+
[tool.black]
|
|
71
|
+
line-length = 120
|
|
72
|
+
target-version = ["py310"]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Click<=8.1.8;python_version=="3.8"
|
|
2
|
+
Click<=8.1.8;python_version=="3.9"
|
|
3
|
+
Click==8.5.0;python_version>="3.10"
|
|
4
|
+
ansimarkup==2.2.0
|
|
5
|
+
cachetools==5.5.2;python_version=="3.8"
|
|
6
|
+
cachetools==6.2.6;python_version=="3.9"
|
|
7
|
+
cachetools==7.2.8;python_version>="3.10"
|
|
8
|
+
colorama==0.4.6
|
|
9
|
+
click-default-group==1.2.4
|
|
10
|
+
click-repl==0.3.0;python_version=="3.8"
|
|
11
|
+
click-repl==0.4.1;python_version>="3.9"
|
|
12
|
+
dict2xml==1.7.8
|
|
13
|
+
jinja2==3.1.6
|
|
14
|
+
maxminddb==2.6.3;python_version=="3.8"
|
|
15
|
+
maxminddb==2.8.2;python_version=="3.9"
|
|
16
|
+
maxminddb==3.2.0;python_version>="3.10"
|
|
17
|
+
more-itertools==10.5.0;python_version=="3.8"
|
|
18
|
+
more-itertools==10.8.0;python_version=="3.9"
|
|
19
|
+
more-itertools==11.1.0;python_version=="3.10"
|
|
20
|
+
more-itertools==11.2.1;python_version>="3.11"
|
|
21
|
+
requests==2.32.4;python_version=="3.8"
|
|
22
|
+
requests==2.32.5;python_version=="3.9"
|
|
23
|
+
requests==2.34.2;python_version>="3.10"
|
|
24
|
+
six==1.17.0
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Requirements needed to develop the application
|
|
2
|
+
-r test.txt
|
|
3
|
+
advbumpversion==1.2.0
|
|
4
|
+
ipython==8.12.3;python_version=="3.8"
|
|
5
|
+
ipython==8.18.1;python_version=="3.9"
|
|
6
|
+
ipython==8.39.0;python_version=="3.10"
|
|
7
|
+
ipython==9.17.1;python_version>="3.11"
|
|
8
|
+
tox==4.25.0;python_version=="3.8"
|
|
9
|
+
tox==4.30.3;python_version=="3.9"
|
|
10
|
+
tox==4.65.0;python_version=="3.10"
|
|
11
|
+
tox==4.67.1;python_version>="3.11"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Requirements needed to build the documentation
|
|
2
|
+
-r common.txt
|
|
3
|
+
Sphinx==7.1.2;python_version=="3.8"
|
|
4
|
+
Sphinx==7.4.7;python_version=="3.9"
|
|
5
|
+
Sphinx==8.1.3;python_version=="3.10"
|
|
6
|
+
Sphinx==9.0.4;python_version=="3.11"
|
|
7
|
+
Sphinx==9.1.1;python_version=="3.12"
|
|
8
|
+
Sphinx==9.2.0;python_version>="3.13"
|
|
9
|
+
sphinx-click==6.0.0;python_version=="3.8"
|
|
10
|
+
sphinx-click==6.0.0;python_version=="3.9"
|
|
11
|
+
sphinx-click==6.2.0;python_version>="3.10"
|
|
12
|
+
sphinx-rtd-theme==3.1.0
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
black==24.8.0;python_version=="3.8"
|
|
2
|
+
black==25.11.0;python_version=="3.9"
|
|
3
|
+
black==26.10.1;python_version>="3.10"
|
|
4
|
+
flake8==7.1.2;python_version=="3.8"
|
|
5
|
+
flake8==7.3.0;python_version=="3.9"
|
|
6
|
+
flake8==7.4.1;python_version>="3.10"
|
|
7
|
+
isort==5.13.2;python_version=="3.8"
|
|
8
|
+
isort==6.1.0;python_version=="3.9"
|
|
9
|
+
isort==9.0.2;python_version>="3.10"
|
|
10
|
+
mock==5.2.0
|
|
11
|
+
pylint==3.2.7;python_version=="3.8"
|
|
12
|
+
pylint==3.3.9;python_version=="3.9"
|
|
13
|
+
pylint==4.1.3;python_version>="3.10"
|
|
14
|
+
pytest-cov==5.0.0;python_version=="3.8"
|
|
15
|
+
pytest-cov==7.1.0;python_version>="3.9"
|
|
16
|
+
pytest==8.3.5;python_version=="3.8"
|
|
17
|
+
pytest==8.4.2;python_version=="3.9"
|
|
18
|
+
pytest==9.1.1;python_version>="3.10"
|
|
19
|
+
restructuredtext-lint==2.0.2
|
|
20
|
+
twine==6.1.0;python_version=="3.8"
|
|
21
|
+
twine==6.2.0;python_version=="3.9"
|
|
22
|
+
twine==7.0.0;python_version>="3.10"
|
|
23
|
+
yamllint==1.35.1;python_version=="3.8"
|
|
24
|
+
yamllint==1.37.1;python_version=="3.9"
|
|
25
|
+
yamllint==1.38.0;python_version>="3.10"
|
|
@@ -43,10 +43,9 @@ if not match:
|
|
|
43
43
|
)
|
|
44
44
|
f.seek(0)
|
|
45
45
|
f.write(text)
|
|
46
|
-
LINK_STRING = (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
).format(ver)
|
|
46
|
+
LINK_STRING = (".. _`dev`: https://github.com/GreyNoise-Intelligence/pygreynoise/" "compare/v{}...HEAD").format(
|
|
47
|
+
ver
|
|
48
|
+
)
|
|
50
49
|
f.write(LINK_STRING)
|
|
51
50
|
f.truncate()
|
|
52
51
|
else:
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[flake8]
|
|
2
|
-
max-line-length =
|
|
2
|
+
max-line-length = 120
|
|
3
3
|
max-complexity = 10
|
|
4
|
-
ignore = C901,W503
|
|
4
|
+
ignore = C901,W503,E203
|
|
5
5
|
|
|
6
6
|
[isort]
|
|
7
7
|
multi_line_output = 3
|
|
8
8
|
include_trailing_comma = True
|
|
9
9
|
use_parentheses = True
|
|
10
|
-
line_length =
|
|
10
|
+
line_length = 120
|
|
11
11
|
|
|
12
12
|
[tool:pytest]
|
|
13
13
|
addopts = --pdbcls=IPython.terminal.debugger:TerminalPdb
|
|
@@ -10,4 +10,10 @@ from greynoise.__version__ import ( # noqa
|
|
|
10
10
|
__status__,
|
|
11
11
|
__version__,
|
|
12
12
|
)
|
|
13
|
+
|
|
14
|
+
USER_AGENT = "GreyNoise/{}".format(__version__)
|
|
15
|
+
PSYCHIC_USER_AGENT = "{} (psychic)".format(USER_AGENT)
|
|
16
|
+
|
|
13
17
|
from greynoise.api import GreyNoise # noqa
|
|
18
|
+
from greynoise.greynoise_timeline import get_greynoise_timeline # noqa
|
|
19
|
+
from greynoise.psychic import Psychic # noqa
|