svc-reg


Namesvc-reg JSON
Version 23.3.0 PyPI version JSON
download
home_page
SummaryA Service Registry for Dependency Injection
upload_time2023-07-20 12:21:11
maintainer
docs_urlNone
author
requires_python>=3.8
license
keywords dependency injection
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# A Service Registry for Dependency Injection

> **Warning**
> ☠️ Not ready yet! ☠️
>
> This project is only public to [gather feedback](https://github.com/hynek/svc-reg/discussions), and everything can and will change until the project is proclaimed stable.
>
> Currently only [**Flask** support](#flask) is production-ready, but API details can still change.
>
> At this point, it's unclear whether this project will become a "proper Hynek project".
> I will keep using it for my work projects, but whether this will grow beyond my personal needs depends on community interest.

*svc-reg* is a [service locator](https://en.wikipedia.org/wiki/Service_locator_pattern) for Python that lets you register factories for types/interfaces and then imperatively request instances of those types with **automatic cleanup** and **health checks**.

**This allows you to configure and manage resources in *one central place* and access them all in a *consistent* way.**

In practice that means that at runtime, you say, for example, "*Give me a database connection*!", and *svc-reg* will give you whatever you've configured it to return when asked for a database connection.
This can be an actual database connection or it can be a mock object for testing.

If you like the [*Dependency Inversion Principle*](https://en.wikipedia.org/wiki/Dependency_inversion_principle) (aka "*program against interfaces, not implementations*"), you would register concrete factories for abstract interfaces[^abstract].

[^abstract]: In Python usually a [`Protocol`](https://docs.python.org/3/library/typing.html#typing.Protocol) or an [Abstract Base Class](https://docs.python.org/3.11/library/abc.html).

That:

- enables **dependency injection**,
- simplifies **testing**,
- unifies **cleanups**,
- and allows for **easy health** checks across *all* resources.

No global mutable state is necessary – but possible for extra comfort.

The goal is to minimize your business code to:

```python
def view(request):
    db = request.services.get(Database)
    api = request.services.get(WebAPIClient)
```

or even:

```python
def view():
    db = services.get(Database)
    api = services.get(WebAPIClient)
```

The latter already works with [Flask](#flask).

And you set it up like this:

```python
engine = create_engine("postgresql://localhost")

def engine_factory():
    with engine.connect() as conn:
        yield Database(conn)

registry = svc_reg.Registry()
registry.register_factory(Database, create_database)
```

The generator-based setup and cleanup may remind you of [Pytest fixtures](https://docs.pytest.org/en/stable/explanation/fixtures.html).

Unlike typical dependency injection that passes your dependencies as arguments, the active obtainment of resources by calling `get()` when you *know* you're going to need it avoids the conundrum of either having to pass a factory (e.g., a connection pool -- which also puts the onus of cleanup on you), or eagerly creating resources that are never used.

*svc-reg* comes with **full async** support via a-prefixed methods (i.e. `aget()` instead of `get()`, et cetera).

---

For now, please refer to the [GitHub README](https://github.com/hynek/svc-reg/blob/main/README.md) for latest documentation.


## Release Information

### Added

- Async method `Container.aget()`.
  This was necessary for generator-based cleanups.
  It works with sync factories too, so you can use it universally in async code.
- Async method `ServicePing.aping()`.
  It works with sync factories and pings too, so you can use it universally in async code.
  [#4](https://github.com/hynek/svc-reg/pull/4)


### Changed

- Switched the cleanup mechanism from passing a function to allowing the factory to be a generator that yields the resource and can clean up after the `yield`.
  Just like Pytest fixtures.
  [#3](https://github.com/hynek/svc-reg/pull/3)


---

[→ Full Changelog](https://github.com/hynek/svc-reg/blob/main/CHANGELOG.md)


## Credits

*svc-reg* is written by [Hynek Schlawack](https://hynek.me/) and distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.

The development is kindly supported by my employer [Variomedia AG](https://www.variomedia.de/) and all my amazing [GitHub Sponsors](https://github.com/sponsors/hynek).

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "svc-reg",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "dependency injection",
    "author": "",
    "author_email": "Hynek Schlawack <hs@ox.cx>",
    "download_url": "https://files.pythonhosted.org/packages/8a/75/fd0adfaf305144cc116aa2bdbf38a8842e654dc2c1b210ba54bc103d9162/svc_reg-23.3.0.tar.gz",
    "platform": null,
    "description": "\n# A Service Registry for Dependency Injection\n\n> **Warning**\n> \u2620\ufe0f Not ready yet! \u2620\ufe0f\n>\n> This project is only public to [gather feedback](https://github.com/hynek/svc-reg/discussions), and everything can and will change until the project is proclaimed stable.\n>\n> Currently only [**Flask** support](#flask) is production-ready, but API details can still change.\n>\n> At this point, it's unclear whether this project will become a \"proper Hynek project\".\n> I will keep using it for my work projects, but whether this will grow beyond my personal needs depends on community interest.\n\n*svc-reg* is a [service locator](https://en.wikipedia.org/wiki/Service_locator_pattern) for Python that lets you register factories for types/interfaces and then imperatively request instances of those types with **automatic cleanup** and **health checks**.\n\n**This allows you to configure and manage resources in *one central place* and access them all in a *consistent* way.**\n\nIn practice that means that at runtime, you say, for example, \"*Give me a database connection*!\", and *svc-reg* will give you whatever you've configured it to return when asked for a database connection.\nThis can be an actual database connection or it can be a mock object for testing.\n\nIf you like the [*Dependency Inversion Principle*](https://en.wikipedia.org/wiki/Dependency_inversion_principle) (aka \"*program against interfaces, not implementations*\"), you would register concrete factories for abstract interfaces[^abstract].\n\n[^abstract]: In Python usually a [`Protocol`](https://docs.python.org/3/library/typing.html#typing.Protocol) or an [Abstract Base Class](https://docs.python.org/3.11/library/abc.html).\n\nThat:\n\n- enables **dependency injection**,\n- simplifies **testing**,\n- unifies **cleanups**,\n- and allows for **easy health** checks across *all* resources.\n\nNo global mutable state is necessary \u2013 but possible for extra comfort.\n\nThe goal is to minimize your business code to:\n\n```python\ndef view(request):\n    db = request.services.get(Database)\n    api = request.services.get(WebAPIClient)\n```\n\nor even:\n\n```python\ndef view():\n    db = services.get(Database)\n    api = services.get(WebAPIClient)\n```\n\nThe latter already works with [Flask](#flask).\n\nAnd you set it up like this:\n\n```python\nengine = create_engine(\"postgresql://localhost\")\n\ndef engine_factory():\n    with engine.connect() as conn:\n        yield Database(conn)\n\nregistry = svc_reg.Registry()\nregistry.register_factory(Database, create_database)\n```\n\nThe generator-based setup and cleanup may remind you of [Pytest fixtures](https://docs.pytest.org/en/stable/explanation/fixtures.html).\n\nUnlike typical dependency injection that passes your dependencies as arguments, the active obtainment of resources by calling `get()` when you *know* you're going to need it avoids the conundrum of either having to pass a factory (e.g., a connection pool -- which also puts the onus of cleanup on you), or eagerly creating resources that are never used.\n\n*svc-reg* comes with **full async** support via a-prefixed methods (i.e. `aget()` instead of `get()`, et cetera).\n\n---\n\nFor now, please refer to the [GitHub README](https://github.com/hynek/svc-reg/blob/main/README.md) for latest documentation.\n\n\n## Release Information\n\n### Added\n\n- Async method `Container.aget()`.\n  This was necessary for generator-based cleanups.\n  It works with sync factories too, so you can use it universally in async code.\n- Async method `ServicePing.aping()`.\n  It works with sync factories and pings too, so you can use it universally in async code.\n  [#4](https://github.com/hynek/svc-reg/pull/4)\n\n\n### Changed\n\n- Switched the cleanup mechanism from passing a function to allowing the factory to be a generator that yields the resource and can clean up after the `yield`.\n  Just like Pytest fixtures.\n  [#3](https://github.com/hynek/svc-reg/pull/3)\n\n\n---\n\n[\u2192 Full Changelog](https://github.com/hynek/svc-reg/blob/main/CHANGELOG.md)\n\n\n## Credits\n\n*svc-reg* is written by [Hynek Schlawack](https://hynek.me/) and distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.\n\nThe development is kindly supported by my employer [Variomedia AG](https://www.variomedia.de/) and all my amazing [GitHub Sponsors](https://github.com/sponsors/hynek).\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A Service Registry for Dependency Injection",
    "version": "23.3.0",
    "project_urls": {
        "Changelog": "https://github.com/hynek/svc-reg/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/hynek/svc-reg/blob/main/README.md",
        "Funding": "https://github.com/sponsors/hynek",
        "Source": "https://github.com/hynek/svc-reg"
    },
    "split_keywords": [
        "dependency",
        "injection"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d4797c4fe13aa8ebe18d9b3679d16a453f07116963f4673f208df5b7705ff276",
                "md5": "8e6d1440c45be6f10f4876becce92f43",
                "sha256": "955eaaaf0b0dcfa8426b10151bc78f98774f786d035cd03846d7aaa0db850b56"
            },
            "downloads": -1,
            "filename": "svc_reg-23.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8e6d1440c45be6f10f4876becce92f43",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 7780,
            "upload_time": "2023-07-20T12:21:09",
            "upload_time_iso_8601": "2023-07-20T12:21:09.608423Z",
            "url": "https://files.pythonhosted.org/packages/d4/79/7c4fe13aa8ebe18d9b3679d16a453f07116963f4673f208df5b7705ff276/svc_reg-23.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8a75fd0adfaf305144cc116aa2bdbf38a8842e654dc2c1b210ba54bc103d9162",
                "md5": "9167d3164cb432c75f1d14a1388b0100",
                "sha256": "eea28e9878980e285c4efa743a65da85990616c26de6f0f4e3d7e9a7d75573db"
            },
            "downloads": -1,
            "filename": "svc_reg-23.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9167d3164cb432c75f1d14a1388b0100",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 21590,
            "upload_time": "2023-07-20T12:21:11",
            "upload_time_iso_8601": "2023-07-20T12:21:11.135968Z",
            "url": "https://files.pythonhosted.org/packages/8a/75/fd0adfaf305144cc116aa2bdbf38a8842e654dc2c1b210ba54bc103d9162/svc_reg-23.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-07-20 12:21:11",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "hynek",
    "github_project": "svc-reg",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "svc-reg"
}
        
Elapsed time: 0.08751s