{"id":15639654,"url":"https://github.com/timofurrer/observable","last_synced_at":"2025-07-09T12:44:50.361Z","repository":{"id":6847394,"uuid":"8096020","full_name":"timofurrer/observable","owner":"timofurrer","description":"minimalist event system for Python","archived":false,"fork":false,"pushed_at":"2020-01-19T22:57:18.000Z","size":152,"stargazers_count":85,"open_issues_count":4,"forks_count":13,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-02T12:53:42.060Z","etag":null,"topics":["event-emitter","event-handlers","events","minimalist","observer","python","simple"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timofurrer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-08T15:43:34.000Z","updated_at":"2024-08-16T15:35:38.000Z","dependencies_parsed_at":"2022-09-15T22:20:49.314Z","dependency_job_id":null,"html_url":"https://github.com/timofurrer/observable","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timofurrer%2Fobservable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timofurrer%2Fobservable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timofurrer%2Fobservable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timofurrer%2Fobservable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timofurrer","download_url":"https://codeload.github.com/timofurrer/observable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054193,"owners_count":21039952,"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":["event-emitter","event-handlers","events","minimalist","observer","python","simple"],"created_at":"2024-10-03T11:26:51.623Z","updated_at":"2025-04-09T14:14:46.618Z","avatar_url":"https://github.com/timofurrer.png","language":"Python","readme":"# observable\n\n[![Build Status](https://travis-ci.com/timofurrer/observable.svg?branch=master)](https://travis-ci.com/timofurrer/observable)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n\n**pyobservable** is a minimalist event system for python. It provides you an easy-to-use interface to trigger arbitrary functions when specific events occur.\n\n```python\nfrom observable import Observable\n\nobs = Observable()\n\n@obs.on(\"error\")\ndef error_handler(message):\n    # do some fancy error handling\n    logging.error(f\"An error occured: {message}\")\n\n...\n\ndef do_time_travel():\n    # do some time traveling\n    ...\n    if year != 1291:\n        obs.trigger(\"error\", \"Time travel to 1291 didn't work\")\n```\n\nAn ``ObservableProperty`` type is included as well, which makes observing\nobject properties a breeze.\n\n**Note:** We are Python 3 only! Only Python Versions \u003e= 3.5 are supported. Use [v0.3.2](https://pypi.org/project/observable/0.3.2/) for older Python Versions.\n\n\n## How to use\n\nUse a `pip` to install it from PyPI:\n\n    pip install observable\n\nAfter completion you can start using `observable`:\n\n```python\nfrom observable import Observable\n\nobs = Observable()\n```\n\n\n## Usage of ``observable.Observable``\n\n### `on`: Register event handler with `on`\nThere are two ways to register a function to an event.\u003cbr /\u003e\nThe first way is to register the event with a decorator like this:\n\n```python\n@obs.on(\"error\")\ndef error_func(message):\n    print(\"Error: %s\" % message)\n```\n\nThe second way is to register it with a method call:\n\n```python\ndef error_func(message):\n    print(\"Error: %s\" % message)\nobs.on(\"error\", error_func)\n```\n\n### `once`: Register event handler with `once`\n`once` works like `on`, but once the event handler is triggered it will be removed and cannot be triggered again.\n\n### `trigger`: trigger event\nYou can trigger a registered event with the `trigger` method:\n\n```python\nobs.trigger(\"error\", \"This is my error message\")\n```\n\nIf no handler for the event `error` could be found an `Observable.NoHandlerFound`-Exception will be raised.\n\n### `off`: remove handler and events\nRemove a handler from a specified event:\n\n```python\nobs.off(\"error\", error_func)\n```\n\n```python\nobs.off(\"error\", [error_func, second_error_func])\n```\n\nRemove all handlers from a specified event:\n\n```python\nobs.off(\"error\")\n```\n\nClear all events:\n\n```python\nobs.off()\n```\n\n### `get_all_handlers`, `get_handlers` and `is_registered`: Check which handlers are registered\nImagine you registered the following handlers:\n\n```python\n@obs.on(\"success\")\ndef success_func():\n    print(\"Success!\")\n\n@obs.on(\"error\")\ndef error_func(message):\n    print(\"Error: %s\" % message)\n```\n\nThen you can do the following to inspect the registered handlers:\n```python\n\u003e\u003e\u003e obs.get_all_handlers()\n{'success': [\u003cfunction success_func at 0x7f7f32d0a1e0\u003e], 'error': [\u003cfunction error_func at 0x7f7f32d0a268\u003e]}\n\u003e\u003e\u003e obs.get_handlers(\"success\")\n[\u003cfunction success_func at 0x7f7f32d0a1e0\u003e]\n\u003e\u003e\u003e obs.get_handlers(\"other_event\")\n[]\n```\n\n\n## Usage of ``observable.property.ObservableProperty``\n\nA property that can be observed easily by listening for some special,\nauto-generated events. Its API is identical to that of the build-in\n``property``.\n\nThe ``ObservableProperty`` needs an ``Observable`` object for\ntriggering events. If the property is an attribute of an object of\ntype ``Observable``, that one will be used automatically. To specify a\ndifferent ``Observable`` object, pass it as the ``observable`` keyword\nargument when initializing the ``ObservableProperty``. You may also pass\na string for ``observable``, which looks for an attribute of that\nname in the containing object. This is useful to specify the name of an\nattribute which will only be created at object initialization and thus\nisn't there when defining the property.\n\nThe following events, of which ``\"after_set_\u003cname\u003e\"`` is probably the\none used most, are triggered:\n\n* ``\"before_get_\u003cname\u003e\"()`` and ``\"after_get_\u003cname\u003e\"(value)``\n* ``\"before_set_\u003cname\u003e\"(value)`` and ``\"after_set_\u003cname\u003e\"(value)``\n* ``\"before_del_\u003cname\u003e\"()`` and ``\"after_del_\u003cname\u003e\"()``\n\n``\u003cname\u003e`` has to be replaced with the property's name. Note that names\nare taken from the individual functions supplied as getter, setter and\ndeleter, so please name those functions like the property itself.\nAlternatively, the name to use can be specified with the ``name``\nkeyword argument when initializing the ObservableProperty.\n\nThe convenience helper ``ObservableProperty.create_with()`` can be used\nas a decorator for creating ``ObservableProperty`` objects with custom\n``event`` and/or ``observable``. It returns a ``functools.partial()``\nwith the chosen attributes pre-set.\n\nHere's an example for using the ``event`` and ``observable`` keyword\narguments:\n\n```python\n\u003e\u003e\u003e from observable import Observable\n\u003e\u003e\u003e from observable.property import ObservableProperty\n\u003e\u003e\u003e class MyObject:\n...     def __init__(self):\n...         self.events = Observable()\n...         self._value = 10\n...     @ObservableProperty.create_with(event=\"prop\", observable=\"events\")\n...     def some_obscure_name(self):\n...         return self._value\n...     @some_obscure_name.setter\n...     def some_obscure_name(self, value):\n...         self._value += value\n...\n\u003e\u003e\u003e obj = MyObject()\n\u003e\u003e\u003e obj.obs.on(\"after_get_prop\", lambda v: print(\"got\", v))\n\u003e\u003e\u003e obj.obs.on(\"before_set_prop\",\n...            lambda v: print(\"setting\", obs.some_obscure_name, v))\n\u003e\u003e\u003e obj.obs.on(\"after_set_prop\", lambda v: print(\"set\", v))\n\u003e\u003e\u003e obj.some_obscure_name = 32\ngot 10\nsetting 10 32\nset 32\n\u003e\u003e\u003e obj.some_obscure_name\ngot 42\n42\n```\n\n\n***\n\n*\u003cp align=\"center\"\u003eThis project is published under [MIT](LICENSE).\u003cbr\u003eA [Timo Furrer](https://tuxtimo.me) project.\u003cbr\u003e- :tada: -\u003c/p\u003e*\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimofurrer%2Fobservable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimofurrer%2Fobservable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimofurrer%2Fobservable/lists"}