A simple client that allows idiomatic access to the Niddel Magnet v2 REST API. Uses the wonderful requests package to perform the requests.
Release history: https://github.com/Niddel/magnet-api2-sdk-python/releases
There are a couple of ways to let the Connection
object know which API key to use.
The simplest one is to pass one explicitly to its constructor:
from magnetsdk2 import Connection
conn = Connection(api_key="my secret API key")
If an explicit API key is not provided, the Connection
constructor will look for
one first in the MAGNETSDK_API_KEY
environment variable and failing that in the
default
profile of the configuration file.
You can add different API keys to a configuration file with different profiles by
creating a file called .magnetsdk/config
under the current user's home directory.
It is a basic Python configuration file that looks like the following:
[default]
api_key=my secret api key
[profile2]
api_key=another secret api key
So in this case you could create a connection to use either API key as follows:
from magnetsdk2 import Connection
conn_default = Connection() # uses default profile
conn_profile2 = Connection(profile='profile2') # use profile2 explicitly
It's as simple as creating a Connection
object and using it to perform queries.
This small example shows you how to print out all of the organizations the configured
API key has access to.
import json
from magnetsdk2 import Connection
conn = Connection()
for org in conn.iter_organizations():
print(json.dumps(org, indent=4))
A common scenario for using the SDK is downloading only new alerts over time, typically to feed an integration with a 3rd party SIEM or ticketing system. In order to implement this, the concept of a persistent iterator that saves its state on a JSON file is provided in the SDK:
from magnetsdk2 import Connection
from magnetsdk2.iterator import FilePersistentAlertIterator
conn = Connection()
# replace xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx with a valid organization ID
alert_iterator = FilePersistentAlertIterator('persistence.json', conn, 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
for alert in alert_iterator:
try:
# try to process alert in some way
print(alert)
except:
alert_iterator.load() # on failure, reload iterator so last alert doesn't count as processed
else:
alert_iterator.save() # on success, save iterator so last alert counts as processed
If you run this same code multiple times, it should ever only output alerts it hasn't
processed before, provided file persistence.json
is not tampered with and remains
available for reading and writing.
You save the current state of the iterator with the save
method. If you tried to
process an alert and failed, you can simply not save the iterator and reload the
previous consistent state from disk using the load
method.
Though the provided implementation saves the data to a JSON file, it is easy to add other
means of persistence by creating subclasses of
magnetsdk2.iterator.AbstractPersistentAlertIterator
that implement the abstract _save
and _load
methods.
Starting with version 1.2.0, the package installs a niddel
command-line utility which
can be used to perform most of the same functionalities available on the SDK. First install
the package:
$ pip install magnetsdk2
Then, you can see that a --profile
option can be provided to select an alternative API key
from ~/.magnetsdk/config
, as described previously:
$ niddel -h
usage: niddel [-h] [-p PROFILE] [-i] [-v] [-o OUTFILE]
{me,organizations,alerts,logs} ...
Command-line utility to interact with the Niddel Magnet v2 API (v1.4.1)
positional arguments:
{me,organizations,alerts,logs}
me display API key owner information
organizations list basic organization information
alerts list an organization's alerts
logs upload, download or list log files
optional arguments:
-h, --help show this help message and exit
-p PROFILE, --profile PROFILE
which profile (from ~/.magnetsdk/config) to obtain API
key from
-i, --indent indent JSON output
-v, --verbose set verbose mode
-o OUTFILE, --outfile OUTFILE
destination file to write to, if exists will be
overwritten
You can even use a persistent alert iterator by providing a file name with --persist
when listing
alerts:
$ niddel alerts -h
usage: niddel alerts [-h] [--start START] [-p PERSIST] [-f {json,cef}]
organization
list an organization's alerts
positional arguments:
organization ID of the organization
optional arguments:
-h, --help show this help message and exit
--start START initial batch date to process in YYYY-MM-DD format
-p PERSIST, --persist PERSIST
file to store persistent state data, to ensure only
alerts that haven't been seen before are part of the
output
-f {json,cef}, --format {json,cef}
format in which to output alerts
Keep in mind that the persistence state is only saved immediately before the command exits, after all unprocessed alerts have been printed to stdout. So if the CLI utility is interrupted or if an exception occurs mid-processing, no state is saved and any alerts output in this failed execution are not considered processed.
The default output format for alerts is JSON, but if you provide --format cef
then the
ArcSight Common Event Format
will be used instead.