Skip to content

Commit 306bd38

Browse files
authored
Merge pull request #143 from predict-idlab/linting
🎨 formatting + linting in CI-CD
2 parents 44b03d3 + 1452741 commit 306bd38

34 files changed

+467
-296
lines changed

.github/workflows/lint.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
with:
15+
lfs: true
16+
- name: Set up Python 3.10
17+
uses: actions/setup-python@v2
18+
with:
19+
python-version: '3.10'
20+
- name: Install Poetry
21+
uses: snok/install-poetry@v1
22+
- name: Cache poetry
23+
id: cached-poetry-dependencies
24+
uses: actions/cache@v2
25+
with:
26+
path: ~/.cache/pypoetry/virtualenvs
27+
key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }}-python-${{ matrix.python-version }}
28+
- run: poetry --version
29+
- name: Install dependencies
30+
run: poetry install
31+
# Do not use caching (anymore)
32+
# if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
33+
- name: Lint
34+
run: make lint

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
venv*
22
.cache_datasets/
3+
*.ruff*
34
*.DS_Store
45
file_system_store/
56

CONTRIBUTING.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,30 @@ poetry build # build the underlying C code
7979

8080
</details>
8181

82+
### Formatting the code
83+
84+
We use [black](https://github.com/psf/black) and [isort](https://github.com/PyCQA/isort) to format the code.
85+
86+
To format the code, run the following command (more details in the [Makefile](Makefile)):
87+
```sh
88+
make format
89+
```
90+
91+
### Checking the linting
92+
93+
We use [ruff](https://github.com/charliermarsh/ruff) to check the linting.
94+
95+
To check the linting, run the following command (more details in the [Makefile](Makefile)):
96+
```sh
97+
make lint
98+
```
99+
82100
### Running the tests (& code coverage)
83101

84-
You can run the test with the following code:
102+
You can run the tests with the following code (more details in the [Makefile](Makefile)):
85103

86104
```sh
87-
poetry run pytest --cov-report term-missing --cov=plotly_resampler tests
105+
make test
88106
```
89107

90108
To get the selenium tests working you should have Google Chrome installed.

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
black = black plotly_resampler examples tests
2+
isort = isort plotly_resampler examples tests
3+
4+
.PHONY: format
5+
format:
6+
$(isort)
7+
$(black)
8+
9+
.PHONY: lint
10+
lint:
11+
poetry run ruff plotly_resampler tests
12+
poetry run $(isort) --check-only --df
13+
poetry run $(black) --check --diff
14+
15+
.PHONY: test
16+
test:
17+
poetry run pytest --cov-report term-missing --cov=plotly_resampler tests
18+
19+
.PHONY: clean
20+
clean:
21+
rm -rf `find . -name __pycache__`
22+
rm -rf .cache
23+
rm -rf .pytest_cache
24+
rm -rf *.egg-info
25+
rm -f .coverage
26+
rm -rf build
27+
28+
rm -f `find . -type f -name '*.py[co]' `
29+
rm -f `find . -type f -name '*~' `
30+
rm -f `find . -type f -name '.*~' `
31+
rm -f `find . -type f -name '*.cpython-*' `

examples/dash_apps/01_minimal_global.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
import numpy as np
1717
import plotly.graph_objects as go
18-
from dash import Input, Output, dcc, html, Dash, no_update, callback_context
18+
from dash import Dash, Input, Output, callback_context, dcc, html, no_update
19+
from trace_updater import TraceUpdater
1920

2021
from plotly_resampler import FigureResampler
21-
from trace_updater import TraceUpdater
2222

2323
# Data that will be used for the plotly-resampler figures
2424
x = np.arange(2_000_000)
@@ -38,7 +38,6 @@
3838
html.H1("plotly-resampler global variable", style={"textAlign": "center"}),
3939
html.Button("plot chart", id="plot-button", n_clicks=0),
4040
html.Hr(),
41-
4241
# The graph and it's needed components to update efficiently
4342
dcc.Graph(id="graph-id"),
4443
TraceUpdater(id="trace-updater", gdID="graph-id"),
@@ -59,8 +58,8 @@ def plot_graph(n_clicks):
5958
# Note how the replace method is used here on the global figure object
6059
global fig
6160
fig.replace(go.Figure())
62-
fig.add_trace(go.Scattergl(name="log"), hf_x=x, hf_y=noisy_sin * .9999995 ** x)
63-
fig.add_trace(go.Scattergl(name="exp"), hf_x=x, hf_y=noisy_sin * 1.000002 ** x)
61+
fig.add_trace(go.Scattergl(name="log"), hf_x=x, hf_y=noisy_sin * 0.9999995**x)
62+
fig.add_trace(go.Scattergl(name="exp"), hf_x=x, hf_y=noisy_sin * 1.000002**x)
6463
return fig
6564
else:
6665
return no_update

examples/dash_apps/02_minimal_cache.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111

1212
import numpy as np
1313
import plotly.graph_objects as go
14-
from dash import Input, Output, State, dcc, html, no_update, callback_context
14+
from dash import Input, Output, State, callback_context, dcc, html, no_update
1515
from dash_extensions.enrich import (
1616
DashProxy,
1717
ServersideOutput,
1818
ServersideOutputTransform,
1919
)
20-
from plotly_resampler import FigureResampler
2120
from trace_updater import TraceUpdater
2221

22+
from plotly_resampler import FigureResampler
23+
2324
# Data that will be used for the plotly-resampler figures
2425
x = np.arange(2_000_000)
2526
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000

examples/dash_apps/03_minimal_cache_dynamic.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
1414
"""
1515

16-
from uuid import uuid4
1716
from typing import List
17+
from uuid import uuid4
1818

1919
import numpy as np
2020
import plotly.graph_objects as go
@@ -26,9 +26,10 @@
2626
Trigger,
2727
TriggerTransform,
2828
)
29-
from plotly_resampler import FigureResampler
3029
from trace_updater import TraceUpdater
3130

31+
from plotly_resampler import FigureResampler
32+
3233
# Data that will be used for the plotly-resampler figures
3334
x = np.arange(2_000_000)
3435
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000

examples/dash_apps/11_sine_generator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,21 @@
1414

1515
from uuid import uuid4
1616

17+
import dash_bootstrap_components as dbc
1718
import numpy as np
1819
import plotly.graph_objects as go
19-
import dash_bootstrap_components as dbc
20-
from dash import MATCH, Input, Output, State, dcc, html, no_update, callback_context
20+
from dash import MATCH, Input, Output, State, callback_context, dcc, html, no_update
2121
from dash_extensions.enrich import (
2222
DashProxy,
2323
ServersideOutput,
2424
ServersideOutputTransform,
2525
Trigger,
2626
TriggerTransform,
2727
)
28-
from plotly_resampler import FigureResampler
2928
from trace_updater import TraceUpdater
3029

30+
from plotly_resampler import FigureResampler
31+
3132
# --------------------------------------Globals ---------------------------------------
3233
app = DashProxy(
3334
__name__,

examples/dash_apps/12_file_selector.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@
1212

1313
import dash_bootstrap_components as dbc
1414
import plotly.graph_objects as go
15-
from dash import Input, Output, State, dcc, html, no_update, callback_context
16-
15+
from dash import Input, Output, State, callback_context, dcc, html, no_update
1716
from dash_extensions.enrich import (
1817
DashProxy,
1918
ServersideOutput,
2019
ServersideOutputTransform,
2120
)
22-
from plotly_resampler import FigureResampler
2321
from trace_updater import TraceUpdater
24-
25-
from utils.callback_helpers import multiple_folder_file_selector, get_selector_states
22+
from utils.callback_helpers import get_selector_states, multiple_folder_file_selector
2623
from utils.graph_construction import visualize_multiple_files
2724

25+
from plotly_resampler import FigureResampler
26+
2827
# --------------------------------------Globals ---------------------------------------
2928
app = DashProxy(
3029
__name__,

examples/dash_apps/13_coarse_fine.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,23 @@
1313

1414
__author__ = "Jonas Van Der Donckt"
1515

16-
import dash_bootstrap_components as dbc
17-
import plotly.graph_objects as go
1816
from pathlib import Path
1917
from typing import List
20-
from dash import Input, Output, State, dcc, html, no_update, callback_context
2118

19+
import dash_bootstrap_components as dbc
20+
import plotly.graph_objects as go
21+
from dash import Input, Output, State, callback_context, dcc, html, no_update
2222
from dash_extensions.enrich import (
2323
DashProxy,
2424
ServersideOutput,
2525
ServersideOutputTransform,
2626
)
27-
28-
from plotly_resampler import FigureResampler
2927
from trace_updater import TraceUpdater
30-
31-
from utils.callback_helpers import multiple_folder_file_selector, get_selector_states
28+
from utils.callback_helpers import get_selector_states, multiple_folder_file_selector
3229
from utils.graph_construction import visualize_multiple_files
3330

31+
from plotly_resampler import FigureResampler
32+
3433
# --------------------------------------Globals ---------------------------------------
3534
app = DashProxy(
3635
__name__,

examples/dash_apps/utils/callback_helpers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
__author__ = "Jonas Van Der Donckt"
55

6+
import itertools
67
from pathlib import Path
78
from typing import Dict, List
89

9-
import itertools
1010
import dash_bootstrap_components as dbc
1111
from dash import Input, Output, State, dcc, html
1212
from functional import seq
@@ -21,8 +21,8 @@ def _update_file_widget(folder):
2121
set(
2222
list(
2323
seq(Path(folder).iterdir())
24-
.filter(lambda x: x.is_file() and x.name.endswith("parquet"))
25-
.map(lambda x: x.name)
24+
.filter(lambda x: x.is_file() and x.name.endswith("parquet"))
25+
.map(lambda x: x.name)
2626
)
2727
)
2828
)
@@ -41,7 +41,7 @@ def _register_selection_callbacks(app, ids=None):
4141

4242

4343
def multiple_folder_file_selector(
44-
app, name_folders_list: List[Dict[str, dict]], multi=True
44+
app, name_folders_list: List[Dict[str, dict]], multi=True
4545
) -> dbc.Card:
4646
"""Constructs a folder user date selector
4747

examples/other_apps/streamlit_app.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,31 @@
1313

1414
__author__ = "Jeroen Van Der Donckt"
1515

16+
# 0. Create a noisy sine wave
17+
import numpy as np
1618
import plotly.graph_objects as go
19+
1720
from plotly_resampler import FigureResampler
1821

19-
# 0. Create a noisy sine wave
20-
import numpy as np
2122
x = np.arange(1_000_000)
2223
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
2324

2425
### 1. Use FigureResampler
2526
fig = FigureResampler(default_n_shown_samples=2_000)
26-
fig.add_trace(go.Scattergl(name='noisy sine', showlegend=True), hf_x=x, hf_y=noisy_sin)
27+
fig.add_trace(go.Scattergl(name="noisy sine", showlegend=True), hf_x=x, hf_y=noisy_sin)
2728
fig.update_layout(height=700)
2829

2930
### 2. Run the visualization (which is a dash app) in a (sub)process on a certain port
3031
# Note: starting a process allows executing code after `.show_dash` is called
3132
from multiprocessing import Process
33+
3234
port = 9022
33-
proc = Process(
34-
target=fig.show_dash, kwargs=dict(mode="external", port=port)
35-
).start()
35+
proc = Process(target=fig.show_dash, kwargs=dict(mode="external", port=port)).start()
3636

3737
# Deleting the lines below this and running this file will result in a classic running dash app
3838
# Note: for just a dash app it is not even necessary to execute .show_dash in a (sub)process
3939

4040
### 3. Add as iframe component to streamlit
4141
import streamlit.components.v1 as components
42-
components.iframe(f'http://localhost:{port}', height=700)
42+
43+
components.iframe(f"http://localhost:{port}", height=700)

plotly_resampler/aggregation/aggregation_interface.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ def __init__(
2929
irregularly sampled data. By default, True.
3030
nan_position: str, optional
3131
Indicates where nans must be placed when gaps are detected. \n
32-
If ``'end'``, the first point after a gap will be replaced with a
32+
If ``'end'``, the first point after a gap will be replaced with a
3333
nan-value \n
34-
If ``'begin'``, the last point before a gap will be replaced with a
34+
If ``'begin'``, the last point before a gap will be replaced with a
3535
nan-value \n
36-
If ``'both'``, both the encompassing gap datapoints are replaced with
36+
If ``'both'``, both the encompassing gap datapoints are replaced with
3737
nan-values \n
3838
.. note::
39-
This parameter only has an effect when ``interleave_gaps`` is set
39+
This parameter only has an effect when ``interleave_gaps`` is set
4040
to *True*.
4141
dtype_regex_list: List[str], optional
4242
List containing the regex matching the supported datatypes, by default None.

plotly_resampler/aggregation/aggregators.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from .algorithms.lttb_c import LTTB_core_c as LTTB_core
2222
except (ImportError, ModuleNotFoundError):
2323
import warnings
24+
2425
warnings.warn("Could not import lttbc; will use a (slower) python alternative.")
2526
from .algorithms.lttb_py import LTTB_core_py as LTTB_core
2627

@@ -286,7 +287,7 @@ def _aggregate(self, s: pd.Series, n_out: int) -> pd.Series:
286287
ratio_threshold = 100
287288

288289
# TODO -> test this with a move of the .so file
289-
if LTTB_core.__name__ == 'LTTB_core_py':
290+
if LTTB_core.__name__ == "LTTB_core_py":
290291
size_threshold = 1_000_000
291292

292293
if s.shape[0] > size_threshold and s.shape[0] / n_out > ratio_threshold:

plotly_resampler/aggregation/algorithms/lttb_c.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import numpy as np
5+
56
from .lttbc import (
67
downsample_double_double,
78
downsample_int_double,

plotly_resampler/figure_resampler/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from .figure_resampler import FigureResampler
1414
from .figurewidget_resampler import FigureWidgetResampler
1515

16-
1716
__all__ = [
1817
"FigureResampler",
1918
"FigureWidgetResampler",

plotly_resampler/figure_resampler/figure_resampler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
__author__ = "Jonas Van Der Donckt, Jeroen Van Der Donckt, Emiel Deprost"
1212

13+
import base64
14+
import uuid
1315
import warnings
14-
from typing import Tuple, List
16+
from typing import List, Tuple
1517

16-
import uuid
17-
import base64
1818
import dash
1919
import plotly.graph_objects as go
2020
from flask_cors import cross_origin

0 commit comments

Comments
 (0)