-
-
Notifications
You must be signed in to change notification settings - Fork 90
Make pandas, numpy, and matplotlib optional dependencies with lazy loading and helpful error messages #309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
74b9105
d6dd79d
2447357
74f8772
33e0289
7832b91
b7f4b1e
08a7642
c02129e
1c8d53b
c2db4c4
cefc56c
abc430e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,18 @@ To install the latest release: | |
|
|
||
| `pip install prometheus-api-client` | ||
|
|
||
| To install with all optional dependencies (pandas, numpy, matplotlib): | ||
|
|
||
| `pip install prometheus-api-client[all]` | ||
|
|
||
| **Note:** Starting from version 0.6.0, pandas, numpy, and matplotlib are optional dependencies. | ||
| If you only need `PrometheusConnect` without DataFrame support or plotting capabilities, you can install the minimal version which significantly reduces memory footprint and installation time, especially on Alpine-based Docker images. | ||
|
|
||
| To install only specific extras: | ||
| - For DataFrame support: `pip install prometheus-api-client[dataframe]` | ||
| - For numpy support: `pip install prometheus-api-client[numpy]` | ||
| - For plotting support: `pip install prometheus-api-client[plot]` | ||
|
Comment on lines
21
to
24
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we consider making these installations use-case oriented instead of package oriented, e.g. something like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added use-case oriented |
||
|
|
||
| To install directly from this branch: | ||
|
|
||
| `pip install https://github.com/4n4nd/prometheus-api-client-python/zipball/master` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,6 @@ | |
| import os | ||
| import json | ||
| import logging | ||
| import numpy | ||
| from datetime import datetime, timedelta | ||
| import requests | ||
| from requests.adapters import HTTPAdapter | ||
|
|
@@ -569,6 +568,8 @@ def get_metric_aggregation( | |
| 'max': 6.009373 | ||
| } | ||
| """ | ||
| import numpy | ||
|
||
|
|
||
| if not isinstance(operations, list): | ||
| raise TypeError("Operations can be only of type list") | ||
| if len(operations) == 0: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| requests | ||
| dateparser |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| """Test lazy imports to ensure pandas/matplotlib are not loaded unnecessarily.""" | ||
| import unittest | ||
| import sys | ||
| import importlib | ||
4n4nd marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| class TestLazyImports(unittest.TestCase): | ||
| """Test that PrometheusConnect can be imported without loading heavy dependencies.""" | ||
|
|
||
| @staticmethod | ||
| def _remove_modules(module_names): | ||
| """Remove specified modules and their submodules from sys.modules. | ||
|
|
||
| Args: | ||
| module_names: List of module names to remove | ||
| """ | ||
| for module_name in module_names: | ||
| modules_to_remove = [ | ||
| key for key in sys.modules.keys() | ||
| if key == module_name or key.startswith(module_name + '.') | ||
| ] | ||
| for module in modules_to_remove: | ||
| del sys.modules[module] | ||
|
|
||
| @staticmethod | ||
| def _is_module_loaded(module_name): | ||
| """Check if a module is loaded in sys.modules. | ||
|
|
||
| Args: | ||
| module_name: Name of the module to check | ||
|
|
||
| Returns: | ||
| bool: True if module is loaded, False otherwise | ||
| """ | ||
| return any(m == module_name or m.startswith(module_name + '.') for m in sys.modules.keys()) | ||
|
|
||
| def test_prometheus_connect_import_without_pandas_matplotlib_numpy(self): | ||
| """Test that importing PrometheusConnect doesn't load pandas, matplotlib, or numpy.""" | ||
| # Remove any previously loaded modules | ||
| self._remove_modules(['prometheus_api_client', 'numpy', 'pandas', 'matplotlib']) | ||
|
|
||
| # Import PrometheusConnect | ||
| from prometheus_api_client import PrometheusConnect | ||
|
|
||
| # Check that pandas, matplotlib, and numpy are not loaded | ||
| self.assertFalse(self._is_module_loaded('pandas'), | ||
| "pandas should not be loaded when importing PrometheusConnect") | ||
| self.assertFalse(self._is_module_loaded('matplotlib'), | ||
| "matplotlib should not be loaded when importing PrometheusConnect") | ||
| self.assertFalse(self._is_module_loaded('numpy'), | ||
| "numpy should not be loaded when importing PrometheusConnect") | ||
|
|
||
| def test_prometheus_connect_instantiation_without_numpy(self): | ||
| """Test that PrometheusConnect can be instantiated without loading numpy.""" | ||
| # Remove any previously loaded modules | ||
| self._remove_modules(['prometheus_api_client', 'numpy']) | ||
|
|
||
| # Import and instantiate PrometheusConnect | ||
| from prometheus_api_client import PrometheusConnect | ||
| pc = PrometheusConnect(url='http://test.local:9090') | ||
|
|
||
| # Check that numpy is still not loaded after instantiation | ||
| self.assertFalse(self._is_module_loaded('numpy'), | ||
| "numpy should not be loaded when instantiating PrometheusConnect") | ||
| self.assertIsNotNone(pc, "PrometheusConnect should be instantiated successfully") | ||
|
|
||
| def test_metric_import_loads_pandas(self): | ||
| """Test that importing Metric does load pandas (expected behavior).""" | ||
| # Remove any previously loaded modules | ||
| self._remove_modules(['prometheus_api_client', 'pandas']) | ||
|
|
||
| # Import Metric | ||
| from prometheus_api_client import Metric | ||
|
|
||
| # Check that pandas is loaded (this is expected for Metric) | ||
| self.assertTrue(self._is_module_loaded('pandas'), | ||
| "pandas should be loaded when importing Metric") | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| unittest.main() | ||
Uh oh!
There was an error while loading. Please reload this page.