{"id":13468754,"url":"https://github.com/pyeventsourcing/eventsourcing","last_synced_at":"2025-05-14T13:09:16.036Z","repository":{"id":39167367,"uuid":"41365202","full_name":"pyeventsourcing/eventsourcing","owner":"pyeventsourcing","description":"A library for event sourcing in Python.","archived":false,"fork":false,"pushed_at":"2025-05-10T00:33:01.000Z","size":10506,"stargazers_count":1540,"open_issues_count":4,"forks_count":133,"subscribers_count":37,"default_branch":"9.4","last_synced_at":"2025-05-10T01:27:33.825Z","etag":null,"topics":["cqrs","ddd","distributed-systems","django","domain-driven-design","event-sourcing","eventsourcing","python","python3","sqlalchemy"],"latest_commit_sha":null,"homepage":"https://eventsourcing.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pyeventsourcing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"pyeventsourcing"}},"created_at":"2015-08-25T13:35:28.000Z","updated_at":"2025-05-10T00:33:05.000Z","dependencies_parsed_at":"2024-02-07T16:25:21.984Z","dependency_job_id":"e49d3f38-10a4-47f3-b1aa-c76e2275d742","html_url":"https://github.com/pyeventsourcing/eventsourcing","commit_stats":{"total_commits":4402,"total_committers":28,"mean_commits":"157.21428571428572","dds":"0.028169014084507005","last_synced_commit":"23a0ced0baee80b4d57016537f54bc8b51701728"},"previous_names":["johnbywater/eventsourcing"],"tags_count":128,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyeventsourcing%2Feventsourcing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyeventsourcing%2Feventsourcing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyeventsourcing%2Feventsourcing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyeventsourcing%2Feventsourcing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyeventsourcing","download_url":"https://codeload.github.com/pyeventsourcing/eventsourcing/tar.gz/refs/heads/9.4","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253351686,"owners_count":21895021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cqrs","ddd","distributed-systems","django","domain-driven-design","event-sourcing","eventsourcing","python","python3","sqlalchemy"],"created_at":"2024-07-31T15:01:18.319Z","updated_at":"2025-05-14T13:09:10.985Z","avatar_url":"https://github.com/pyeventsourcing.png","language":"Python","funding_links":["https://github.com/sponsors/pyeventsourcing"],"categories":["Python"],"sub_categories":[],"readme":"[![Build Status](https://github.com/pyeventsourcing/eventsourcing/actions/workflows/runtests.yaml/badge.svg?branch=main)](https://github.com/pyeventsourcing/eventsourcing/tree/main)\n[![Coverage Status](https://coveralls.io/repos/github/pyeventsourcing/eventsourcing/badge.svg?branch=main)](https://coveralls.io/github/pyeventsourcing/eventsourcing?branch=main)\n[![Documentation Status](https://readthedocs.org/projects/eventsourcing/badge/?version=stable)](https://eventsourcing.readthedocs.io/en/stable/)\n[![Latest Release](https://badge.fury.io/py/eventsourcing.svg)](https://pypi.org/project/eventsourcing/)\n[![Downloads](https://static.pepy.tech/personalized-badge/eventsourcing?period=total\u0026units=international_system\u0026left_color=grey\u0026right_color=brightgreen\u0026left_text=downloads)](https://pypistats.org/packages/eventsourcing)\n[![Code Style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n\n# Event Sourcing in Python\n\nA library for event sourcing in Python.\n\n*\"totally amazing and a pleasure to use\"*\n\n*\"very clean and intuitive\"*\n\n*\"a huge help and time saver\"*\n\nPlease [read the docs](https://eventsourcing.readthedocs.io/). See also [extension projects](https://github.com/pyeventsourcing).\n\n\n## Installation\n\nUse pip to install the [stable distribution](https://pypi.org/project/eventsourcing/)\nfrom the Python Package Index.\n\n    $ pip install eventsourcing\n\nPlease note, it is recommended to install Python\npackages into a Python virtual environment.\n\n\n## Synopsis\n\nDefine aggregates with the `Aggregate` class and the `@event` decorator.\n\n```python\nfrom eventsourcing.domain import Aggregate, event\n\nclass Dog(Aggregate):\n    @event('Registered')\n    def __init__(self, name):\n        self.name = name\n        self.tricks = []\n\n    @event('TrickAdded')\n    def add_trick(self, trick):\n        self.tricks.append(trick)\n```\n\nDefine application objects with the `Application` class.\n\n```python\nfrom eventsourcing.application import Application\n\nclass DogSchool(Application):\n    def register_dog(self, name):\n        dog = Dog(name)\n        self.save(dog)\n        return dog.id\n\n    def add_trick(self, dog_id, trick):\n        dog = self.repository.get(dog_id)\n        dog.add_trick(trick)\n        self.save(dog)\n\n    def get_dog(self, dog_id):\n        dog = self.repository.get(dog_id)\n        return {'name': dog.name, 'tricks': tuple(dog.tricks)}\n```\n\nWrite a test.\n\n```python\ndef test_dog_school():\n    # Construct application object.\n    school = DogSchool()\n\n    # Evolve application state.\n    dog_id = school.register_dog('Fido')\n    school.add_trick(dog_id, 'roll over')\n    school.add_trick(dog_id, 'play dead')\n\n    # Query application state.\n    dog = school.get_dog(dog_id)\n    assert dog['name'] == 'Fido'\n    assert dog['tricks'] == ('roll over', 'play dead')\n\n    # Select notifications.\n    notifications = school.notification_log.select(start=1, limit=10)\n    assert len(notifications) == 3\n```\n\nRun the test with the default persistence module. Events are stored\nin memory using Python objects.\n\n```python\ntest_dog_school()\n```\n\nConfigure the application to run with an SQLite database. Other persistence modules are available.\n\n```python\nimport os\n\nos.environ[\"PERSISTENCE_MODULE\"] = 'eventsourcing.sqlite'\nos.environ[\"SQLITE_DBNAME\"] = 'dog-school.db'\n```\n\nRun the test with SQLite.\n\n```python\ntest_dog_school()\n```\n\nSee the [documentation](https://eventsourcing.readthedocs.io/) for more information.\n\n\n## Features\n\n**Aggregates and applications** — base classes for event-sourced aggregates\nand applications. Suggests how to structure an event-sourced application. All\nclasses are fully type-hinted to guide developers in using the library.\n\n**Flexible event store** — flexible persistence of aggregate events. Combines\nan event mapper and an event recorder in ways that can be easily extended.\nMapper uses a transcoder that can be easily extended to support custom\nmodel object types. Recorders supporting different databases can be easily\nsubstituted and configured with environment variables.\n\n**Application-level encryption and compression** — encrypts and decrypts events inside the\napplication. This means data will be encrypted in transit across a network (\"on the wire\")\nand at disk level including backups (\"at rest\"), which is a legal requirement in some\njurisdictions when dealing with personally identifiable information (PII) for example\nthe EU's GDPR. Compression reduces the size of stored aggregate events and snapshots, usually\nby around 25% to 50% of the original size. Compression reduces the size of data\nin the database and decreases transit time across a network.\n\n**Snapshotting** — reduces access-time for aggregates that have many events.\n\n**Versioning** - allows changes to be introduced after an application\nhas been deployed. Both aggregate events and aggregate snapshots can be versioned.\n\n**Optimistic concurrency control** — ensures a distributed or horizontally scaled\napplication doesn't become inconsistent due to concurrent method execution. Leverages\noptimistic concurrency controls in adapted database management systems.\n\n**Notifications and projections** — reliable propagation of application\nevents with pull-based notifications allows the application state to be\nprojected accurately into replicas, indexes, view models, and other applications.\nSupports materialized views and CQRS.\n\n**Event-driven systems** — reliable event processing. Event-driven systems\ncan be defined independently of particular persistence infrastructure and mode of\nrunning.\n\n**Detailed documentation** — documentation provides general overview, introduction\nof concepts, explanation of usage, and detailed descriptions of library classes.\nAll code is annotated with type hints.\n\n**Worked examples** — includes examples showing how to develop aggregates, applications\nand systems.\n\n\n## Extensions\n\nThe GitHub organisation\n[Event Sourcing in Python](https://github.com/pyeventsourcing)\nhosts extension projects for the Python eventsourcing library.\nThere are projects that adapt popular ORMs such as\n[Django](https://github.com/pyeventsourcing/eventsourcing-django#readme)\nand [SQLAlchemy](https://github.com/pyeventsourcing/eventsourcing-sqlalchemy#readme).\nThere are projects that adapt specialist event stores such as\n[Axon Server](https://github.com/pyeventsourcing/eventsourcing-axonserver#readme) and\n[EventStoreDB](https://github.com/pyeventsourcing/eventsourcing-eventstoredb#readme).\nThere are projects that support popular NoSQL databases such as\n[DynamoDB](https://github.com/pyeventsourcing/eventsourcing-dynamodb#readme).\nThere are also projects that provide examples of using the\nlibrary with web frameworks such as\n[FastAPI](https://github.com/pyeventsourcing/example-fastapi#readme)\nand [Flask](https://github.com/pyeventsourcing/example-flask#readme),\nand for serving applications and running systems with efficient\ninter-process communication technologies like [gRPC](https://github.com/pyeventsourcing/eventsourcing-grpc#readme).\nAnd there are examples of event-sourced applications and systems\nof event-sourced applications, such as the\n[Paxos system](https://github.com/pyeventsourcing/example-paxos#readme),\nwhich is used as the basis for a\n[replicated state machine](https://github.com/pyeventsourcing/example-paxos/tree/master/replicatedstatemachine),\nwhich is used as the basis for a\n[distributed key-value store](https://github.com/pyeventsourcing/example-paxos/tree/master/keyvaluestore).\n\n## Project\n\nThis project is [hosted on GitHub](https://github.com/pyeventsourcing/eventsourcing).\n\nPlease register questions, requests and\n[issues on GitHub](https://github.com/pyeventsourcing/eventsourcing/issues),\nor post in the project's Slack channel.\n\nThere is a [Slack channel](https://join.slack.com/t/eventsourcinginpython/shared_invite/zt-3hogb36o-LCvKd4Rz8JMALoLSl_pQ8g)\nfor this project, which you are [welcome to join](https://join.slack.com/t/eventsourcinginpython/shared_invite/zt-3hogb36o-LCvKd4Rz8JMALoLSl_pQ8g).\n\nPlease refer to the [documentation](https://eventsourcing.readthedocs.io/) for installation and usage guides.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyeventsourcing%2Feventsourcing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyeventsourcing%2Feventsourcing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyeventsourcing%2Feventsourcing/lists"}