Create pyproject.toml

Update siem models based on their documentations
This commit is contained in:
Peter Annabel 2025-07-24 09:47:49 -05:00
parent b25e300fef
commit 854f16cc45
5 changed files with 53 additions and 83 deletions

3
.gitignore vendored
View File

@ -207,4 +207,5 @@ marimo/_lsp/
__marimo__/
# Development files
src/scratchpad.py
managedsat_scratchpad.py
siem_scratchpad.py

View File

@ -71,7 +71,7 @@ siem_api_client = HuntressSIEMAPIClient(
Endpoints are 1:1 to what's available for both the Huntress Managed SAT and Huntress SIEM.
For more information, check out the following resources:
- [Huntress Managed SAT REST API Docs](https://support.meetgradient.com/huntress-managed-sat)
- [Huntress Managed SAT REST API Docs](https://curricula.stoplight.io/docs/curricula-api/00fkcnpgk5vnn-getting-started)
- [Huntress SIEM REST API Docs](https://api.huntress.io/docs)
### Get many

37
pyproject.toml Normal file
View File

@ -0,0 +1,37 @@
[project]
name = "pyhuntress"
version = "0.1.1"
authors = [
{ name="Peter Annabel", email="peter.annabel@gmail.com" },
]
description = "A full-featured Python client for the Huntress APIs"
readme = "README.md"
requires-python = ">=3.9"
classifiers = [
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.10",
]
keywords = [
"Huntress",
"Manages SAT",
"SIEM",
"API",
"Python",
"Client",
"Annotated",
"Typed",
"MSP",
]
license = "GPL-3.0-only"
license-files = ["LICEN[CS]E*"]
[project.urls]
Homepage = "https://github.com/brygphilomena/pyhuntress"
Issues = "https://github.com/brygphilomena/pyhuntress/issues"
[build-system]
requires = ["hatchling >= 1.26"]
build-backend = "hatchling.build"

View File

@ -21,7 +21,7 @@ class SIEMAgents(HuntressModel):
id: int | None = Field(default=None, alias="Id")
version: str | None = Field(default=None, alias="Version")
arch: str | None = Field(default=None, alias="Arch")
win_build_number: str | None = Field(default=None, alias="WinBuildNumber")
win_build_number: int | None = Field(default=None, alias="WinBuildNumber")
domain_name: str | None = Field(default=None, alias="DomainName")
created_at: datetime | None = Field(default=None, alias="CreateAt")
hostname: str | None = Field(default=None, alias="Hostname")
@ -62,7 +62,10 @@ class SIEMAccount(HuntressModel):
id: int | None = Field(default=None, alias="Id")
name: str | None = Field(default=None, alias="Name")
subdomain: str | None = Field(default=None, alias="Subdomain")
status: str | None = Field(default=None, alias="Status")
status: Literal[
"enabled",
"disabled",
] | None = Field(default=None, alias="Status")
class SIEMActorResponse(HuntressModel):
account: dict[str, Any] | None = Field(default=None, alias="Account")
@ -217,12 +220,14 @@ class SIEMReports(HuntressModel):
itdr_incidents_reported: int | None = Field(default=None, alias="ITDRIncidentsReported")
siem_incidents_reported: int | None = Field(default=None, alias="SIEMIncidentsReported")
incidents_resolved: int | None = Field(default=None, alias="IncidentsResolved")
# The following 3 counts are listed as "map" in Huntress' docs, I'm not sure what data type to use here
incident_severity_counts: int | None = Field(default=None, alias="IncidentSeverityCounts")
incident_product_counts: int | None = Field(default=None, alias="IncidentProductCounts")
incident_indicator_counts: int | None = Field(default=None, alias="IncidentIndicatorCounts")
top_incident_av_threats: list | None = Field(default=None, alias="TopIncidentAVThreats")
# top_incident_hosts is also listed as "map" in their docs
top_incident_hosts: list | None = Field(default=None, alias="TopIncidentHosts")
potential_threat_indicators: list | None = Field(default=None, alias="PotentialThreatIndicators")
potential_threat_indicators: int | None = Field(default=None, alias="PotentialThreatIndicators")
agents_count: int | None = Field(default=None, alias="AgentsCount")
deployed_canaries_count: int | None = Field(default=None, alias="DeployedCanariesCount")
protected_profiles_count: int | None = Field(default=None, alias="ProtectedProfilesCount")
@ -232,6 +237,8 @@ class SIEMReports(HuntressModel):
analyst_note: str | None = Field(default=None, alias="AnalystNote")
global_threats_note: str | None = Field(default=None, alias="GlobalThreatsNote")
ransomware_note: str | None = Field(default=None, alias="RansomwareNote")
# Huntress has incident_log listed as "complex" with the note "A JSON representation of any critical
# or high severity incidents from this report"
incident_log: str | None = Field(default=None, alias="IncidentLog")
total_mav_detection_count: int | None = Field(default=None, alias="TotalMAVDetectionCount")
blocked_malware_count: int | None = Field(default=None, alias="BlockedMalwareCount")
@ -245,9 +252,9 @@ class SIEMReports(HuntressModel):
itdr_signals: int | None = Field(default=None, alias="ITDRSignals")
siem_signals: int | None = Field(default=None, alias="SIEMSignals")
itdr_investigations_completed: int | None = Field(default=None, alias="ITDRInvestigationsCompleted")
macos_agents: str | None = Field(default=None, alias="MacOSAgents")
windows_agents: str | None = Field(default=None, alias="WindowsAgents")
only_macos_agents: str | None = Field(default=None, alias="OnlyMacOSAgents")
macos_agents: bool | None = Field(default=None, alias="MacOSAgents")
windows_agents: bool | None = Field(default=None, alias="WindowsAgents")
only_macos_agents: bool | None = Field(default=None, alias="OnlyMacOSAgents")
antivirus_exclusions_count: int | None = Field(default=None, alias="AntivirusExclusionsCount")
new_exclusions_count: int | None = Field(default=None, alias="NewExclusionsCount")
allowed_exclusions_count: int | None = Field(default=None, alias="AllowedExclusionsCount")

View File

@ -1,75 +0,0 @@
import os
from pyhuntress import HuntressSIEMAPIClient
from dotenv import load_dotenv
load_dotenv()
siem_url = os.getenv('siem_url')
publickey = os.getenv('publickey')
privatekey = os.getenv('privatekey')
# init client
siem_api_client = HuntressSIEMAPIClient(
siem_url,
publickey,
privatekey,
)
#account = siem_api_client.account.get()
#print(account)
#actor = siem_api_client.actor.get()
#print(actor)
#agents = siem_api_client.agents.get()
#print(agents)
#agents = siem_api_client.agents.id(3989773).get()
#print(agents)
#billingreports = siem_api_client.billing_reports.get()
#print(billingreports)
#billingreports = siem_api_client.billing_reports.id(90173).get()
#print(billingreports)
#incidentreports = siem_api_client.incident_reports.get()
#print(incidentreports)
incidentreports = siem_api_client.incident_reports.id(1448648).get()
print(incidentreports)
#organizations = siem_api_client.organizations.id(174759).get()
#print(organizations)
#organizations = siem_api_client.organizations.get()
#print(organizations)
#reports = siem_api_client.reports.get()
#print(reports)
#signals = siem_api_client.signals.get()
#print(signals)
reports = siem_api_client.reports.id(2175766).get()
print(reports)
signals = siem_api_client.signals.id(36581548).get()
print(signals)
#paginated_billingreports = siem_api_client.billing_reports.paginated(1, 10)
#print(paginated_billingreports.data)
#paginated_incidentreports = siem_api_client.incident_reports.paginated(1, 10)
#print(paginated_incidentreports.data)
#paginated_organizations = siem_api_client.organizations.paginated(2, 100)
#print(paginated_organizations.data)
#paginated_organizations.get_next_page()
#print(paginated_organizations.data)
#paginated_reports = siem_api_client.reports.paginated(1, 10)
#print(paginated_reports.data)
#paginated_signals = siem_api_client.signals.paginated(1, 10)
#print(paginated_signals.data)