{"id":13700489,"url":"https://github.com/mosquito/cysystemd","last_synced_at":"2026-03-04T23:06:03.091Z","repository":{"id":10984469,"uuid":"66869380","full_name":"mosquito/cysystemd","owner":"mosquito","description":"systemd wrapper on Cython","archived":false,"fork":false,"pushed_at":"2025-07-14T17:04:40.000Z","size":193,"stargazers_count":112,"open_issues_count":2,"forks_count":24,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-02-11T17:36:26.602Z","etag":null,"topics":["cython","journald","python","python-2","python-3","python-3-5","python-3-6","systemd","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Cython","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mosquito.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-08-29T18:26:43.000Z","updated_at":"2026-01-23T13:32:21.000Z","dependencies_parsed_at":"2025-05-16T03:03:04.749Z","dependency_job_id":"0311e989-23dd-4275-a02e-811fb978ebf7","html_url":"https://github.com/mosquito/cysystemd","commit_stats":{"total_commits":134,"total_committers":16,"mean_commits":8.375,"dds":"0.18656716417910446","last_synced_commit":"f1a6f6b9bf10575f0b9cb4991bfd5fe6a3368e55"},"previous_names":["mosquito/python-systemd"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/mosquito/cysystemd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mosquito%2Fcysystemd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mosquito%2Fcysystemd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mosquito%2Fcysystemd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mosquito%2Fcysystemd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mosquito","download_url":"https://codeload.github.com/mosquito/cysystemd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mosquito%2Fcysystemd/sbom","scorecard":{"id":660962,"data":{"date":"2025-08-11","repo":{"name":"github.com/mosquito/cysystemd","commit":"36424aabd77e07c21a5528672a079a5d04c38e63"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","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":3,"reason":"Found 7/22 approved changesets -- score normalized to 3","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":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":"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":"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":"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":"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":"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: Apache License 2.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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.6.3 not signed: https://api.github.com/repos/mosquito/cysystemd/releases/194308866","Warn: release artifact 1.6.2 not signed: https://api.github.com/repos/mosquito/cysystemd/releases/157956302","Warn: release artifact 1.5.4 not signed: https://api.github.com/repos/mosquito/cysystemd/releases/108711345","Warn: release artifact 1.6.3 does not have provenance: https://api.github.com/repos/mosquito/cysystemd/releases/194308866","Warn: release artifact 1.6.2 does not have provenance: https://api.github.com/repos/mosquito/cysystemd/releases/157956302","Warn: release artifact 1.5.4 does not have provenance: https://api.github.com/repos/mosquito/cysystemd/releases/108711345"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 18 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-21T16:11:22.088Z","repository_id":10984469,"created_at":"2025-08-21T16:11:22.088Z","updated_at":"2025-08-21T16:11:22.088Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30098147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T22:49:54.894Z","status":"ssl_error","status_checked_at":"2026-03-04T22:49:48.883Z","response_time":59,"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":["cython","journald","python","python-2","python-3","python-3-5","python-3-6","systemd","wrapper"],"created_at":"2024-08-02T20:00:57.529Z","updated_at":"2026-03-04T23:06:03.071Z","avatar_url":"https://github.com/mosquito.png","language":"Cython","funding_links":[],"categories":["Cython"],"sub_categories":[],"readme":"![pypi version](https://img.shields.io/pypi/v/cysystemd.svg) ![](https://img.shields.io/pypi/pyversions/cysystemd.svg)  ![License](https://img.shields.io/pypi/l/cysystemd.svg)\n\n# systemd wrapper in Cython\n\nPython systemd wrapper using Cython.\n\n## Installation\n\n### About Binary Wheels Distribution\n\nHistorically, `cysystemd` was not distributed via wheels due to systemd versioning challenges.\nWhile the `libsystemd` headers remain relatively stable, the ABI can vary between different OS versions and\ndistributions.\nPrevious attempts to distribute wheels resulted in compatibility issues across different Linux systems.\nCurrently, we use the `manylinux_2_34` format for wheel distribution, which bundles the necessary shared objects\n(.so files) required for operation.\n\nThis approach should provide compatibility with modern systemd installations.\n\n**However, if you encounter any compatibility issues, we strongly recommend installing the package from\nsource code instead.**\n\n```bash\npip install --no-binary=:all: cysystemd\n```\n\n### Installation via Debian packages\n\nPre-built `.deb` packages are available for Debian/Ubuntu in the\n[GitHub Releases](https://github.com/mosquito/cysystemd/releases) page.\n\n### Installation from PyPI\n\nOnce the system dependencies are installed, you can install cysystemd:\n```shell\npip install cysystemd\n```\n\n### Installation from Source\n\n**You must install the systemd development headers (libsystemd) before installation!** Without these headers, the\ninstallation will fail.\n\nFor Debian/Ubuntu users:\n```shell\napt install build-essential libsystemd-dev\n```\n\nOn older versions of Debian/Ubuntu, you might also need:\n\n```shell\napt install libsystemd-daemon-dev libsystemd-journal-dev\n```\n\nFor CentOS/RHEL:\n```shell\nyum install gcc systemd-devel\n```\n\n# BREAKING CHANGES in v2.0.0\n\n## AsyncJournalReader Changes\n1. Major refactoring of the AsyncJournalReader iterator implementation:\n   * Removed internal queue and threading-based implementation\n   * Now uses direct async iteration through journal events\n   * More reliable handling of journal invalidation events\n   * Simpler and more efficient implementation\n\n2. `wait()` method now returns `JournalEvent` instead of boolean\n   * Returns specific event type (`JournalEvent.APPEND`, `JournalEvent.INVALIDATE`, `JournalEvent.NOP`)\n   * Better error handling and event processing\n\n## Type Annotations\n* Added comprehensive type hints throughout the codebase\n* Added return type annotations for all public methods\n* Enhanced IDE support and code documentation\n\n## API Behavior Changes\n* `seek_tail()` now automatically calls `previous()` to ensure cursor is positioned correctly\n* Improved error handling and validation in various methods\n* More consistent return types across the API\n\n## Python Support\n* Added support for Python 3.13\n* Maintained support for Python 3.8-3.12\n\n## Dependency Changes\n* Requires latest libsystemd development headers\n* Binary wheels are no longer distributed (see \"Why binary wheels are no longer distributed\" above)\n\nPlease ensure your code is updated to handle these changes when upgrading to version 2.0.0.\n\n## Usage examples\n\n### Writing to journald\n\n#### Logging handler for python logger\n\n```python\nfrom cysystemd import journal\nimport logging\nimport uuid\n\nlogging.basicConfig(level=logging.DEBUG)\nlogger = logging.getLogger()\nlogger.addHandler(journal.JournaldLogHandler())\n\ntry:\n    logger.info(\"Trying to do something\")\n    raise Exception('foo')\nexcept:\n    logger.exception(\"Test Exception %s\", 1)\n```\n\n#### systemd daemon notification\n\n\n```python\nfrom cysystemd.daemon import notify, Notification\n\n# Send READY=1\nnotify(Notification.READY)\n\n# Send status\nnotify(Notification.STATUS, \"I'm fine.\")\n\n# Send stopping\nnotify(Notification.STOPPING)\n```\n\nWrite message into systemd journal:\n\n```python\nfrom cysystemd import journal\n\n\njournal.write(\"Hello Lennart\")\n\n# Or send structured data\njournal.send(\n    message=\"Hello Lennart\",\n    priority=journal.Priority.INFO,\n    some_field='some value',\n)\n```\n\n### Reading journald\n\n#### Reading all systemd records\n\n```python\n\nfrom cysystemd.reader import JournalReader, JournalOpenMode\n\njournal_reader = JournalReader()\njournal_reader.open(JournalOpenMode.SYSTEM)\njournal_reader.seek_head()\n\nfor record in journal_reader:\n    print(record.data['MESSAGE'])\n```\n\n#### Read only cron logs\n\n```python\nfrom cysystemd.reader import JournalReader, JournalOpenMode, Rule\n\n\nrules = (\n  Rule(\"SYSLOG_IDENTIFIER\", \"CRON\") \u0026\n  Rule(\"_SYSTEMD_UNIT\", \"crond.service\") |\n  Rule(\"_SYSTEMD_UNIT\", \"cron.service\")\n)\n\ncron_reader = JournalReader()\ncron_reader.open(JournalOpenMode.SYSTEM)\ncron_reader.seek_head()\ncron_reader.add_filter(rules)\n\nfor record in cron_reader:\n    print(record.data['MESSAGE'])\n```\n\n#### Polling records\n\n```python\nfrom cysystemd.reader import JournalReader, JournalOpenMode\n\n\nreader = JournalReader()\nreader.open(JournalOpenMode.SYSTEM)\nreader.seek_tail()\n\npoll_timeout = 255\n\nwhile True:\n    reader.wait(poll_timeout)\n\n    for record in reader:\n       print(record.data['MESSAGE'])\n```\n\n#### journald open modes\n\n* `CURRENT_USER`\n* `LOCAL_ONLY`\n* `RUNTIME_ONLY`\n* `SYSTEM`\n* `SYSTEM_ONLY` - deprecated alias of `SYSTEM`\n\n\n```python\nfrom cysystemd.reader import JournalReader, JournalOpenMode\n\n\nreader = JournalReader()\nreader.open(JournalOpenMode.CURRENT_USER)\n```\n\n#### journald entry\n\nJournalEntry class has some special properties and methods:\n\n* `data` - journal entry content (`dict`)\n* `date` - entry timestamp (`datetime` instance)\n* `cursor` - systemd identification bytes for this entry\n* `boot_id()` - returns bootid\n* `get_realtime_sec()` - entry epoch (`float`)\n* `get_realtime_usec()` - entry epoch (`int` microseconds)\n* `get_monotonic_sec()` - entry monotonic time (`float`)\n* `get_monotonic_usec()` - entry monotonic time (`int` microseconds)\n* `__getitem__(key)` - shoutcut for `entry.data[key]`\n\n\n#### journald reader\n\nJournalReader class has some special properties and methods:\n\n* `open(flags=JournalOpenMode.CURRENT_USER)` - opening journald\n  with selected mode\n* `open_directory(path)` - opening journald from path\n* `open_files(*filename)` - opening journald from files\n* `data_threshold` - may be used to get or set the data field size threshold\n  for data returned by fething entry data.\n* `closed` - returns True when journal reader closed\n* `locked` - returns True when journal reader locked\n* `idle` - returns True when journal reader opened\n* `seek_head` - move reader pointer to the first entry\n* `seek_tail` - move reader pointer to the last entry\n* `seek_monotonic_usec` - seeks to the entry with the specified monotonic\n  timestamp, i.e. CLOCK_MONOTONIC. Since monotonic time restarts on every\n  reboot a boot ID needs to be specified as well.\n* `seek_realtime_usec` - seeks to the entry with the specified realtime\n  (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that the realtime clock\n  is not necessarily monotonic. If a realtime timestamp is ambiguous, it is\n  not defined which position is sought to.\n* `seek_cursor` - seeks to the entry located at the specified cursor\n  (see `JournalEntry.cursor`).\n* `wait(timeout)` - It will synchronously wait until the journal gets\n  changed. The maximum time this call sleeps may be controlled with the\n  timeout_usec parameter.\n* `__iter__` - returns JournalReader object\n* `__next__` - calls `next()` or raise `StopIteration`\n* `next(skip=0)` - returns the next `JournalEntry`. The `skip`\n  parameter skips some entries.\n* `previous(skip=0)` - returns the previous `JournalEntry`.\n  The `skip` parameter skips some entries.\n* `skip_next(skip)` - skips next entries.\n* `skip_previous(skip)` - skips next entries.\n* `add_filter(rule)` - adding filter rule.\n  See `read-only-cron-logs`_ as example.\n* `clear_filter` - reset all filters\n* `fd` - returns a special file descriptor\n* `events` - returns `EPOLL` events\n* `timeout` - returns internal timeout\n* `process_events()` - After each poll() wake-up process_events() needs\n  to be called to process events. This call will also indicate what kind of\n  change has been detected.\n* `get_catalog()` - retrieves a message catalog entry for the current\n  journal entry. This will look up an entry in the message catalog by using\n  the \"MESSAGE_ID=\" field of the current journal entry. Before returning\n  the entry all journal field names in the catalog entry text enclosed in\n  \"@\" will be replaced by the respective field values of the current entry.\n  If a field name referenced in the message catalog entry does not exist,\n  in the current journal entry, the \"@\" will be removed, but the field name\n  otherwise left untouched.\n* `get_catalog_for_message_id(message_id: UUID)` - works similar to\n  `get_catalog()` but the entry is looked up by the specified\n  message ID (no open journal context is necessary for this),\n  and no field substitution is performed.\n\n\n### Asyncio support\n\nInitial `asyncio` support for reading journal asynchronously.\n\n#### AsyncJournalReader\n\nBlocking methods were wrapped by threads.\nMethod `wait()` use epoll on journald file descriptor.\n\n```python\nimport asyncio\nimport json\n\nfrom cysystemd.reader import JournalOpenMode\nfrom cysystemd.async_reader import AsyncJournalReader\n\n\nasync def main():\n    reader = AsyncJournalReader()\n    await reader.open(JournalOpenMode.SYSTEM)\n    await reader.seek_tail()\n\n    async for record in reader:\n        print(json.dumps(record.data, indent=1, sort_keys=True))\n\nif __name__ == '__main__':\n    asyncio.run(main())\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmosquito%2Fcysystemd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmosquito%2Fcysystemd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmosquito%2Fcysystemd/lists"}