Skip to main content

eyalsec: the Python client for the EyalSec API

PyPI Python versions CI Docs

Work with your EyalSec account from Python: pull this week's critical events into a report, fail a pipeline on a new finding, label and annotate events in bulk, keep rules and filters in code, or add a machine from your provisioning script. Everything the EyalSec API offers is a typed method here, in a synchronous and an asyncio flavour, with paging, retries and clear errors handled for you.

import eyalsec

client = eyalsec.EyalSec()  # reads EYALSEC_API_KEY

for event in client.iter_events(severity=["critical", "high"], from_date="2026-10-01"):
    print(event.created_at, event.severity, event.where, event.machine_name)

This package is the API client, not the runtime. pip install eyalsec gives you this library. It is not es-python, the EyalSec Python runtime, and importing it adds no security checks to your program. The runtime is installed from your EyalSec dashboard: see the Quick start.

What EyalSec does

EyalSec follows untrusted data (requests, files, environment variables and more) through your running program and reports when it reaches a risky operation: a SQL query, a shell command, deserialization, a file path. Each event names the operation, the line of code, the value it received and where the untrusted part came from. You run your existing app through es-python, unchanged, and the events arrive on your dashboard. This library reads and manages them.

Install

pip install eyalsec

Python 3.9 or newer. The only dependency is httpx.

Get a key

Create an API key on your dashboard under Settings > API access and put it in EYALSEC_API_KEY. A read-only key can call every read, and it is the one to use for reports and dashboards; scripts that change things need a full key. See API keys.

export EYALSEC_API_KEY=es2_your_key
python -m eyalsec --check    # calls the API once and prints the account it reached

No account yet? Book a live demo and we will set one up with you. Pricing is at eyalsec.com/pricing.

Examples

Events

page = client.query_events(view="python", sort="severity")  # one page, up to 100
for event in page.events:
    print(event.id, event.severity, event.where, event.str_repr)

detail = client.get_event(page.events[0].id)  # the large fields
print(detail.trace)
print(detail.source_code, detail.sink_code)

# Every event, following the cursor for you (including past empty pages).
critical = list(client.iter_events(severity="critical", machine="web-01"))

# What one run of a program produced.
run = next(client.iter_runs(q="manage.py"))
for event in client.iter_events(view="python", run=run.run_uid):
    print(event.where, event.count)

csv_bytes = client.export_events("csv", view="python", from_date="2026-10-01")

Triage

label = client.create_label("needs review", "amber")
for event in client.iter_events(tags=["sqli"], bucket="live"):
    client.attach_label(event.id, label.id)
    client.set_note(event.id, "Queued for the Thursday review.")

Rules and filters as code

from eyalsec import RuleMode

client.create_rule(event_pattern="^healthcheck", mode=RuleMode.HIDE, label="health checks")
client.create_filter("^socket-recv$", "blacklist", label="noise")
client.set_taint("socket", "on")  # your account default
client.apply_rule_template(template_id=3, machine=None)  # None means your global rules

Machines and CI

machine = client.add_machine("web-02")  # build detected at install time
command = client.get_install_command(machine.public_id, attested=True)
print(command.script_path, command.expires_in)  # the secret is single-use

install = client.ci_install("ci-myrepo", attested=True, distro="ubuntu_24_04", arch="x86_64")
# ... run your tests under es-python ...
result = client.ci_findings("ci-myrepo", since=install.server_time, min_severity="high")
if result.findings:
    raise SystemExit(f"{result.findings} findings at high or above: {result.url}")

attested=True is your confirmation that you are authorized to monitor that machine, the same box the dashboard asks you to tick.

asyncio

import asyncio
import eyalsec


async def main() -> None:
    async with eyalsec.AsyncEyalSec() as client:
        async for event in client.iter_events(severity=["critical"]):
            print(event.id, event.where)


asyncio.run(main())

AsyncEyalSec has exactly the same methods as EyalSec.

Errors

Every error the client raises is an eyalsec.EyalSecError. An error status becomes a subclass you can catch by meaning:

Status Exception
400 BadRequestError
401 AuthenticationError (missing, wrong, revoked or expired key)
403 PermissionDeniedError (for example a read-only key trying to write)
404 NotFoundError (also for things on another account, so their existence is never confirmed)
409 ConflictError (for example the machine limit is reached)
422 UnprocessableEntityError
429 RateLimitError, with retry_after
5xx InternalServerError

Each carries status, message, method and path. A request that got no answer raises APIConnectionError (or APITimeoutError).

The client retries a rate-limited request after the server's Retry-After (up to max_retries, default 2), and retries reads after a dropped connection or a 502, 503 or 504. Writes are never retried after a dropped connection, because there is no way to know whether they applied. The API's rate limits are 300 requests a minute per account.

Configuration

Argument Environment Default
api_key EYALSEC_API_KEY none (required for everything but the two public lists)
base_url EYALSEC_URL https://eyalsec.com
timeout 30 seconds
max_retries 2
http_client your own httpx.Client / httpx.AsyncClient, for proxies or custom TLS

The key is sent only to base_url, only over HTTPS (plain http:// is accepted for localhost alone), and never appears in a repr.

Documentation

Related: eyalsec-cli for the terminal, eyalsec-mcp for AI assistants, and es-python-action for GitHub Actions.

Development

git clone https://github.com/EyalSec/eyalsec-python && cd eyalsec-python
python -m venv .venv && . .venv/bin/activate
pip install -e '.[test]'
pytest

src/eyalsec/_client.py is generated from _async_client.py: edit the async file and run python scripts/unasync.py. The tests run against a fake API; EYALSEC_LIVE=1 adds a read-only pass against your own account (see tests/test_live.py).

Help

Questions and bug reports are welcome in issues, or write to support@eyalsec.com. Please send security reports to security@eyalsec.com rather than a public issue.

License

MIT. See LICENSE. The license covers this client library; your EyalSec account is governed by the EyalSec terms.

Metadata

Release files for eyalsec 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eyalsec 1.1.0
File Size Uploaded
eyalsec-1.1.0.tar.gz 40.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for eyalsec 1.1.0
File Interpreter ABI Platform
eyalsec-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 84.6 kB

Release files / eyalsec-1.1.0.tar.gz

Download URL eyalsec-1.1.0.tar.gz
Size 40.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4eedd06accbf5f9d08b838b3c370c941c693efe05846cbe948d7facf345a836f
BLAKE2b-256 checksum
How to use checksums
a52146517f7b05084c74d411b5af437e2ef74ca30e69b40374cbb75667070b38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / eyalsec-1.1.0-py3-none-any.whl

Download URL eyalsec-1.1.0-py3-none-any.whl
Size 44.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
828c1fb8d8ae037bbb4f928f9da6fa64a94bf324a6f8eef8d39cee84f7f9ff1a
BLAKE2b-256 checksum
How to use checksums
e0eef277f74bc2f8d66fcefac0ac895ab6c932dfb70ed1de7dfe34d1fdcaa3cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page