Skip to main content

truesignal (Python)

A provenance-first OSINT/security intelligence feed. Every item ships a real source URL, a real upstream timestamp, and an explicit live/fallback flag -- never a fabricated or silently-replayed data point.

PyPI version npm version License: MIT Python versions CI

Why this exists

Personal OSINT/security feeds are easy to build and easy to get wrong in one specific way: silently showing stale or synthetic data as if it were current. TrueSignal's answer is structural, not a documentation promise -- every connector's failure path is enforced by a dedicated test suite to return either a real cached item honestly labeled fallback with its real age, or nothing at all. This package is the Python distribution -- a genuine, independent port of the npm package, not a wrapper around the Node binary.

Install

pip install truesignal-cli

or with uv:

uv add truesignal-cli

No separate install step, no external binary to fetch. The complementary JS/TS distribution installs the same way on the npm side: npm install -g truesignal-cli (or npx truesignal-cli init to run it once without installing) -- see the project README for that package. Both are first-class, maintained together; neither is deprecated in favor of the other.

Quickstart

truesignal init
truesignal feed

init reports which connectors are ready right now -- CISA-KEV and GDELT need no configuration -- and which environment variables are still missing for the rest (Cloudflare Radar, Reddit, Telegram). feed pulls from every configured connector.

Or call the library directly (the agent-native path):

from truesignal import ALL_CONNECTORS

for connector in ALL_CONNECTORS:
    if connector.requires_config and not connector.is_configured():
        continue
    for item in connector.fetch_items():
        print(item.status, item.source, item.url)

How it works

connector.fetch_items()
   -> fetch_with_fallback(source, fetch_live)
        -> upstream API call succeeds -> stamp_live() -> write_cache() -> real "live" items
        -> upstream API call fails    -> read_cache() -> stamp_fallback() -> real "fallback"
                                          items with an honest fallback_age_seconds, or []
                                          if nothing has ever been cached

Every connector implements the same Connector interface (truesignal/types.py) and calls fetch_with_fallback instead of touching the network directly -- that single function is what gives every connector its live/fallback/nothing guarantee. See docs/concepts.md for the full data model and what each of the five connectors actually returns.

No-fabrication guarantee

Every connector's live, fallback, and empty-cache-failure path is covered by a dedicated pytest suite (tests/test_no_fabrication.py), ported directly from the TypeScript suite's no-fabrication.test.ts: it proves, for every connector, that a failed upstream fetch never produces synthetic, randomized, or silently-relabeled-as-current data -- only a real cached fallback item with an honest age, or nothing. A companion static check scans every connector source file in src/truesignal/connectors/ for forbidden patterns (random.random(), a fake-data library, datetime.now() used to construct an item's timestamp).

CLI command reference

usage: truesignal [-h] [--version] {init,feed,verify} ...

Commands:
  init [--json]                     Check which connectors are ready right now.
  feed [--source NAME] [--json]     Pull the current feed from every configured
                                     connector, or one connector with --source.
  verify <item-id> [--json]         Re-fetch the source named in <item-id> and
                                     confirm its current provenance.

Exit codes: 0 success, 1 general error, 2 no connectors configured, 3 network error (a configured connector's fetch failed with no fallback data), 4 a malformed or unknown verify item id -- documented in full in docs/concepts.md.

Security

No connector ever eval()s, exec()s, or dynamically imports anything read from an upstream response -- responses are only ever parsed as JSON and mapped into typed fields. Credentials are read only from real environment variables (CLOUDFLARE_RADAR_API_TOKEN, REDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET, TELEGRAM_BOT_TOKEN) -- never accepted as a CLI flag, never auto-loaded from a .env file. To report a vulnerability, see SECURITY.md. Honest note: this project does not currently publish SLSA provenance, Sigstore signatures, or an SBOM, and has no OpenSSF Scorecard badge set up -- none of that infrastructure exists yet for either distribution, so it isn't claimed here.

FAQ

What does this do? Pulls OSINT and security-relevant items (CVEs, threat intel, security news) from five official APIs -- CISA-KEV, Cloudflare Radar, Reddit, Telegram, GDELT -- and stamps every item with a real source URL, a real upstream timestamp, and an explicit live/fallback label, so you never see fabricated or silently-stale data presented as current.

How is this PyPI package different from the npm one, if at all? It isn't a wrapper around the Node binary -- it's a genuine, independent Python port with the same five connectors, the same fetch_with_fallback provenance guarantee, and the same init/feed/ verify CLI surface. Both distributions are first-class and maintained together; neither is deprecated in favor of the other, so pick whichever fits your toolchain.

Does this need an API key? Not to start. CISA-KEV and GDELT work with zero configuration. Cloudflare Radar, Reddit, and Telegram each need a free developer key or token, read only from environment variables (CLOUDFLARE_RADAR_API_TOKEN, REDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET, TELEGRAM_BOT_TOKEN) -- truesignal init tells you exactly which ones are still missing.

Is it safe to run? No connector eval()s, exec()s, or dynamically imports anything read from an upstream response -- responses are only ever parsed as JSON and mapped into typed fields. Credentials are never accepted as a CLI flag and never auto-loaded from a .env file. See the Security section above for the current caveat on SLSA/Sigstore/SBOM/Scorecard coverage.

What happens if a source goes down? The connector returns real cached data explicitly labeled fallback (with its exact real age in fallback_age_seconds), or nothing at all -- never invented data, and never old data silently relabeled as current. That guarantee is enforced by tests/test_no_fabrication.py for every one of the 5 connectors.

Contributing

See CONTRIBUTING.md for the full guide, covering both the TypeScript and Python codebases.

cd python
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

License

MIT, see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

truesignal_cli-0.1.5.tar.gz (33.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

truesignal_cli-0.1.5-py3-none-any.whl (33.7 kB view details)

Uploaded Python 3

File details

Details for the file truesignal_cli-0.1.5.tar.gz.

File metadata

  • Download URL: truesignal_cli-0.1.5.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for truesignal_cli-0.1.5.tar.gz
Algorithm Hash digest
SHA256 94bb1103d0e33a226755444b6ed20640697b1cd2ffea587d95070c3fba83b79f
MD5 60e61693ba16ee141d878368d0d7d91a
BLAKE2b-256 95a4dd7794172c751afabe233d1b66b6ba0b78548a53e9976abaee44fb3b9b2e

See more details on using hashes here.

File details

Details for the file truesignal_cli-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: truesignal_cli-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 33.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for truesignal_cli-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e31fe1d20a9480dfe3b0bb41f02ea54c1cf433aab1478114166a58e63f1766b5
MD5 844d1effc42c1945e9629b8054d0c366
BLAKE2b-256 bfb98d575cac374669da93b8b879b134730c93faa1e422a75b08639e0c33817c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.6

2 files

This release

0.1.5 This release

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 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