From 4d12cfc27cd1292cdb682c9a6e320c280ddefd5d Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Fri, 3 May 2024 17:57:34 -0400 Subject: [PATCH] allow for missing kafka/websocket C++ adapters, enable future mmissing parquet adapter after cache cleanup Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> Raise hard import errors if trying to use adapters with missing dependencies, with helpful error messages. Remove runtime requirement on pandas Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> Remove superfluous checks Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> Add oldest supported numpy as runtime dep as well Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> fix spacing in action, dont depend on oldest-supported-numpy Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> --- .github/actions/setup-caches/action.yml | 6 +++--- csp/adapters/db.py | 7 +------ csp/adapters/kafka.py | 6 +++++- csp/adapters/parquet.py | 7 ++++++- csp/adapters/perspective.py | 6 +++--- csp/adapters/slack.py | 6 +----- csp/adapters/symphony.py | 6 +++++- csp/adapters/websocket.py | 12 +++++++++--- pyproject.toml | 5 ++--- 9 files changed, 35 insertions(+), 26 deletions(-) diff --git a/.github/actions/setup-caches/action.yml b/.github/actions/setup-caches/action.yml index 4fa38a489..ebbd36049 100644 --- a/.github/actions/setup-caches/action.yml +++ b/.github/actions/setup-caches/action.yml @@ -61,7 +61,7 @@ runs: /Users/runner/vcpkg_download_cache key: vcpkg-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('vcpkg.json') }} restore-keys: vcpkg-${{ runner.os }}-${{ runner.arch }}- - if: ${{ runner.os == 'macOS' && inputs.vcpkg == 'true'}} + if: ${{ runner.os == 'macOS' && inputs.vcpkg == 'true' }} - name: Setup vcpkg cache in shell (Windows) shell: bash @@ -70,7 +70,7 @@ runs: mkdir C:\\Users\\runneradmin\\AppData\\Local\\vcpkg_download_cache echo "VCPKG_DEFAULT_BINARY_CACHE=C:\\Users\\runneradmin\\AppData\\Local\\vcpkg_cache" >> $GITHUB_ENV echo "VCPKG_DOWNLOADS=C:\\Users\\runneradmin\\AppData\\Local\\vcpkg_download_cache" >> $GITHUB_ENV - if: ${{ runner.os == 'Windows' && inputs.vcpkg == 'true'}} + if: ${{ runner.os == 'Windows' && inputs.vcpkg == 'true' }} - name: Setup vcpkg cache (Windows) uses: actions/cache@v4 @@ -80,4 +80,4 @@ runs: C:\\Users\\runneradmin\\AppData\\Local\\vcpkg_download_cache key: vcpkg-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('vcpkg.json') }} restore-keys: vcpkg-${{ runner.os }}-${{ runner.arch }}- - if: ${{ runner.os == 'Windows' && inputs.vcpkg == 'true'}} + if: ${{ runner.os == 'Windows' && inputs.vcpkg == 'true' }} diff --git a/csp/adapters/db.py b/csp/adapters/db.py index 8316c1a67..49beb9060 100644 --- a/csp/adapters/db.py +++ b/csp/adapters/db.py @@ -25,11 +25,8 @@ _SQLALCHEMY_2 = False import sqlalchemy as db - - _HAS_SQLALCHEMY = True except (PackageNotFoundError, ValueError, TypeError, ImportError): - _HAS_SQLALCHEMY = False - db = None + raise ModuleNotFoundError("csp's db adapter requires `sqlalchemy`") class TimeAccessor(ABC): @@ -199,8 +196,6 @@ def __init__( :param log_query: set to True to see what query was generated to access the data :param use_raw_user_query: Don't do any alteration to user query, assume it contains all the needed columns and sorting """ - if not _HAS_SQLALCHEMY: - raise RuntimeError("Could not find SQLAlchemy installation") self._connection = connection self._table_name = table_name self._schema_name = schema_name diff --git a/csp/adapters/kafka.py b/csp/adapters/kafka.py index 6871004e3..595877aff 100644 --- a/csp/adapters/kafka.py +++ b/csp/adapters/kafka.py @@ -15,7 +15,11 @@ RawTextMessageMapper, ) from csp.impl.wiring import input_adapter_def, output_adapter_def, status_adapter_def -from csp.lib import _kafkaadapterimpl + +try: + from csp.lib import _kafkaadapterimpl +except ImportError: + raise ImportError("csp's kafka adapter requires the C++ csp extension to be built, but it could not be imported") _ = BytesMessageProtoMapper, DateTimeType, JSONTextMessageMapper, RawBytesMessageMapper, RawTextMessageMapper T = typing.TypeVar("T") diff --git a/csp/adapters/parquet.py b/csp/adapters/parquet.py index e88fcfeaa..bad8c5989 100644 --- a/csp/adapters/parquet.py +++ b/csp/adapters/parquet.py @@ -15,7 +15,12 @@ from csp.impl.types.typing_utils import CspTypingUtils from csp.impl.wiring import input_adapter_def, status_adapter_def from csp.impl.wiring.node import node -from csp.lib import _parquetadapterimpl + +try: + from csp.lib import _parquetadapterimpl +except ImportError: + raise ImportError("csp's parquet adapter requires the C++ csp extension to be built, but it could not be imported") + __all__ = [ "ParquetOutputConfig", diff --git a/csp/adapters/perspective.py b/csp/adapters/perspective.py index 0075b6015..da9bf0fe7 100644 --- a/csp/adapters/perspective.py +++ b/csp/adapters/perspective.py @@ -11,7 +11,7 @@ import tornado.web import tornado.websocket except ImportError: - raise ImportError("perspective adapter requires tornado package") + raise ModuleNotFoundError("csp's perspective adapter requires `tornado`") try: @@ -19,9 +19,9 @@ MAJOR, MINOR, PATCH = map(int, __version__.split(".")) if (MAJOR, MINOR, PATCH) < (0, 6, 2): - raise ImportError("perspective adapter requires 0.6.2 or greater of the perspective-python package") + raise ModuleNotFoundError("csp's perspective adapter requires `perspective-python>=0.6.2`") except ImportError: - raise ImportError("perspective adapter requires 0.6.2 or greater of the perspective-python package") + raise ModuleNotFoundError("csp's perspective adapter requires `perspective-python>=0.6.2`") # Run perspective update in a separate tornado loop diff --git a/csp/adapters/slack.py b/csp/adapters/slack.py index 70c5c047f..96ea8489e 100644 --- a/csp/adapters/slack.py +++ b/csp/adapters/slack.py @@ -20,10 +20,8 @@ from slack_sdk.socket_mode.request import SocketModeRequest from slack_sdk.socket_mode.response import SocketModeResponse from slack_sdk.web import WebClient - - _HAVE_SLACK_SDK = True except ImportError: - _HAVE_SLACK_SDK = False + raise ModuleNotFoundError("csp's slack adapter requires `slack-sdk`") T = TypeVar("T") log = getLogger(__file__) @@ -55,8 +53,6 @@ def mention_user(userid: str) -> str: class SlackAdapterManager(AdapterManagerImpl): def __init__(self, app_token: str, bot_token: str, ssl: Optional[SSLContext] = None): - if not _HAVE_SLACK_SDK: - raise RuntimeError("Could not find slack-sdk installation") if not app_token.startswith("xapp-") or not bot_token.startswith("xoxb-"): raise RuntimeError("Slack app token or bot token looks malformed") diff --git a/csp/adapters/symphony.py b/csp/adapters/symphony.py index 782d1008e..d2aead286 100644 --- a/csp/adapters/symphony.py +++ b/csp/adapters/symphony.py @@ -1,6 +1,5 @@ import http.client import json -import requests import ssl import threading from logging import getLogger @@ -14,6 +13,11 @@ from csp.impl.pushadapter import PushInputAdapter from csp.impl.wiring import py_push_adapter_def +try: + import requests +except ImportError: + raise ModuleNotFoundError("csp's symphony adapter requires `requests`") + __all__ = ["SymphonyAdapter", "SymphonyMessage"] log = getLogger(__file__) diff --git a/csp/adapters/websocket.py b/csp/adapters/websocket.py index e418088b9..335339a3c 100644 --- a/csp/adapters/websocket.py +++ b/csp/adapters/websocket.py @@ -20,7 +20,13 @@ ) from csp.impl.wiring import input_adapter_def, output_adapter_def, status_adapter_def from csp.impl.wiring.delayed_node import DelayedNodeWrapperDef -from csp.lib import _websocketadapterimpl + +try: + from csp.lib import _websocketadapterimpl +except ImportError: + raise ImportError( + "csp's websocket adapter requires the C++ csp extension to be built, but it could not be imported" + ) from .websocket_types import WebsocketHeaderUpdate @@ -39,14 +45,14 @@ import tornado.web import tornado.websocket except ImportError: - raise ImportError("websocket adapter requires tornado package") + raise ModuleNotFoundError("csp's websocket adapter requires `tornado`") try: import rapidjson datetime_mode = rapidjson.DM_UNIX_TIME | rapidjson.DM_NAIVE_IS_UTC except ImportError: - raise ImportError("websocket adapter requires rapidjson package") + raise ModuleNotFoundError("csp's websocket adapter requires `rapidjson`") def diff_dict(old, new): diff --git a/pyproject.toml b/pyproject.toml index 55ebed0f4..dead83bc0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,14 +19,12 @@ requires-python = ">=3.8" dependencies = [ "backports.zoneinfo; python_version<'3.9'", - "numpy", + "numpy>=1.19", "packaging", - "pandas", "psutil", "pyarrow>=7.0.0", "pytz", "ruamel.yaml", - "sqlalchemy", ] classifiers = [ @@ -75,6 +73,7 @@ develop = [ "pillow", # adapters "httpx>=0.20,<1", # kafka + "pandas", # pandas extension "polars", # parquet "psutil", # test_engine/test_history "slack-sdk>=3", # slack