Skip to content

Commit d6dd79d

Browse files
Copilot4n4nd
andcommitted
Make numpy import lazy in prometheus_connect.py
- Remove numpy import from module level in prometheus_connect.py - Add lazy import of numpy inside get_metric_aggregation method - Add tests to verify PrometheusConnect can be imported without loading pandas/matplotlib/numpy - All mocked network tests pass successfully Co-authored-by: 4n4nd <22333506+4n4nd@users.noreply.github.com>
1 parent 74b9105 commit d6dd79d

2 files changed

Lines changed: 102 additions & 1 deletion

File tree

prometheus_api_client/prometheus_connect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import os
55
import json
66
import logging
7-
import numpy
87
from datetime import datetime, timedelta
98
import requests
109
from requests.adapters import HTTPAdapter
@@ -569,6 +568,8 @@ def get_metric_aggregation(
569568
'max': 6.009373
570569
}
571570
"""
571+
import numpy
572+
572573
if not isinstance(operations, list):
573574
raise TypeError("Operations can be only of type list")
574575
if len(operations) == 0:

tests/test_lazy_imports.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""Test lazy imports to ensure pandas/matplotlib are not loaded unnecessarily."""
2+
import unittest
3+
import sys
4+
import importlib
5+
6+
7+
class TestLazyImports(unittest.TestCase):
8+
"""Test that PrometheusConnect can be imported without loading heavy dependencies."""
9+
10+
def test_prometheus_connect_import_without_pandas_matplotlib_numpy(self):
11+
"""Test that importing PrometheusConnect doesn't load pandas, matplotlib, or numpy."""
12+
# Remove any previously loaded prometheus_api_client modules
13+
modules_to_remove = [
14+
key for key in sys.modules.keys()
15+
if key.startswith('prometheus_api_client')
16+
]
17+
for module in modules_to_remove:
18+
del sys.modules[module]
19+
20+
# Also remove numpy, pandas, matplotlib if they were loaded
21+
for heavy_module in ['numpy', 'pandas', 'matplotlib']:
22+
modules_to_remove = [
23+
key for key in sys.modules.keys()
24+
if key == heavy_module or key.startswith(heavy_module + '.')
25+
]
26+
for module in modules_to_remove:
27+
del sys.modules[module]
28+
29+
# Import PrometheusConnect
30+
from prometheus_api_client import PrometheusConnect
31+
32+
# Check that pandas, matplotlib, and numpy are not loaded
33+
loaded_modules = sys.modules.keys()
34+
pandas_loaded = any('pandas' in m for m in loaded_modules)
35+
matplotlib_loaded = any('matplotlib' in m for m in loaded_modules)
36+
numpy_loaded = any('numpy' in m for m in loaded_modules)
37+
38+
self.assertFalse(pandas_loaded, "pandas should not be loaded when importing PrometheusConnect")
39+
self.assertFalse(matplotlib_loaded, "matplotlib should not be loaded when importing PrometheusConnect")
40+
self.assertFalse(numpy_loaded, "numpy should not be loaded when importing PrometheusConnect")
41+
42+
def test_prometheus_connect_instantiation_without_numpy(self):
43+
"""Test that PrometheusConnect can be instantiated without loading numpy."""
44+
# Remove any previously loaded prometheus_api_client modules
45+
modules_to_remove = [
46+
key for key in sys.modules.keys()
47+
if key.startswith('prometheus_api_client')
48+
]
49+
for module in modules_to_remove:
50+
del sys.modules[module]
51+
52+
# Also remove numpy if it was loaded
53+
modules_to_remove = [
54+
key for key in sys.modules.keys()
55+
if key == 'numpy' or key.startswith('numpy.')
56+
]
57+
for module in modules_to_remove:
58+
del sys.modules[module]
59+
60+
# Import and instantiate PrometheusConnect
61+
from prometheus_api_client import PrometheusConnect
62+
pc = PrometheusConnect(url='http://test.local:9090')
63+
64+
# Check that numpy is still not loaded after instantiation
65+
loaded_modules = sys.modules.keys()
66+
numpy_loaded = any('numpy' in m for m in loaded_modules)
67+
68+
self.assertFalse(numpy_loaded, "numpy should not be loaded when instantiating PrometheusConnect")
69+
self.assertIsNotNone(pc, "PrometheusConnect should be instantiated successfully")
70+
71+
def test_metric_import_loads_pandas(self):
72+
"""Test that importing Metric does load pandas (expected behavior)."""
73+
# Remove any previously loaded prometheus_api_client modules
74+
modules_to_remove = [
75+
key for key in sys.modules.keys()
76+
if key.startswith('prometheus_api_client')
77+
]
78+
for module in modules_to_remove:
79+
del sys.modules[module]
80+
81+
# Also remove pandas if it was loaded
82+
modules_to_remove = [
83+
key for key in sys.modules.keys()
84+
if key == 'pandas' or key.startswith('pandas.')
85+
]
86+
for module in modules_to_remove:
87+
del sys.modules[module]
88+
89+
# Import Metric
90+
from prometheus_api_client import Metric
91+
92+
# Check that pandas is loaded (this is expected for Metric)
93+
loaded_modules = sys.modules.keys()
94+
pandas_loaded = any('pandas' in m for m in loaded_modules)
95+
96+
self.assertTrue(pandas_loaded, "pandas should be loaded when importing Metric")
97+
98+
99+
if __name__ == '__main__':
100+
unittest.main()

0 commit comments

Comments
 (0)