svcs

A Flexible Service Locator for Python.

MIT License

Downloads
9.1K
Stars
289

Bot releases are visible (Hide)

svcs - Latest Release

Published by hynek 9 months ago

Highlights

This is just a quick fix for a warning in AIOHTTP 3.9+.

Full changelog below!

Special Thanks

This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!

Above and Beyond

Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), Kevin P. Fleming (@kpfleming), and Sören Weber (@SoerenWeber).

Maintenance Sustainers

Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Mike Fiedler (@miketheman), and Michel Vittória (@michelvittoria).

Not to forget 5 more amazing humans who chose to be generous but anonymous!

Full Changelog

Fixed

  • AIOHTTP: The registry is now stored using aiohttp.web.AppKeys on the application. This is an implementation detail and shouldn't matter, but it fixes a warning on AIOHTTP 3.9 and later.
svcs -

Published by hynek 11 months ago

Highlights

The main feature of this release are container-local registries that allow you to define factories that are only valid for a container. For example, based on request metadata! Check out the docs for details.

There's one minor backward-incompatible change regarding the handling of values and context managers – please refer to https://github.com/hynek/svcs/discussions/50 for the reasons.

Finally there's a bunch of fixes around typing.

Special Thanks

This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!

Above and Beyond

Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).

Maintenance Sustainers

Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), and Mostafa Khalil (@khadrawy).

Not to forget 5 more amazing humans who chose to be generous but anonymous!

Full Changelog

Changed

  • Backwards-Incompatible: Since multiple people have been bit by the enter=True default for Registry.register_value(), and it's very early in svcs life, we're changing the default to enter=False for all versions of register_value().

    This means that you have to explicitly opt-in to context manager behavior which makes a lot more sense for singletons like connection pools which are the most common candidates for registered values.

    (The irony of shipping a backwards-incompatible change in the release directly following the adoption of a backwards-compatibility policy not lost on me.) #50 #51

Added

  • Container-local registries! Sometimes it's useful to bind a value or factory only to a container. For example, request metadata or authentication information.

    You can now achieve that with svcs.Container.register_local_factory() and svcs.Container.register_local_value(). Once something local is registered, a registry is transparently created and it takes precedence over the global one when a service is requested. The local registry is closed together with the container. #56

  • Flask: svcs.flask.registry which is a werkzeug.local.LocalProxy for the currently active registry on flask.current_app.

Fixed

  • We've stopped rewriting the public names of our objects and typing.get_type_hints() now works on them as expected for Python 3.10 and later. #52 #53

  • The detection of container arguments in svcs.Registry() when using string-based type annotations is more robust now. #55

svcs -

Published by hynek about 1 year ago

Highlights

I'm very proud to hereby announce the first stable version of svcs.

I'm both excited and anxious how it's going to be received.

Please give it a shot and let me know!

Special Thanks

This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!

Above and Beyond

Variomedia AG (@variomedia), Tidelift (@tidelift), Sentry (@getsentry), HiredScore (@HiredScore), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).

Maintenance Sustainers

Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), Stein Magnus Jodal (@jodal), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Tom Ballinger (@thomasballinger), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), and Stefan Hagen (@sthagen).

Not to forget 3 more amazing humans who chose to be generous but anonymous!

Full Changelog

Added

  • Backwards-compatibility! svcs is pronounced stable now -- no more rug-pulls planned! #36

  • Flask: svcs.flask.container which is a werkzeug.local.LocalProxy (like, for example, flask.current_app) and is the currently active container when accessed within a request context.

svcs -

Published by hynek about 1 year ago

Just internal re-jiggerings.

svcs -

Published by hynek about 1 year ago

With Starlette successfully added, I hope svcs is now feature-complete and won't need any bigger changes in the future.

I suspect it can be proclaimed stable soon, just when I realize how to market it…

Added

  • Flask: svcs.flask.get_registry().

  • Starlette integration. #31

svcs -

Published by hynek about 1 year ago

FastAPI integration has landed in #30!

svcs -

Published by hynek about 1 year ago

Added

  • enter keyword argument to all register_(value|factory)(). It prevents svcs from entering context managers if the factory returns one. This is useful for context managers like database transactions that you want to start manually.

  • Services acquired using aget() now also can receive the current container if they take one argument that is named svcs_container or that is annotated as being svcs.Container and has any name.

svcs -

Published by hynek about 1 year ago

Added

  • A ResourceWarning is now raised when a container or a registry are garbage-collected with pending cleanups.

Changed

  • Cleanups for services are internally context managers now. For your convenience, if you pass an (async) generator function for a factory, the registry will automatically wrap it for you into an (async) context manager. #92

  • Pyramid: svcs.pyramid.get() now takes a Pyramid request as the first argument. svcs.pyramid.get_pings() also doesn't look at thread locals anymore. If you still want to use thread locals, you can use svcs.pyramid.from_svcs(None) to obtain the currently active container.

  • Flask: replace_(value|factory)() is now called overwrite_(value|factory()) to be consistent with the docs lingo. They also completely reset the instantiation cache now (practically speaking: they close the container).

Removed

  • svcs.Container.forget_about(). It doesn't make any sense in a world of recursive dependencies. Just reset the container using svcs.Container.(a)close().
svcs -

Published by hynek about 1 year ago

Added

  • aiohttp: missing aget_abstract() function.
  • pyramid: missing get_pings() function.
svcs -

Published by hynek about 1 year ago

AIOHTTP integration has landed!

svcs -

Published by hynek about 1 year ago

Added

  • svcs now logs registrations at debug level along with a stacktrace. So if you ever get confused where your factories are coming from, set the log level to debug and trace your registrations!

Changed

  • Ooof. It's obvious in hindsight, but accessing anything directly on a request object like in the request.svcs.get() examples erases type information and everything becomes a big soup of Any.

    Therefore, we've added a new "best practice" for integrations to have a svcs_from() function that extracts containers from request objects (or from thread locals in the case of Flask).

svcs -

Published by hynek about 1 year ago

Changed

  • Factory results of None are now treated like every other result and cached. #22

  • Calling Container.get() on a service that has an async factory now raises a TypeError. #21

Added

  • API reference docs!

  • A huge glossary that should have been a book. #20

svcs -

Published by hynek about 1 year ago

Added

  • Proper documentation at https://svcs.hynek.me/!
    I guess it's getting serious.
    #17

  • Pyramid integration.

    Please note that not all integrations will be shipped with svcs proper once it is stable.
    Some will be moved to separate packages and Pyramid is a prime contender for that.

svcs - 23.9.0

Published by hynek about 1 year ago

This is a huge release as far as breaking changes go and I hope the last one of such sorts.

There has always been the conundrum imposed by Python typing whether we a) support automatic type-deduction of the services or b) support abstract classes (ABCs, Protocols).

After lots of waffling, I've gone for a compromise: Container.(a)get() are now properly typed as type[T] -> T (for up to 10 services at once 😅). If you want T to be abstract (until Python typing changes its stance), you'll have to use Container.(a)get_abstract(). The nice thing is that this separation serves more people and will be fully backwards-compatible, if we ever don't need it anymore.

Please see https://github.com/hynek/svcs#typing-caveats for more details and a more verbose explanation of the problem if you don't understand what any of the above means.

Full Changelog

Changed

  • Container.get() and Container.aget() now have type hints that only work with concrete classes but allow for type checking without repeating yourself.
    If you want to use abstract classes like typing.Protocol or ABCs, you can use Container.get_abstract() and Container.aget_abstract() instead.

Added

  • Container.get_abstract() and Container.aget_abstract().
    They behave like Container.get() and Container.aget() before.

  • It is now possible to check if a service type is registered with a Registry by using in.

  • It is now possible to check if a service type has a cached instance within a Container by using in.

  • Registry and Container are now also an (async) context managers that call close() / aclose() on exit automatically.

svcs - 23.8.0

Published by hynek about 1 year ago

Added

  • It's now possible to request multiple services at once by passing multiple types to Container.get() and Container.aget().
    #15
svcs - 23.7.0

Published by hynek about 1 year ago

Added

  • Factories now may take a parameter called svcs_container or that is annotated to be svcs.Container.
    In this case the factory will receive the current container as a first positional argument.
    This allows for recursive factories without global state.
    #10
svcs - 23.6.0

Published by hynek about 1 year ago

Warning Still in RFC mode!

Changed

  • Renamed Container.forget_service_type() to Container.forget_about().

Fixed

  • svcs.flask.init_app()'s type hints now take into account custom flask.Flask subclasses.
svcs - 23.5.0

Published by hynek about 1 year ago

Still, RFC-mode, added registry-level cleanups which allows to clean up pools automatically.

svcs - 23.4.0

Published by hynek about 1 year ago

The only difference is that we've rebranded ourselves to svcs which is easier to type and leaves back the "registry" baggage.

I'm still open to better names before we go official tho!

svcs - 23.3.0

Published by hynek about 1 year ago

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

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