Skip to content

Commit

Permalink
Merge pull request #415 from Duncan-Hunter/main
Browse files Browse the repository at this point in the history
db optional dependency
  • Loading branch information
nnansters authored Sep 6, 2024
2 parents 0a35cf2 + 1fabe2b commit b614dec
Show file tree
Hide file tree
Showing 14 changed files with 1,852 additions and 1,434 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e '.[db]' --upgrade pip
pip install poetry tox tox-gh-actions
- name: test with tox
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

permissions:
contents: write
id-token: write

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
publish_dev_build:
Expand Down Expand Up @@ -50,9 +54,9 @@ jobs:
poetry build
- name: publish to Test PyPI
uses: pypa/gh-action-pypi-publish@master
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TEST_PYPI_API_TOKEN}}
repository_url: https://test.pypi.org/legacy/
skip_existing: true
skip-existing: true
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ENV POETRY_INSTALLER_MAX_WORKERS=10

# Install project in editable mode and with development dependencies
WORKDIR $APP_PATH
RUN poetry install
RUN poetry install --all-extras

ENTRYPOINT ["poetry", "run"]
CMD ["nml"]
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,21 @@ docker -v /local/config/dir/:/config/ run nannyml/nannyml nml run
python -m pip install git+https://github.com/NannyML/nannyml
```

#### Extras

If you're using database connections to read model inputs/outputs or you're exporting monitoring results to a database,
you'll need to include the optional `db` dependency. For example using `pip`:

```bash
pip install nannyml[db]
```

or using `poetry`

```bash
poetry install nannyml --all-extras
```

### Quick Start

_The following snippet is based on our [latest release](https://github.com/NannyML/nannyml/releases/latest)_.
Expand Down
15 changes: 15 additions & 0 deletions docs/installing_nannyml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ or

Any issues with installation? `Let us know`_ so we can help you.

Extras
------

If you're using database connections to read model inputs/outputs or you're exporting monitoring results to a database,
you'll need to include the optional `db` dependency. For example using `pip`:

.. code-block:: bash
$ pip install nannyml[db]
or using `poetry`

.. code-block:: bash
$ poetry install nannyml --all-extras
.. _`Let us know`: https://github.com/NannyML/nannyml/issues
.. _`LightGBM`: https://github.com/microsoft/LightGBM
Expand Down
3 changes: 3 additions & 0 deletions docs/tutorials/working_with_results.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ results to disk using a :class:`~nannyml.io.raw_files_writer.RawFilesWriter`, se
:class:`~nannyml.io.db.database_writer.DatabaseWriter`. This example will show how to use the
:class:`~nannyml.io.db.database_writer.DatabaseWriter`.

In order to get the dependencies required for database access, please ensure you've installed the
optional `db` dependency. Check the :ref:`installation instructions<installing_nannyml>` for more information.

We construct the :class:`~nannyml.io.db.database_writer.DatabaseWriter` by providing a database connection string.
Upon calling the :meth:`~nannyml.io.base.Writer.write` method, all results will be written into
the database, in this case, an `SQLite` database.
Expand Down
22 changes: 19 additions & 3 deletions nannyml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
# Dev branch marker is: 'X.Y.dev' or 'X.Y.devN' where N is an integer.
# 'X.Y.dev0' is the canonical version of 'X.Y.dev'
#
__version__ = '0.11.0'
__version__ = '0.12.0'

import logging

from dotenv import load_dotenv
from importlib import import_module


from .calibration import Calibrator, IsotonicCalibrator, needs_calibration
from .chunk import Chunk, Chunker, CountBasedChunker, DefaultChunker, PeriodBasedChunker, SizeBasedChunker
from .data_quality import MissingValuesCalculator, UnseenValuesCalculator, NumericalRangeCalculator
from .data_quality import MissingValuesCalculator, NumericalRangeCalculator, UnseenValuesCalculator
from .datasets import (
load_modified_california_housing_dataset,
load_synthetic_binary_classification_dataset,
Expand All @@ -59,7 +61,7 @@
UnivariateDriftCalculator,
)
from .exceptions import ChunkerException, InvalidArgumentsException, MissingMetadataException
from .io import DatabaseWriter, PickleFileWriter, RawFilesWriter
from .io import PickleFileWriter, RawFilesWriter
from .performance_calculation import PerformanceCalculator
from .performance_estimation import CBPE, DLE
from .stats import (
Expand All @@ -71,6 +73,20 @@
)
from .usage_logging import UsageEvent, disable_usage_logging, enable_usage_logging, log_usage


_optional_dependencies = {
'DatabaseWriter': '.io.db',
}


def __getattr__(name: str):
optional_module_path = _optional_dependencies.get(name)
if optional_module_path is not None:
module = import_module(optional_module_path, package=__name__)
return getattr(module, name)
raise AttributeError(f"module {__name__} has no attribute {name}")


try:
import nannyml_premium

Expand Down
16 changes: 15 additions & 1 deletion nannyml/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,27 @@
The `store` module implements an object cache, meant to cache fitted calculators in between runs.
"""
from importlib import import_module

from .base import Reader, Writer, WriterFactory
from .db import DatabaseWriter
from .file_reader import FileReader
from .file_writer import FileWriter
from .pickle_file_writer import PickleFileWriter
from .raw_files_writer import RawFilesWriter
from .store import FilesystemStore, JoblibPickleSerializer, Serializer, Store


_optional_dependencies = {
'DatabaseWriter': '.db'
}


def __getattr__(name):
optional_module_path = _optional_dependencies.get(name)
if optional_module_path is not None:
module = import_module(optional_module_path, package=__name__)
return getattr(module, name)
raise AttributeError(f"module {__name__} has no attribute {name}")


DEFAULT_WRITER = RawFilesWriter(path='out')
7 changes: 6 additions & 1 deletion nannyml/io/db/database_writer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from typing import Any, Dict, Optional

from sqlmodel import Session, SQLModel, create_engine, select
try:
from sqlmodel import Session, SQLModel, create_engine, select
except ImportError:
raise ImportError(
"`sqlmodel` module is not available. Please install the `nannyml[db]` extra to use this functionality."
)

from nannyml._typing import Result
from nannyml.exceptions import WriterException
Expand Down
9 changes: 7 additions & 2 deletions nannyml/io/db/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@
"""

import sys

from datetime import datetime
from typing import List, Optional

from pydantic import ConfigDict
from sqlmodel import Field, Relationship, SQLModel

try:
from sqlmodel import Field, Relationship, SQLModel
except ImportError:
raise ImportError(
"`sqlmodel` module is not available. Please install the `nannyml[db]` extra to use this functionality."
)


class Model(SQLModel, table=True): # type: ignore[call-arg]
Expand Down
Loading

0 comments on commit b614dec

Please sign in to comment.