Skip to main content

TicketSync

Bidirectional ticket synchronization across ITSM, monitoring, and security systems.

CI PyPI Python License

TicketSync is a Python library, not a platform. You pip install it and use it in code. No daemons, no YAML platform to self-host, no vendor lock-in.


Install

pip install ticketsync

For AWS adapters (CloudWatch, GuardDuty, Security Hub, OpsCenter):

pip install "ticketsync[integration]"

Requires Python 3.10+.


Quickstart — CloudWatch alarms into OpsCenter in 15 lines

import boto3
from ticketsync.adapters.cloudwatch_alarms import CloudWatchAlarmsAdapter
from ticketsync.adapters.opscenter import OpsCenterAdapter
from ticketsync.config import SyncConfig
from ticketsync.engine import SyncEngine

source = CloudWatchAlarmsAdapter(
    client=boto3.client("cloudwatch", region_name="us-east-1"),
    state_filter=["ALARM"],
)
dest = OpsCenterAdapter(
    client=boto3.client("ssm", region_name="us-east-1"),
)
config = SyncConfig.from_dict({
    "source": {"type": "cloudwatch_alarms"},
    "destination": {"type": "opscenter"},
    "deduplication": True,
    "lookback_hours": 24,
})

engine = SyncEngine(source=source, dest=dest, config=config)
result = engine.run()
print(f"Synced {result.written} alarms to OpsCenter")

Adapter table

Adapter class System Direction Required IAM / auth
CloudWatchAlarmsAdapter AWS CloudWatch Alarms read cloudwatch:DescribeAlarms
GuardDutyFindingsAdapter AWS GuardDuty Findings read guardduty:ListFindings, guardduty:GetFindings
SecurityHubFindingsAdapter AWS Security Hub (ASFF) read securityhub:GetFindings
OpsCenterAdapter AWS Systems Manager OpsCenter read/write ssm:GetOpsItem, ssm:CreateOpsItem, ssm:UpdateOpsItem
GitHubIssuesAdapter GitHub Issues REST API read/write GitHub PAT with repo scope
LocalFilesystemAdapter Local JSON files read/write None

Config YAML reference

source:
  type: cloudwatch_alarms      # adapter type key (see table above)
  # any extra keys are passed as kwargs to the adapter constructor

destination:
  type: opscenter
  region: us-east-1

deduplication: true            # skip tickets already written to destination
lookback_hours: 24             # only sync tickets updated in last N hours (0 = all)

Load config from a YAML string, file path, or open file object:

from ticketsync.config import SyncConfig

config = SyncConfig.from_yaml("path/to/sync.yaml")
# or
config = SyncConfig.from_dict({"source": {...}, "destination": {...}})

Example — GuardDuty findings into GitHub Issues

import boto3
import httpx
from ticketsync.adapters.guardduty import GuardDutyFindingsAdapter
from ticketsync.adapters.github_issues import GitHubIssuesAdapter
from ticketsync.config import SyncConfig
from ticketsync.engine import SyncEngine


class HttpxClient:
    """Thin httpx wrapper matching the GitHubIssuesAdapter client interface."""

    def __init__(self, token: str) -> None:
        self._headers = {"Authorization": f"Bearer {token}"}

    def get(self, url: str, params: dict | None = None) -> object:
        return httpx.get(url, params=params, headers=self._headers).json()

    def post(self, url: str, json: dict | None = None) -> dict:
        return httpx.post(url, json=json, headers=self._headers).json()

    def patch(self, url: str, json: dict | None = None) -> dict:
        return httpx.patch(url, json=json, headers=self._headers).json()


source = GuardDutyFindingsAdapter(
    client=boto3.client("guardduty", region_name="us-east-1"),
    detector_id="your-detector-id",
)
dest = GitHubIssuesAdapter(
    client=HttpxClient("ghp_your_token"),
    owner="your-org",
    repo="security-issues",
)
config = SyncConfig.from_dict({
    "source": {"type": "guardduty"},
    "destination": {"type": "github_issues"},
    "deduplication": True,
    "lookback_hours": 6,
})

result = SyncEngine(source=source, dest=dest, config=config).run()
print(f"Opened {result.written} GitHub issues from GuardDuty findings")

Core data model

Every ticket, alarm, finding, and issue is normalized to the Ticket IR before moving between adapters:

from ticketsync.models import Ticket

ticket = Ticket(
    source_system="guardduty",
    source_id="abc123",
    title="Suspicious API call from known malicious IP",
    description="GuardDuty detected an unusual API call pattern.",
    severity="high",        # critical / high / medium / low / informational
    status="open",          # open / in_progress / resolved / closed
    category="Recon:EC2/Portscan",
    tags=["region:us-east-1", "product:GuardDuty"],
)

See docs/ARCHITECTURE.md for the full field reference.


Documentation

  • docs/ADAPTERS.md — required permissions, field mapping tables, and config examples for every adapter
  • docs/ARCHITECTURE.md — Ticket IR fields, Protocol interface, SyncEngine behavior, deduplication logic
  • docs/CONTRIBUTING.md — how to write a new adapter, test patterns, registry entry

License

Apache 2.0

Release files for ticketsync 0.3.1

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

Source distribution (sdist)

Source distribution for ticketsync 0.3.1
File Size Uploaded
ticketsync-0.3.1.tar.gz 80.9 kB Details

Built distribution (wheel)

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

Total release size: 121.1 kB

Release files / ticketsync-0.3.1.tar.gz

Download URL ticketsync-0.3.1.tar.gz
Size 80.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6ee409edeef1359dad206d5b84bc98b38ad5f91020e0198c2a78199e4d318a35
BLAKE2b-256 checksum
How to use checksums
a4b0dde46800eeccfd2874007b6b5d81c2794dc1617562cba2718d61806c2c73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 9, 2026.

Transparency log

Release files / ticketsync-0.3.1-py3-none-any.whl

Download URL ticketsync-0.3.1-py3-none-any.whl
Size 40.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ac84a29ffc1343422ed0ba323c3daf5c7de6424b309ebc0f5d2bbf8434b1743e
BLAKE2b-256 checksum
How to use checksums
c16b956cb338b92aeef8298523bbe84409e581b43516fe5b28014c68daeabbb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

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