diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index 86a7b4c..f551be9 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -105,9 +105,6 @@ class AppHandler: self.providers = self.get_all_providers() return self.providers - # if 'providers' not in self.__dict__: - # self.__dict__['providers'] = self.get_all_providers() - for provider in self.providers.values(): if hasattr(provider, name): return getattr(provider, name) @@ -121,10 +118,22 @@ class AppHandler: Note that you do not need to call this directly; instead just use :attr:`providers`. + The discovery logic is based on :term:`entry points` using the ``wutta.app.providers`` group. For instance + here is a sample entry point used by WuttaWeb (in its + ``pyproject.toml``): + + .. code-block:: toml + + [project.entry-points."wutta.app.providers"] + wuttaweb = "wuttaweb.app:WebAppProvider" + :returns: Dictionary keyed by entry point name; values are - :class:`AppProvider` *instances*. + :class:`AppProvider` instances. """ - providers = load_entry_points(f'{self.appname}.providers') + # nb. must use 'wutta' and not self.appname prefix here, or + # else we can't find all providers with custom appname + providers = load_entry_points('wutta.app.providers') for key in list(providers): providers[key] = providers[key](self.config) return providers @@ -278,8 +287,7 @@ class AppProvider: These can add arbitrary extra functionality to the main :term:`app handler`. See also :doc:`/narr/providers/app`. - :param config: Config object for the app. This should be an - instance of :class:`~wuttjamaican.conf.WuttaConfig`. + :param config: The app :term:`config object`. Instances have the following attributes: @@ -301,7 +309,16 @@ class AppProvider: config = config.config self.config = config - self.app = config.get_app() + self.app = self.config.get_app() + + @property + def appname(self): + """ + The :term:`app name` for the current app. + + See also :attr:`AppHandler.appname`. + """ + return self.app.appname class GenericHandler: @@ -318,3 +335,12 @@ class GenericHandler: def __init__(self, config, **kwargs): self.config = config self.app = self.config.get_app() + + @property + def appname(self): + """ + The :term:`app name` for the current app. + + See also :attr:`AppHandler.appname`. + """ + return self.app.appname diff --git a/tests/test_app.py b/tests/test_app.py index 30adf72..ea1d4e4 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -134,6 +134,7 @@ class TestAppProvider(TestCase): provider = app.AppProvider(self.config) self.assertIs(provider.config, self.config) self.assertIs(provider.app, self.app) + self.assertEqual(provider.appname, 'wuttatest') # but can pass app handler instead with warnings.catch_warnings(): @@ -155,7 +156,7 @@ class TestAppProvider(TestCase): # sanity check, we get *instances* back from this providers = self.app.get_all_providers() - load_entry_points.assert_called_once_with('wuttatest.providers') + load_entry_points.assert_called_once_with('wutta.app.providers') self.assertEqual(len(providers), 1) self.assertIn('fake', providers) self.assertIsInstance(providers['fake'], FakeProvider) @@ -212,3 +213,4 @@ class TestGenericHandler(TestCase): handler = app.GenericHandler(self.config) self.assertIs(handler.config, self.config) self.assertIs(handler.app, self.app) + self.assertEqual(handler.appname, 'wuttatest')