Compare commits
	
		
			No commits in common. "a302f323afe6c27b42f53645b771e2d3f654bb50" and "ce79346f76c11d0473bcf7378d05870cef850b64" have entirely different histories.
		
	
	
		
			a302f323af
			...
			ce79346f76
		
	
		
					 3 changed files with 8 additions and 160 deletions
				
			
		|  | @ -182,9 +182,8 @@ Glossary | ||||||
|      The "session" is a SQLAlchemy abstraction for an open database |      The "session" is a SQLAlchemy abstraction for an open database | ||||||
|      connection, essentially. |      connection, essentially. | ||||||
| 
 | 
 | ||||||
|      For the :term:`app database`, the class used is |      In practice this generally refers to a | ||||||
|      :class:`~wuttjamaican.db.sess.Session`; other databases may use |      :class:`~wuttjamaican.db.sess.Session` instance. | ||||||
|      different classes. |  | ||||||
| 
 | 
 | ||||||
|    email handler |    email handler | ||||||
|       The :term:`handler` responsible for sending email on behalf of |       The :term:`handler` responsible for sending email on behalf of | ||||||
|  |  | ||||||
|  | @ -842,87 +842,6 @@ class AppHandler: | ||||||
|             self.handlers['auth'] = factory(self.config, **kwargs) |             self.handlers['auth'] = factory(self.config, **kwargs) | ||||||
|         return self.handlers['auth'] |         return self.handlers['auth'] | ||||||
| 
 | 
 | ||||||
|     def get_batch_handler(self, key, default=None, **kwargs): |  | ||||||
|         """ |  | ||||||
|         Get the configured :term:`batch handler` for the given type. |  | ||||||
| 
 |  | ||||||
|         :param key: Unique key designating the :term:`batch type`. |  | ||||||
| 
 |  | ||||||
|         :param default: Spec string to use as the default, if none is |  | ||||||
|            configured. |  | ||||||
| 
 |  | ||||||
|         :returns: :class:`~wuttjamaican.batch.BatchHandler` instance |  | ||||||
|            for the requested type.  If no spec can be determined, a |  | ||||||
|            ``KeyError`` is raised. |  | ||||||
|         """ |  | ||||||
|         spec = self.config.get(f'{self.appname}.batch.{key}.handler.spec', |  | ||||||
|                                default=default) |  | ||||||
|         if not spec: |  | ||||||
|             spec = self.config.get(f'{self.appname}.batch.{key}.handler.default_spec') |  | ||||||
|             if not spec: |  | ||||||
|                 raise KeyError(f"handler spec not found for batch key: {key}") |  | ||||||
|         factory = self.load_object(spec) |  | ||||||
|         return factory(self.config, **kwargs) |  | ||||||
| 
 |  | ||||||
|     def get_batch_handler_specs(self, key, default=None): |  | ||||||
|         """ |  | ||||||
|         Get the :term:`spec` strings for all available handlers of the |  | ||||||
|         given batch type. |  | ||||||
| 
 |  | ||||||
|         :param key: Unique key designating the :term:`batch type`. |  | ||||||
| 
 |  | ||||||
|         :param default: Default spec string(s) to include, even if not |  | ||||||
|            registered.  Can be a string or list of strings. |  | ||||||
| 
 |  | ||||||
|         :returns: List of batch handler spec strings. |  | ||||||
| 
 |  | ||||||
|         This will gather available spec strings from the following: |  | ||||||
| 
 |  | ||||||
|         First, the ``default`` as provided by caller. |  | ||||||
| 
 |  | ||||||
|         Second, the default spec from config, if set; for example: |  | ||||||
| 
 |  | ||||||
|         .. code-block:: ini |  | ||||||
| 
 |  | ||||||
|            [wutta.batch] |  | ||||||
|            inventory.handler.default_spec = poser.batch.inventory:InventoryBatchHandler |  | ||||||
| 
 |  | ||||||
|         Third, each spec registered via entry points.  For instance in |  | ||||||
|         ``pyproject.toml``: |  | ||||||
| 
 |  | ||||||
|         .. code-block:: toml |  | ||||||
| 
 |  | ||||||
|            [project.entry-points."wutta.batch.inventory"] |  | ||||||
|            poser = "poser.batch.inventory:InventoryBatchHandler" |  | ||||||
| 
 |  | ||||||
|         The final list will be "sorted" according to the above, with |  | ||||||
|         the latter registered handlers being sorted alphabetically. |  | ||||||
|         """ |  | ||||||
|         handlers = [] |  | ||||||
| 
 |  | ||||||
|         # defaults from caller |  | ||||||
|         if isinstance(default, str): |  | ||||||
|             handlers.append(default) |  | ||||||
|         elif default: |  | ||||||
|             handlers.extend(default) |  | ||||||
| 
 |  | ||||||
|         # configured default, if applicable |  | ||||||
|         default = self.config.get(f'{self.config.appname}.batch.{key}.handler.default_spec') |  | ||||||
|         if default and default not in handlers: |  | ||||||
|             handlers.append(default) |  | ||||||
| 
 |  | ||||||
|         # registered via entry points |  | ||||||
|         registered = [] |  | ||||||
|         for Handler in load_entry_points(f'{self.appname}.batch.{key}').values(): |  | ||||||
|             spec = Handler.get_spec() |  | ||||||
|             if spec not in handlers: |  | ||||||
|                 registered.append(spec) |  | ||||||
|         if registered: |  | ||||||
|             registered.sort() |  | ||||||
|             handlers.extend(registered) |  | ||||||
| 
 |  | ||||||
|         return handlers |  | ||||||
| 
 |  | ||||||
|     def get_db_handler(self, **kwargs): |     def get_db_handler(self, **kwargs): | ||||||
|         """ |         """ | ||||||
|         Get the configured :term:`db handler`. |         Get the configured :term:`db handler`. | ||||||
|  | @ -1102,10 +1021,3 @@ class GenericHandler: | ||||||
|         See also :attr:`AppHandler.appname`. |         See also :attr:`AppHandler.appname`. | ||||||
|         """ |         """ | ||||||
|         return self.app.appname |         return self.app.appname | ||||||
| 
 |  | ||||||
|     @classmethod |  | ||||||
|     def get_spec(cls): |  | ||||||
|         """ |  | ||||||
|         Returns the class :term:`spec` string for the handler. |  | ||||||
|         """ |  | ||||||
|         return f'{cls.__module__}:{cls.__name__}' |  | ||||||
|  |  | ||||||
|  | @ -19,15 +19,7 @@ from wuttjamaican import app as mod | ||||||
| from wuttjamaican.progress import ProgressBase | from wuttjamaican.progress import ProgressBase | ||||||
| from wuttjamaican.conf import WuttaConfig | from wuttjamaican.conf import WuttaConfig | ||||||
| from wuttjamaican.util import UNSPECIFIED | from wuttjamaican.util import UNSPECIFIED | ||||||
| from wuttjamaican.testing import FileTestCase, ConfigTestCase | from wuttjamaican.testing import FileTestCase | ||||||
| from wuttjamaican.batch import BatchHandler |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class MockBatchHandler(BatchHandler): |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| class AnotherBatchHandler(BatchHandler): |  | ||||||
|     pass |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestAppHandler(FileTestCase): | class TestAppHandler(FileTestCase): | ||||||
|  | @ -554,59 +546,6 @@ app_title = WuttaTest | ||||||
|         auth = self.app.get_auth_handler() |         auth = self.app.get_auth_handler() | ||||||
|         self.assertIsInstance(auth, AuthHandler) |         self.assertIsInstance(auth, AuthHandler) | ||||||
| 
 | 
 | ||||||
|     def test_get_batch_handler(self): |  | ||||||
| 
 |  | ||||||
|         # error if handler not found |  | ||||||
|         self.assertRaises(KeyError, self.app.get_batch_handler, 'CannotFindMe!') |  | ||||||
| 
 |  | ||||||
|         # caller can specify default |  | ||||||
|         handler = self.app.get_batch_handler('foo', default='wuttjamaican.batch:BatchHandler') |  | ||||||
|         self.assertIsInstance(handler, BatchHandler) |  | ||||||
| 
 |  | ||||||
|         # default can be configured |  | ||||||
|         self.config.setdefault('wuttatest.batch.foo.handler.default_spec', |  | ||||||
|                                'wuttjamaican.batch:BatchHandler') |  | ||||||
|         handler = self.app.get_batch_handler('foo') |  | ||||||
|         self.assertIsInstance(handler, BatchHandler) |  | ||||||
| 
 |  | ||||||
|         # preference can be configured |  | ||||||
|         self.config.setdefault('wuttatest.batch.foo.handler.spec', |  | ||||||
|                                'tests.test_app:MockBatchHandler') |  | ||||||
|         handler = self.app.get_batch_handler('foo') |  | ||||||
|         self.assertIsInstance(handler, MockBatchHandler) |  | ||||||
| 
 |  | ||||||
|     def test_get_batch_handler_specs(self): |  | ||||||
| 
 |  | ||||||
|         # empty by default |  | ||||||
|         specs = self.app.get_batch_handler_specs('foo') |  | ||||||
|         self.assertEqual(specs, []) |  | ||||||
| 
 |  | ||||||
|         # caller can specify default as string |  | ||||||
|         specs = self.app.get_batch_handler_specs('foo', default='wuttjamaican.batch:BatchHandler') |  | ||||||
|         self.assertEqual(specs, ['wuttjamaican.batch:BatchHandler']) |  | ||||||
| 
 |  | ||||||
|         # caller can specify default as list |  | ||||||
|         specs = self.app.get_batch_handler_specs('foo', default=['wuttjamaican.batch:BatchHandler', |  | ||||||
|                                                                  'tests.test_app:MockBatchHandler']) |  | ||||||
|         self.assertEqual(specs, ['wuttjamaican.batch:BatchHandler', |  | ||||||
|                                  'tests.test_app:MockBatchHandler']) |  | ||||||
| 
 |  | ||||||
|         # default can be configured |  | ||||||
|         self.config.setdefault('wuttatest.batch.foo.handler.default_spec', |  | ||||||
|                                'wuttjamaican.batch:BatchHandler') |  | ||||||
|         specs = self.app.get_batch_handler_specs('foo') |  | ||||||
|         self.assertEqual(specs, ['wuttjamaican.batch:BatchHandler']) |  | ||||||
| 
 |  | ||||||
|         # the rest come from entry points |  | ||||||
|         with patch.object(mod, 'load_entry_points', return_value={ |  | ||||||
|                 'mock': MockBatchHandler, |  | ||||||
|                 'another': AnotherBatchHandler, |  | ||||||
|         }): |  | ||||||
|             specs = self.app.get_batch_handler_specs('foo') |  | ||||||
|             self.assertEqual(specs, ['wuttjamaican.batch:BatchHandler', |  | ||||||
|                                      'tests.test_app:AnotherBatchHandler', |  | ||||||
|                                      'tests.test_app:MockBatchHandler']) |  | ||||||
| 
 |  | ||||||
|     def test_get_db_handler(self): |     def test_get_db_handler(self): | ||||||
|         try: |         try: | ||||||
|             from wuttjamaican.db.handler import DatabaseHandler |             from wuttjamaican.db.handler import DatabaseHandler | ||||||
|  | @ -745,17 +684,15 @@ class TestAppProvider(TestCase): | ||||||
|         self.assertEqual(self.app.foo_value, 'bar') |         self.assertEqual(self.app.foo_value, 'bar') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestGenericHandler(ConfigTestCase): | class TestGenericHandler(TestCase): | ||||||
| 
 | 
 | ||||||
|     def make_config(self, **kw): |     def setUp(self): | ||||||
|         kw.setdefault('appname', 'wuttatest') |         self.config = WuttaConfig(appname='wuttatest') | ||||||
|         return super().make_config(**kw) |         self.app = mod.AppHandler(self.config) | ||||||
|  |         self.config._app = self.app | ||||||
| 
 | 
 | ||||||
|     def test_constructor(self): |     def test_constructor(self): | ||||||
|         handler = mod.GenericHandler(self.config) |         handler = mod.GenericHandler(self.config) | ||||||
|         self.assertIs(handler.config, self.config) |         self.assertIs(handler.config, self.config) | ||||||
|         self.assertIs(handler.app, self.app) |         self.assertIs(handler.app, self.app) | ||||||
|         self.assertEqual(handler.appname, 'wuttatest') |         self.assertEqual(handler.appname, 'wuttatest') | ||||||
| 
 |  | ||||||
|     def test_get_spec(self): |  | ||||||
|         self.assertEqual(mod.GenericHandler.get_spec(), 'wuttjamaican.app:GenericHandler') |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue