diff --git a/libs/garf_io/garf_io/__init__.py b/libs/garf_io/garf_io/__init__.py index 8feb5d5..87dd28e 100644 --- a/libs/garf_io/garf_io/__init__.py +++ b/libs/garf_io/garf_io/__init__.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = '0.0.2' +__version__ = '0.0.3' diff --git a/libs/garf_io/garf_io/exceptions.py b/libs/garf_io/garf_io/exceptions.py new file mode 100644 index 0000000..be50c83 --- /dev/null +++ b/libs/garf_io/garf_io/exceptions.py @@ -0,0 +1,19 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Defines common library exceptions.""" + + +class GarfIoError(Exception): + """Base class for all library exceptions.""" diff --git a/libs/garf_io/garf_io/writer.py b/libs/garf_io/garf_io/writer.py index 50e029f..ec32b8b 100644 --- a/libs/garf_io/garf_io/writer.py +++ b/libs/garf_io/garf_io/writer.py @@ -15,11 +15,17 @@ from __future__ import annotations -from importlib import import_module +import inspect +from importlib.metadata import entry_points +from garf_io import exceptions from garf_io.writers import abs_writer +class GarfIoWriterError(exceptions.GarfIoError): + """Writer specific exception.""" + + def create_writer( writer_option: str, **kwargs: str ) -> type[abs_writer.AbsWriter]: @@ -35,22 +41,16 @@ def create_writer( Returns: Concrete instantiated writer. """ - if writer_option in ('bq', 'bigquery'): - writer_module = import_module('garf_io.writers.bigquery_writer') - return writer_module.BigQueryWriter(**kwargs) - if writer_option == 'sqldb': - writer_module = import_module('garf_io.writers.sqldb_writer') - return writer_module.SqlAlchemyWriter(**kwargs) - if writer_option in ('sheet', 'sheets'): - writer_module = import_module('garf_io.writers.sheets_writer') - return writer_module.SheetWriter(**kwargs) - if writer_option == 'console': - writer_module = import_module('garf_io.writers.console_writer') - return writer_module.ConsoleWriter(**kwargs) - if writer_option == 'csv': - writer_module = import_module('garf_io.writers.csv_writer') - return writer_module.CsvWriter(**kwargs) - if writer_option == 'json': - writer_module = import_module('garf_io.writers.json_writer') - return writer_module.JsonWriter(**kwargs) - return import_module('garf_io.writers.null_writer').NullWriter(writer_option) + writers = entry_points(group='garf_writer') + found_writers = {} + for writer in writers: + try: + writer_module = writer.load() + for name, obj in inspect.getmembers(writer_module): + if inspect.isclass(obj) and issubclass(obj, abs_writer.AbsWriter): + found_writers[writer.name] = getattr(writer_module, name) + except ModuleNotFoundError: + continue + if concrete_writer := found_writers.get(writer_option): + return concrete_writer(**kwargs) + raise GarfIoWriterError(f'{writer_option} is unknown writer type!') diff --git a/libs/garf_io/pyproject.toml b/libs/garf_io/pyproject.toml index c00e82f..c4eb73f 100644 --- a/libs/garf_io/pyproject.toml +++ b/libs/garf_io/pyproject.toml @@ -57,3 +57,12 @@ sheets = [ all = [ "garf-io[bq,sheets,sqlalchemy]" ] +[project.entry-points.garf_writer] +bq = "garf_io.writers.bigquery_writer" +bigquery = "garf_io.writers.bigquery_writer" +console = "garf_io.writers.console_writer" +csv = "garf_io.writers.csv_writer" +json = "garf_io.writers.json_writer" +sheet = "garf_io.writers.sheets_writer" +sheets = "garf_io.writers.sheets_writer" +sqldb = "garf_io.writers.sqldb_writer" diff --git a/libs/garf_io/tests/unit/test_writer.py b/libs/garf_io/tests/unit/test_writer.py index f275dfb..5f5be3b 100644 --- a/libs/garf_io/tests/unit/test_writer.py +++ b/libs/garf_io/tests/unit/test_writer.py @@ -56,5 +56,5 @@ def test_create_writer_returns_correct_fields_for_json_option(): def test_null_writer_raises_unknown_writer_error(): - with pytest.raises(ValueError): + with pytest.raises(writer.GarfIoWriterError): writer.create_writer('non-existing-option')