{"id":48101141,"url":"https://github.com/distributed-system-analysis/state-signals","last_synced_at":"2026-04-04T15:43:23.176Z","repository":{"id":41141463,"uuid":"394696129","full_name":"distributed-system-analysis/state-signals","owner":"distributed-system-analysis","description":"A python package for easy state/event signal publishing, receiving, subscribing, and responding. Also defines standard state signal/response protocols. Built on top of Redis pub/sub channels. Find at https://pypi.org/project/state-signals or https://copr.fedorainfracloud.org/coprs/meyceoz/state-signals","archived":false,"fork":false,"pushed_at":"2023-02-03T20:10:16.000Z","size":181,"stargazers_count":5,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-28T00:21:38.346Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/distributed-system-analysis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-10T15:03:22.000Z","updated_at":"2024-09-25T22:52:53.000Z","dependencies_parsed_at":"2023-02-18T14:00:27.051Z","dependency_job_id":null,"html_url":"https://github.com/distributed-system-analysis/state-signals","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/distributed-system-analysis/state-signals","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-system-analysis%2Fstate-signals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-system-analysis%2Fstate-signals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-system-analysis%2Fstate-signals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-system-analysis%2Fstate-signals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/distributed-system-analysis","download_url":"https://codeload.github.com/distributed-system-analysis/state-signals/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/distributed-system-analysis%2Fstate-signals/sbom","scorecard":{"id":344929,"data":{"date":"2025-08-11","repo":{"name":"github.com/distributed-system-analysis/state-signals","commit":"14edc882661f5d13a1a06ec83569bd18ce5add5c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-app.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/distributed-system-analysis/state-signals/python-app.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-app.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/distributed-system-analysis/state-signals/python-app.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:26","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:27","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:30","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:31","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":1,"reason":"Found 3/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/python-app.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T06:49:39.365Z","repository_id":41141463,"created_at":"2025-08-18T06:49:39.366Z","updated_at":"2025-08-18T06:49:39.366Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31403960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T15:43:22.996Z","updated_at":"2026-04-04T15:43:23.139Z","avatar_url":"https://github.com/distributed-system-analysis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# state-signals: the State/Event Signal Module\n\n[![Python application](https://github.com/distributed-system-analysis/state-signals/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/distributed-system-analysis/state-signals/actions/workflows/python-app.yml)\n\nA python package for handling state/event signals\n\nAdds two new, simple-to-use objects:\n - SignalExporter      (for publishing state signals and handling subscribers + responses)\n - SignalResponder     (for receiving state signals, locking onto publishers, and publishing responses)\n\nAlso provides two dataclass specifications:\n - Signal              (state signal protocol payload definition)\n - Response            (response protocol payload definition)\n\nCombining redis pubsub features with state signal + response protocols, \nthese additions make state signal publishing, subscribing, receiving, \nand responding incredibly easy to integrate into any python code.\n\nSee full documentation [here](https://distributed-system-analysis.github.io/state-signals/)\n\n# Installation\nThe state-signals PyPI package is available [here](https://pypi.org/project/state-signals)\n - To install, run `pip install state-signals`\n\nThere are also state-signals RPMs available:\n - For python 3.6, use `python36-state_signals`\n - For python 3.7 or later, use `python3-state_signals`\n - Both can be found [here](https://copr.fedorainfracloud.org/coprs/meyceoz/state-signals/builds/)\n\n# Requirements\nThe use of this module requires the existence of an accessible redis server.\n - Redis can easily be installed with a `yum install redis` (or replace yum with package manager of choice).\n - A redis container can also be started using the [official image](https://hub.docker.com/_/redis)\n\nA redis server can be started with the `redis-server` command.\n - The default port is 6379 (also default for state-signals), but can be changed with `--port (port)`\n - A config file can also be used for greater control/detail `redis-server \\path\\to\\config`\n - Example config available [here](https://download.redis.io/redis-stable/redis.conf)\n\nSee https://redis.io/ for more details and usage\n\nNote that state-signals also works with any redis-compatible pub/sub databases (like [KeyDB](https://github.com/Snapchat/KeyDB))\n\n# Protocol / Behaviors\n\nThe `Signal` and `Response` dataclasses define the exact fields/format of signal and response payloads.\n\nPublishing, receiving, and responding mechanisms are all detailed in `SignalExporter` and `SignalResponder` documentation. Below are details on the subscribing/awaiting protocol.\n\nAccept Subscribers and Awaiting Responses:\n - Using the `SignalExporter`, call an `exporter.initialize(legal_events, ...)`\n - Initialization will start the subscriber listener and establish legal event names\n - It will also publish an \"initialization\" state signal\n - Responders can then respond to the \"initialization\" signal to be added to the list of subs\n    - Note: A responder can subscribe at any point, unless a \"shutdown\" signal has been published after the initialization\n - The `SignalExporter` will now wait for (up until timeout) and read the responses of the subscribers after publishing any further signals with `exporter.publish_signal(event, ...)`\n - When finished, calling `exporter.shutdown(...)` will stop the subscriber listener, wipe the subscriber list, and publish a \"shutdown\" signal\n    - This signal publish will NOT listen for responses\n\nSending Responses\n - Receiving signals and sending responses can be done with the `SignalResponder`\n - To respond to a signal, simply use the `respond` method and pass in the `publisher_id` of the signal's publisher, and pass in the `event` being responded to.\n - (NEW IN v0.2.0) `srespond(signal, ...)`: A method where the user can simply pass in the received signal object they wish to respond to instead of the signal's id/event\n - Responding to an \"initialization\" signal will subscribe the responder to that specific publisher, which will now await responses from the responder for any future signals published.\n    - NOTE: When responding to an \"initialization\" signal, a Response-Action-Success (RAS) code is not necessary\n    - For any future responses to that publisher's signals, an RAS code will be necessary, and will indicate to the publisher whether or not the responder was successful in acting upon the signal\n    - See documentation for more details on RAS codes\n\nInitialization and Subscribing:\n![Initialization and Subscribing](imgs/signalsub.png)\n\nPublishing, Awaiting, and Responding:\n![Publishing, Awaiting, and Responding](imgs/awaitresp.png)\n\nSee the [full documentation](https://distributed-system-analysis.github.io/state-signals/) for further details, options, and more\n\n# Development\n\nFormatting\n - For formatting, get black v22.3.0 via `pip install black==22.3.0`\n - To check any modified python files, run `black --check (file)`\n - To check the entire repo, run `black --check .` from the top-level\n - To auto-format all python code, remove the `--check` option\n\nTesting\n - Testing is done with pytest\n - Run a `pip install` for `pytest` and `pytest-mock`\n - To run the tests, run `pytest -v` from the top-level\n - Any new test functions/scripts can be added into the `tests` folder\n - NOTE: You will need to run a local `redis-server` for the functional tests to pass\n\n Both formatting checks and tests must pass for GH Actions to approve a commit\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributed-system-analysis%2Fstate-signals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdistributed-system-analysis%2Fstate-signals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdistributed-system-analysis%2Fstate-signals/lists"}