---
myst:
html_meta:
"description lang=en": "suricata-check is a command line utility to provide feedback on Suricata rules to by detecting issues through static analysis."
"keywords": "Suricata, rules, ruleset, suricata-check, API, Python"
---
# API Usage
Sometimes it may be more convenient to avoid the CLI and instead use the module directly, which exposes more functionality and may be easier te extend if your project also uses Python. Below, we will characterize several use-cases you may encounter and how to address them using the functionality exposed by `suricata-check`.
All publicly exposed modules, classes, and methods are documented and typed such that IDEs such as Visual Studio Code will provide useful information and suggestions as you write code using `suricata_check`.
## Analyze a single rule
In order to analyze a single rule using the module, you first need to parse the rule using `idstools`, which is installed together with `suricata_check`.
Thereafter, you can process it using `suricata_check.analyze_rule` as follows to obtain a `RuleReport`
```python
import idstools
import idstools.rule
import suricata_check
rule = """\
alert ip any any -> any any (msg:"Some msg"; sid:1;)"""
parsed_rule = idstools.rule.parse(rule)
assert parsed_rule is not None
rule_report = suricata_check.analyze_rule(parsed_rule)
```
Note that `parsed_rule` may be `None` if it is unparseable for `idstools`. Parseable rules need not be valid Suricata rules. If `suricata_check` cannot parse the rule, a `InvalidRuleError` will be raised.
You can further inspect the rule report, which is implemented as a dataclass, by treating it as a dictionary.
```python
print(rule_report.rule['raw'])
print("Number of issues found: " + str(len(rule_report.issues)))
```
## Inspecting issues
Similar to the rule report, issues are represented by dataclasses, which you can treat as dictionaries.
```python
print(rule_report.rule['raw'])
for issue in rule_report.issues:
print(issue.code)
print(issue.msg)
```
## Selecting checkers
Sometimes you may only be interested in running a single checker, or enabling/disabling certain codes similar to the CLI usage. You can do so by passing checkers to `analyze_rule`.
```python
checkers = suricata_check.get_checkers(include=("M.*",), exclude=tuple())
rule_report = suricata_check.analyze_rule(parsed_rule, checkers=checkers)
```
If you have implemented a checker implementing the `CheckerInterface` as descibed in [CONTRIBUTING](./contributing.md), the checker will be discoverable by the `get_checkers` function. Any other class (e.g. `MyOwnChecker`) implementing `CheckerInterface`, may be passed to `analyze_rule` directly as follows:
```python
rule_report = suricata_check.analyze_rule(parsed_rule, checkers=[MyOwnChecker()])
```
## Processing rulesets
Similar to the CLI, it is possible to process entire rulesets at once using `process_rules_file`. Also for this function, it is optionally possible to explcitly pass checkers to use.
```python
from suricata_check.checkers import MetadataChecker
ruleset_report = suricata_check.process_rules_file(
"/var/lib/suricata/rules/suricata.rules",
evaluate_disabled=True,
checkers=[MetadataChecker()]
)
for rule_report in ruleset_report.rules:
has_issues = len(rule_report.issues) > 0
if has_issues:
print(rule_report.rule['raw'])
```