Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install sphinx sphinx_rtd_theme myst_parser
Expand Down
15 changes: 11 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install dependencies
run: pip3 install --upgrade setuptools wheel twine
run: pip3 install --upgrade build twine

- name: Build package
run: python -m build

- name: Build and publish
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
python3 setup.py sdist bdist_wheel
twine upload --repository pypi dist/*
15 changes: 10 additions & 5 deletions .github/workflows/status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4

- name: Update pylint
run: pip3 install -U pylint
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Check pylint
run: pylint -rn --rcfile pylintrc nbtools
- name: Install ruff
run: pip3 install -U ruff

- name: Check ruff
run: ruff check nbtools
47 changes: 43 additions & 4 deletions .github/workflows/test-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.8, 3.9, '3.10', 3.11]
python-version: ['3.10', '3.11', '3.12']

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -47,13 +47,13 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.8, 3.9, '3.10', 3.11]
python-version: ['3.10', '3.11', '3.12']

runs-on: ${{ matrix.os }}

steps:
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -65,3 +65,42 @@ jobs:

- name: Run 'import nbtools'
run: python -c 'import nbtools'


# -----------------------------------------
# Install with uv
# -----------------------------------------
install_with_uv:

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12']

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@v2

- name: Install with uv
run: uv sync

- name: Test import with uv
run: uv run python -c 'import nbtools; print("nbtools version:", nbtools.__version__)'

- name: Test console scripts with uv
run: uv run nbstat --help

- name: Test optional dependencies with uv
run: |
uv sync --extra dev --extra nbrun
uv run python -c 'import ruff; print("ruff available")'
8 changes: 6 additions & 2 deletions nbtools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
""" Init file. """
#pylint: disable=wildcard-import
from importlib.metadata import PackageNotFoundError, version

from .core import *
from .exec_notebook import exec_notebook, run_notebook
from .pylint_notebook import pylint_notebook

__version__ = '0.9.14'
try:
__version__ = version("py-nbtools")
except PackageNotFoundError:
__version__ = "0.0.0" # e.g., running from a source tree
5 changes: 1 addition & 4 deletions nbtools/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
""" Core utility functions to work with Jupyter Notebooks. """
#pylint: disable=import-outside-toplevel
import os
import sys
import re
Expand Down Expand Up @@ -34,7 +33,6 @@ def get_notebook_path():

If run outside Jupyter notebook, returns None.
"""
#pylint: disable=missing-timeout
if not in_notebook():
return None

Expand Down Expand Up @@ -74,7 +72,7 @@ def get_notebook_name():

def notebook_to_script(path_script, path_notebook=None, ignore_markdown=True, return_info=False):
""" Convert a notebook to a script. """
import nbformat #pylint: disable=import-outside-toplevel
import nbformat
path_notebook = path_notebook or get_notebook_path()
if path_notebook is None:
raise ValueError('Provide path to Jupyter Notebook or run `notebook_to_script` inside of it!')
Expand Down Expand Up @@ -267,7 +265,6 @@ def set_gpus(n=1, min_free_memory=0.9, max_processes=2, verbose=False, raise_err
devices : list
Indices of selected and reserved GPUs.
"""
#pylint: disable=consider-iterating-dictionary
if 'CUDA_VISIBLE_DEVICES' in os.environ.keys():
str_devices = os.environ["CUDA_VISIBLE_DEVICES"]
warnings.warn(f'`CUDA_VISIBLE_DEVICES` is already set to "{str_devices}"!')
Expand Down
13 changes: 5 additions & 8 deletions nbtools/exec_notebook.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
""" Functions for running Jupyter Notebooks programmatically."""
#pylint: disable=import-outside-toplevel
import os
import time
import json
Expand All @@ -10,7 +9,7 @@
import psutil


TMP_DIR = '/tmp/nbtools_exec_notebook'
TMP_DIR = '/tmp/nbtools_exec_notebook' # noqa: S108
os.makedirs(TMP_DIR, exist_ok=True)


Expand All @@ -19,7 +18,6 @@ def run_in_process(func):
""" Decorator to run the ``func`` in a separate process for terminating all related processes properly. """
@wraps(func)
def _wrapper(*args, **kwargs):
# pylint: disable=broad-exception-caught, broad-exception-raised
_output_queue = Queue()
kwargs = {**kwargs, '_output_queue': _output_queue}

Expand All @@ -39,7 +37,7 @@ def _wrapper(*args, **kwargs):

output = _output_queue.get()
process.join()
except (KeyboardInterrupt, Exception) as e:
except (KeyboardInterrupt, Exception) as e: # noqa: BLE001
output = {'failed': True, 'traceback': e}

# Terminate all relevant processes when something went wrong, e.g. Keyboard Interrupt
Expand Down Expand Up @@ -245,7 +243,6 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
- ``'notebook'`` : :class:`nbformat.notebooknode.NotebookNode`, optional
Executed notebook object. Note that this output is provided only if ``return_notebook`` is ``True``.
"""
# pylint: disable=bare-except, lost-exception, return-in-finally
import nbformat
from jupyter_client.manager import KernelManager
from nbconvert.preprocessors import ExecutePreprocessor
Expand Down Expand Up @@ -321,7 +318,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
exec_failed = False
try:
executor.preprocess(notebook, {'metadata': {'path': working_dir}}, km=kernel_manager)
except:
except: # noqa: E722
exec_failed = True

# Save notebook outputs in the shelve db
Expand Down Expand Up @@ -359,7 +356,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
# Re-raise exception if needed
if raise_exception:
_output_queue.put(exec_res)
return None
return None # noqa: RET501
else:
exec_res = {'failed': failed, 'failed cell number': None, 'traceback': ''}

Expand Down Expand Up @@ -397,7 +394,7 @@ def exec_notebook(path, inputs=None, outputs=None, inputs_pos=1, replace_inputs_
exec_res['notebook'] = notebook

_output_queue.put(exec_res) # return for parent process
return None
return None # noqa: RET501

# Functions for database operations cells masking
def _display_inputs_reading(notebook, pos):
Expand Down
1 change: 0 additions & 1 deletion nbtools/nbstat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
""" NBstat module: monitoring running Python processes and Notebooks. """
#pylint: disable=wildcard-import
from .resource import Resource
from .resource_entry import ResourceEntry
from .resource_table import ResourceTable
Expand Down
10 changes: 4 additions & 6 deletions nbtools/nbstat/cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
""" Command line interface of `nbstat`.
Also provides `nbwatch`, `devicestat` and `devicewatch` functions.
"""
#pylint: disable=redefined-outer-name, too-many-nested-blocks
import sys
import traceback
from inspect import cleandoc
Expand All @@ -21,9 +20,9 @@ def main(name, interval=None):
""" Run command `name`. If `interval` is given, continuously output it to a terminal in fullscreen mode. """
# Attach SIGPIPE handler to properly handle broken pipe
try: # sigpipe not available under windows. just ignore in this case
import signal # pylint: disable=import-outside-toplevel
import signal # noqa: E402
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except Exception: # pylint: disable=broad-except
except Exception: # noqa: BLE001, S110
pass

# Make parameters for requested view
Expand Down Expand Up @@ -54,15 +53,14 @@ def output_once(inspector, name, formatter, view_args):
try:
view = inspector.get_view(name=name, formatter=formatter, **view_args)
print(view)
except Exception as e: # pylint: disable=broad-except
except Exception as e:
_ = e
print('Error on getting system information!' + str(e))
raise e

def output_looped(inspector, name, formatter, view_args,
other_name, other_formatter, other_view_args, interval=0.5):
""" Output visualization to a stdout once each `interval` seconds in a fullscreen mode. """
#pylint: disable=too-many-statements
terminal = Terminal()

initial_view_args = dict(view_args)
Expand Down Expand Up @@ -194,7 +192,7 @@ def output_looped(inspector, name, formatter, view_args,
else:
print(f'\nUnrecognized key={inkey}, code={inkey.code}.')

except Exception as e: # pylint: disable=broad-except
except Exception as e: # noqa: BLE001
sys.stderr.write(traceback.format_exc())
sys.stderr.write('Error on getting system information!')
sys.stderr.write(str(e))
Expand Down
1 change: 0 additions & 1 deletion nbtools/nbstat/resource_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def to_format_data(self, resource, terminal, **kwargs):
kwargs : dict
Other parameters for string creation like memory format, width, etc.
"""
#pylint: disable=too-many-statements
resource = Resource.parse_alias(resource)
default_string = '-'
style, string = None, None
Expand Down
5 changes: 2 additions & 3 deletions nbtools/nbstat/resource_inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
KERNEL_ID_SEARCHER = re.compile('kernel-(.*).json').search
VSCODE_KEY_SEARCHER = re.compile('key=b"(.*)"').search
SCRIPT_NAME_SEARCHER = re.compile('python.* (.*).py').search
RUN_NOTEBOOK_PATH_SEARCHER = re.compile('/tmp/.*.json.*--HistoryManager.hist_file=:memory:.*').search
RUN_NOTEBOOK_PATH_SEARCHER = re.compile('/tmp/.*.json.*--HistoryManager.hist_file=:memory:.*').search # noqa: S108


class ResourceInspector:
Expand Down Expand Up @@ -159,7 +159,6 @@ def get_notebook_table(self, formatter=None):

TODO: once VSCode has stable standard and doc for ipykernel launches, add its parsing here.
"""
#pylint: disable=import-outside-toplevel, missing-timeout
servers = []
try:
from notebook.notebookapp import list_running_servers as list_running_servers_v2
Expand Down Expand Up @@ -628,7 +627,7 @@ def make_terminal(self, force_styling, separator):
""" Create terminal instance. """
terminal = Terminal(kind=os.getenv('TERM'), force_styling=force_styling if force_styling else None)
terminal.separator_symbol = separator
terminal._normal = '\x1b[0;10m' # pylint: disable=protected-access
terminal._normal = '\x1b[0;10m' # noqa: SLF001

# Change some methods to a faster versions
# TODO: better measurements and tests for the same outputs
Expand Down
5 changes: 2 additions & 3 deletions nbtools/nbstat/resource_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class ResourceTable:
# TODO: can require `index` and/or `columns` at table creation, should we want so, for consistency
# TODO: can create a `PandasResourceTable` with the same API, but `pandas.DataFrame` under the hood
"""
#pylint: disable=self-cls-assignment
def __init__(self, data=None):
self._data = [] if data is None else [ResourceEntry(entry) for entry in data]

Expand Down Expand Up @@ -468,7 +467,7 @@ def format(self, terminal, formatter, hide_similar=True,
if hide_similar and hidable and i > 0:
style, string = '', ''

if False and i: # pylint: disable=condition-evals-to-constant
if False and i:
# TODO: aggregate info by using `aggregate` method
# for a given resource and create a ResourceEntry out of it to make style/string
remaining_table = subtable[1:]
Expand Down Expand Up @@ -536,5 +535,5 @@ def format(self, terminal, formatter, hide_similar=True,
# Pandas compatibility
def to_pd(self):
""" Convert the table to a `pandas.DataFrame`. """
import pandas as pd #pylint: disable=import-outside-toplevel
import pandas as pd
return pd.DataFrame(self.data)
5 changes: 2 additions & 3 deletions nbtools/nbstat/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
""" Utility functions. """
#pylint: disable=redefined-builtin
import re
import platform
import linecache
Expand All @@ -25,7 +24,7 @@ def pid_to_name_linux(pid):
try:
line = linecache.getline(f'/proc/{pid}/status', 1)
name = line.strip().split()[1]
except Exception: #pylint: disable=broad-except
except Exception: # noqa: BLE001
name = ''
return name

Expand All @@ -42,7 +41,7 @@ def pid_to_ngid_linux(pid):
line = linecache.getline(f'/proc/{pid}/status', 5)
ngid = line.strip().split()[1]
ngid = int(ngid)
except Exception: #pylint: disable=broad-except
except Exception: # noqa: BLE001
ngid = pid
return ngid or pid

Expand Down
Loading