Usage Guide¶
Installation¶
pip install python-rayhunter
Requirements¶
Python >= 3.11
requests >= 2.32.2
Quick Start¶
All interaction with a Rayhunter device happens through RayhunterApi.
Instantiate it with the hostname (or IP address) and port of your device:
from rayhunter import RayhunterApi
api = RayhunterApi(hostname="192.168.1.1", port=8080)
Checking Recording Status¶
The active_recording property returns True if a
capture is currently in progress:
if api.active_recording:
print("A recording is currently in progress")
Fetching the QMDL Manifest¶
The manifest lists all capture files available on the device, plus the currently active
capture (if any). Use get_manifest() to retrieve it:
manifest = api.get_manifest()
for entry in manifest.entries:
print(f"{entry.name} — started {entry.start_time}, size {entry.qmdl_size_bytes} bytes")
if manifest.current_entry:
print(f"Active capture: {manifest.current_entry.name}")
Downloading Capture Files¶
Use the filenames from the manifest to download raw captures, PCAP files, or analysis reports.
# Raw QMDL capture data
qmdl_data = api.get_qmdl_file("capture.qmdl")
# PCAP file (dynamically generated from QMDL by the Rayhunter binary)
pcap_data = api.get_pcap_file("capture.qmdl")
# Analysis report
report_data = api.get_analysis_report_file("capture.qmdl")
# ZIP containing both the QMDL and the generated PCAP
zip_data = api.get_zip("capture.qmdl")
Controlling Recordings¶
# Start a new recording (stops any active recording first)
api.start_recording()
# Stop the current recording
api.stop_recording()
# Delete a specific recording
api.delete_recording("capture.qmdl")
# Delete all recordings (not available in debug mode)
api.delete_all_recordings()
System Statistics¶
get_system_stats() returns a
SystemStats object containing disk, memory, and
battery information:
stats = api.get_system_stats()
disk = stats.disk_stats
print(f"Partition: {disk.partition} ({disk.mounted_on})")
print(f"Disk usage: {disk.used_size}/{disk.total_size} bytes ({disk.used_percent}% used)")
mem = stats.memory_stats
print(f"Memory: {mem.used}/{mem.total} bytes used, {mem.free} bytes free")
meta = stats.runtime_metadata
print(f"Rayhunter {meta.rayhunter_version} on {meta.system_os} ({meta.arch})")
if stats.battery_status:
bat = stats.battery_status
print(f"Battery: {bat.level}% {'(charging)' if bat.is_plugged_in else ''}")
Configuration¶
Read and update the runtime configuration of a connected device using the
configuration property or the lower-level
get_config() /
set_config() methods.
Warning
Setting the configuration triggers a device reboot.
config = api.configuration # fetch current config
config.debug_mode = True
api.configuration = config # push updated config (reboots device)
Analysis Status¶
Check which QMDL files have been analyzed, are queued, or are currently being processed:
status = api.get_analysis_status()
print("Finished:", status.finished)
print("Queued: ", status.queued)
if status.running:
print("Running: ", status.running)
Time¶
Retrieve the device clock and its current offset:
t = api.get_time()
print(f"System time: {t.system_time}")
print(f"Adjusted time (+{t.offset_seconds}s): {t.adjusted_time}")
Notifications¶
Trigger a test notification to the ntfy_url configured on the device:
api.send_test_notification()
Device Log¶
Download the current device log as raw bytes (UTF-8 plaintext):
log_bytes = api.get_log()
print(log_bytes.decode("utf-8"))