Skip to content

Commit f107563

Browse files
authored
Merge pull request #25 from yuvipanda/psutil_optional
Make psutil optional dependency of NBResuse
2 parents 2a7780d + 63117fb commit f107563

File tree

6 files changed

+58
-38
lines changed

6 files changed

+58
-38
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ var/
2323
*.egg-info/
2424
.installed.cfg
2525
*.egg
26+
*.ipynb

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ main toolbar in the notebook itself, refreshing every 5s.
2525
You can currently install this package from PyPI.
2626

2727
```bash
28-
pip install nbresuse
28+
pip install nbresuse[resources]
2929
```
3030

31+
The above command will install NBResuse along with `psutil` Python package (which is used for getting hardware usage information from the system). If you would like to install NBResuse _without_ `psutil` (in which case NBResuse does essentially nothing), run `pip install nbresuse` instead.
32+
3133
**If your notebook version is < 5.3**, you need to enable the extension manually.
3234

3335
```

nbresuse/metrics.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
from typing import NamedTuple
1+
from typing import NamedTuple, Optional
22

3-
import psutil
3+
try:
4+
import psutil
5+
except ImportError:
6+
psutil = None
47

58

69
class MemoryMetrics(NamedTuple):
@@ -13,30 +16,38 @@ class CPUMetrics(NamedTuple):
1316
cpu_usage: float
1417

1518

16-
def memory_metrics() -> MemoryMetrics:
17-
cur_process = psutil.Process()
18-
all_processes = [cur_process] + cur_process.children(recursive=True)
19+
def memory_metrics() -> Optional[MemoryMetrics]:
20+
if psutil:
21+
cur_process = psutil.Process()
22+
all_processes = [cur_process] + cur_process.children(recursive=True)
1923

20-
rss = sum([p.memory_info().rss for p in all_processes])
21-
virtual_memory = psutil.virtual_memory()
24+
rss = sum([p.memory_info().rss for p in all_processes])
25+
virtual_memory = psutil.virtual_memory().total
2226

23-
return MemoryMetrics(rss, virtual_memory.total)
27+
else:
28+
return None
2429

30+
return MemoryMetrics(rss, virtual_memory)
2531

26-
def cpu_metrics() -> CPUMetrics:
27-
cur_process = psutil.Process()
28-
all_processes = [cur_process] + cur_process.children(recursive=True)
2932

30-
cpu_count = psutil.cpu_count()
33+
def cpu_metrics() -> Optional[CPUMetrics]:
34+
if psutil:
35+
cur_process = psutil.Process()
36+
all_processes = [cur_process] + cur_process.children(recursive=True)
3137

32-
def get_cpu_percent(p):
33-
try:
34-
return p.cpu_percent(interval=0.05)
35-
# Avoid littering logs with stack traces complaining
36-
# about dead processes having no CPU usage
37-
except BaseException:
38-
return 0
38+
cpu_count = psutil.cpu_count()
3939

40-
cpu_percent = sum([get_cpu_percent(p) for p in all_processes])
40+
def get_cpu_percent(p):
41+
try:
42+
return p.cpu_percent(interval=0.05)
43+
# Avoid littering logs with stack traces complaining
44+
# about dead processes having no CPU usage
45+
except BaseException:
46+
return 0
47+
48+
cpu_percent = sum([get_cpu_percent(p) for p in all_processes])
49+
50+
else:
51+
return None
4152

4253
return CPUMetrics(cpu_count * 100.0, cpu_percent)

nbresuse/prometheus.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from notebook.notebookapp import NotebookApp
22
from prometheus_client import Gauge
33
from tornado import gen
4+
from typing import Optional
45

56
from nbresuse.metrics import cpu_metrics
67
from nbresuse.metrics import CPUMetrics
@@ -31,21 +32,25 @@ def __init__(self, nbapp: NotebookApp):
3132
@gen.coroutine
3233
def __call__(self, *args, **kwargs):
3334
metrics = self.apply_memory_limits(memory_metrics())
34-
TOTAL_MEMORY_USAGE.set(metrics.current_memory)
35-
MAX_MEMORY_USAGE.set(metrics.max_memory)
35+
if metrics is not None:
36+
TOTAL_MEMORY_USAGE.set(metrics.current_memory)
37+
MAX_MEMORY_USAGE.set(metrics.max_memory)
3638
if self.config.track_cpu_percent:
3739
metrics = self.apply_cpu_limits(cpu_metrics())
38-
TOTAL_CPU_USAGE.set(metrics.cpu_usage)
39-
MAX_CPU_USAGE.set(metrics.cpu_max)
40-
41-
def apply_memory_limits(self, metrics: MemoryMetrics) -> MemoryMetrics:
42-
if callable(self.config.mem_limit):
43-
metrics.max_memory = self.config.mem_limit(rss=metrics.max_memory)
44-
elif self.config.mem_limit > 0: # mem_limit is an Int
45-
metrics.max_memory = self.config.mem_limit
40+
if metrics is not None:
41+
TOTAL_CPU_USAGE.set(metrics.cpu_usage)
42+
MAX_CPU_USAGE.set(metrics.cpu_max)
43+
44+
def apply_memory_limits(self, metrics: Optional[MemoryMetrics]) -> Optional[MemoryMetrics]:
45+
if metrics is not None:
46+
if callable(self.config.mem_limit):
47+
metrics.max_memory = self.config.mem_limit(rss=metrics.max_memory)
48+
elif self.config.mem_limit > 0: # mem_limit is an Int
49+
metrics.max_memory = self.config.mem_limit
4650
return metrics
4751

48-
def apply_cpu_limits(self, metrics: CPUMetrics) -> CPUMetrics:
49-
if self.config.cpu_limit > 0:
50-
metrics.cpu_max = self.config.cpu_limit
52+
def apply_cpu_limits(self, metrics: Optional[CPUMetrics]) -> Optional[CPUMetrics]:
53+
if metrics is not None:
54+
if self.config.cpu_limit > 0:
55+
metrics.cpu_max = self.config.cpu_limit
5156
return metrics

nbresuse/static/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ define([
6161
let totalMemoryUsage = metric("total_memory_usage", data);
6262
let maxMemoryUsage = metric("max_memory_usage", data);
6363

64-
if (!totalMemoryUsage || !maxMemoryUsage)
64+
if (maxMemoryUsage[2] <= 0)
6565
return;
6666
totalMemoryUsage = humanFileSize(parseFloat(totalMemoryUsage[2]));
6767
maxMemoryUsage = humanFileSize(parseFloat(maxMemoryUsage[2]));

setup.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
setuptools.setup(
1313
name="nbresuse",
14-
version="0.3.3",
14+
version="0.3.4",
1515
url="https://github.com/yuvipanda/nbresuse",
1616
author="Yuvi Panda",
1717
description="Simple Jupyter extension to show how much resources (RAM) your notebook is using",
@@ -23,9 +23,10 @@
2323
"Programming Language :: Python :: 3",
2424
],
2525
packages=setuptools.find_packages(),
26-
install_requires=["psutil>=5.6.0", "notebook>=5.6.0"],
26+
install_requires=["notebook>=5.6.0", "prometheus_client"],
2727
extras_require={
28-
"dev": ["autopep8", "pytest", "flake8", "pytest-cov>=2.6.1", "mock"]
28+
"resources": ["psutil>=5.6.0"],
29+
"dev": ["autopep8", "pytest", "flake8", "pytest-cov>=2.6.1", "mock"],
2930
},
3031
data_files=[
3132
("share/jupyter/nbextensions/nbresuse", glob("nbresuse/static/*")),

0 commit comments

Comments
 (0)