Skip to content

🎨 formatting + linting in CI-CD #143

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

Merged
merged 5 commits into from
Dec 15, 2022
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
34 changes: 34 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Lint

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
lfs: true
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Cache poetry
id: cached-poetry-dependencies
uses: actions/cache@v2
with:
path: ~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }}-python-${{ matrix.python-version }}
- run: poetry --version
- name: Install dependencies
run: poetry install
# Do not use caching (anymore)
# if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
- name: Lint
run: make lint
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
venv*
.cache_datasets/
*.ruff*
*.DS_Store
file_system_store/

Expand Down
22 changes: 20 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,30 @@ poetry build # build the underlying C code

</details>

### Formatting the code

We use [black](https://github.com/psf/black) and [isort](https://github.com/PyCQA/isort) to format the code.

To format the code, run the following command (more details in the [Makefile](Makefile)):
```sh
make format
```

### Checking the linting

We use [ruff](https://github.com/charliermarsh/ruff) to check the linting.

To check the linting, run the following command (more details in the [Makefile](Makefile)):
```sh
make lint
```

### Running the tests (& code coverage)

You can run the test with the following code:
You can run the tests with the following code (more details in the [Makefile](Makefile)):

```sh
poetry run pytest --cov-report term-missing --cov=plotly_resampler tests
make test
```

To get the selenium tests working you should have Google Chrome installed.
Expand Down
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
black = black plotly_resampler examples tests
isort = isort plotly_resampler examples tests

.PHONY: format
format:
$(isort)
$(black)

.PHONY: lint
lint:
poetry run ruff plotly_resampler tests
poetry run $(isort) --check-only --df
poetry run $(black) --check --diff

.PHONY: test
test:
poetry run pytest --cov-report term-missing --cov=plotly_resampler tests

.PHONY: clean
clean:
rm -rf `find . -name __pycache__`
rm -rf .cache
rm -rf .pytest_cache
rm -rf *.egg-info
rm -f .coverage
rm -rf build

rm -f `find . -type f -name '*.py[co]' `
rm -f `find . -type f -name '*~' `
rm -f `find . -type f -name '.*~' `
rm -f `find . -type f -name '*.cpython-*' `
9 changes: 4 additions & 5 deletions examples/dash_apps/01_minimal_global.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

import numpy as np
import plotly.graph_objects as go
from dash import Input, Output, dcc, html, Dash, no_update, callback_context
from dash import Dash, Input, Output, callback_context, dcc, html, no_update
from trace_updater import TraceUpdater

from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

# Data that will be used for the plotly-resampler figures
x = np.arange(2_000_000)
Expand All @@ -38,7 +38,6 @@
html.H1("plotly-resampler global variable", style={"textAlign": "center"}),
html.Button("plot chart", id="plot-button", n_clicks=0),
html.Hr(),

# The graph and it's needed components to update efficiently
dcc.Graph(id="graph-id"),
TraceUpdater(id="trace-updater", gdID="graph-id"),
Expand All @@ -59,8 +58,8 @@ def plot_graph(n_clicks):
# Note how the replace method is used here on the global figure object
global fig
fig.replace(go.Figure())
fig.add_trace(go.Scattergl(name="log"), hf_x=x, hf_y=noisy_sin * .9999995 ** x)
fig.add_trace(go.Scattergl(name="exp"), hf_x=x, hf_y=noisy_sin * 1.000002 ** x)
fig.add_trace(go.Scattergl(name="log"), hf_x=x, hf_y=noisy_sin * 0.9999995**x)
fig.add_trace(go.Scattergl(name="exp"), hf_x=x, hf_y=noisy_sin * 1.000002**x)
return fig
else:
return no_update
Expand Down
5 changes: 3 additions & 2 deletions examples/dash_apps/02_minimal_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@

import numpy as np
import plotly.graph_objects as go
from dash import Input, Output, State, dcc, html, no_update, callback_context
from dash import Input, Output, State, callback_context, dcc, html, no_update
from dash_extensions.enrich import (
DashProxy,
ServersideOutput,
ServersideOutputTransform,
)
from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

from plotly_resampler import FigureResampler

# Data that will be used for the plotly-resampler figures
x = np.arange(2_000_000)
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
Expand Down
5 changes: 3 additions & 2 deletions examples/dash_apps/03_minimal_cache_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

"""

from uuid import uuid4
from typing import List
from uuid import uuid4

import numpy as np
import plotly.graph_objects as go
Expand All @@ -26,9 +26,10 @@
Trigger,
TriggerTransform,
)
from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

from plotly_resampler import FigureResampler

# Data that will be used for the plotly-resampler figures
x = np.arange(2_000_000)
noisy_sin = (3 + np.sin(x / 200) + np.random.randn(len(x)) / 10) * x / 1_000
Expand Down
7 changes: 4 additions & 3 deletions examples/dash_apps/11_sine_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@

from uuid import uuid4

import dash_bootstrap_components as dbc
import numpy as np
import plotly.graph_objects as go
import dash_bootstrap_components as dbc
from dash import MATCH, Input, Output, State, dcc, html, no_update, callback_context
from dash import MATCH, Input, Output, State, callback_context, dcc, html, no_update
from dash_extensions.enrich import (
DashProxy,
ServersideOutput,
ServersideOutputTransform,
Trigger,
TriggerTransform,
)
from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

from plotly_resampler import FigureResampler

# --------------------------------------Globals ---------------------------------------
app = DashProxy(
__name__,
Expand Down
9 changes: 4 additions & 5 deletions examples/dash_apps/12_file_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@

import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from dash import Input, Output, State, dcc, html, no_update, callback_context

from dash import Input, Output, State, callback_context, dcc, html, no_update
from dash_extensions.enrich import (
DashProxy,
ServersideOutput,
ServersideOutputTransform,
)
from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

from utils.callback_helpers import multiple_folder_file_selector, get_selector_states
from utils.callback_helpers import get_selector_states, multiple_folder_file_selector
from utils.graph_construction import visualize_multiple_files

from plotly_resampler import FigureResampler

# --------------------------------------Globals ---------------------------------------
app = DashProxy(
__name__,
Expand Down
13 changes: 6 additions & 7 deletions examples/dash_apps/13_coarse_fine.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,23 @@

__author__ = "Jonas Van Der Donckt"

import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from pathlib import Path
from typing import List
from dash import Input, Output, State, dcc, html, no_update, callback_context

import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from dash import Input, Output, State, callback_context, dcc, html, no_update
from dash_extensions.enrich import (
DashProxy,
ServersideOutput,
ServersideOutputTransform,
)

from plotly_resampler import FigureResampler
from trace_updater import TraceUpdater

from utils.callback_helpers import multiple_folder_file_selector, get_selector_states
from utils.callback_helpers import get_selector_states, multiple_folder_file_selector
from utils.graph_construction import visualize_multiple_files

from plotly_resampler import FigureResampler

# --------------------------------------Globals ---------------------------------------
app = DashProxy(
__name__,
Expand Down
8 changes: 4 additions & 4 deletions examples/dash_apps/utils/callback_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

__author__ = "Jonas Van Der Donckt"

import itertools
from pathlib import Path
from typing import Dict, List

import itertools
import dash_bootstrap_components as dbc
from dash import Input, Output, State, dcc, html
from functional import seq
Expand All @@ -21,8 +21,8 @@ def _update_file_widget(folder):
set(
list(
seq(Path(folder).iterdir())
.filter(lambda x: x.is_file() and x.name.endswith("parquet"))
.map(lambda x: x.name)
.filter(lambda x: x.is_file() and x.name.endswith("parquet"))
.map(lambda x: x.name)
)
)
)
Expand All @@ -41,7 +41,7 @@ def _register_selection_callbacks(app, ids=None):


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

Expand Down
15 changes: 8 additions & 7 deletions examples/other_apps/streamlit_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,31 @@

__author__ = "Jeroen Van Der Donckt"

# 0. Create a noisy sine wave
import numpy as np
import plotly.graph_objects as go

from plotly_resampler import FigureResampler

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

### 1. Use FigureResampler
fig = FigureResampler(default_n_shown_samples=2_000)
fig.add_trace(go.Scattergl(name='noisy sine', showlegend=True), hf_x=x, hf_y=noisy_sin)
fig.add_trace(go.Scattergl(name="noisy sine", showlegend=True), hf_x=x, hf_y=noisy_sin)
fig.update_layout(height=700)

### 2. Run the visualization (which is a dash app) in a (sub)process on a certain port
# Note: starting a process allows executing code after `.show_dash` is called
from multiprocessing import Process

port = 9022
proc = Process(
target=fig.show_dash, kwargs=dict(mode="external", port=port)
).start()
proc = Process(target=fig.show_dash, kwargs=dict(mode="external", port=port)).start()

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

### 3. Add as iframe component to streamlit
import streamlit.components.v1 as components
components.iframe(f'http://localhost:{port}', height=700)

components.iframe(f"http://localhost:{port}", height=700)
8 changes: 4 additions & 4 deletions plotly_resampler/aggregation/aggregation_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ def __init__(
irregularly sampled data. By default, True.
nan_position: str, optional
Indicates where nans must be placed when gaps are detected. \n
If ``'end'``, the first point after a gap will be replaced with a
If ``'end'``, the first point after a gap will be replaced with a
nan-value \n
If ``'begin'``, the last point before a gap will be replaced with a
If ``'begin'``, the last point before a gap will be replaced with a
nan-value \n
If ``'both'``, both the encompassing gap datapoints are replaced with
If ``'both'``, both the encompassing gap datapoints are replaced with
nan-values \n
.. note::
This parameter only has an effect when ``interleave_gaps`` is set
This parameter only has an effect when ``interleave_gaps`` is set
to *True*.
dtype_regex_list: List[str], optional
List containing the regex matching the supported datatypes, by default None.
Expand Down
3 changes: 2 additions & 1 deletion plotly_resampler/aggregation/aggregators.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .algorithms.lttb_c import LTTB_core_c as LTTB_core
except (ImportError, ModuleNotFoundError):
import warnings

warnings.warn("Could not import lttbc; will use a (slower) python alternative.")
from .algorithms.lttb_py import LTTB_core_py as LTTB_core

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

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

if s.shape[0] > size_threshold and s.shape[0] / n_out > ratio_threshold:
Expand Down
1 change: 1 addition & 0 deletions plotly_resampler/aggregation/algorithms/lttb_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import numpy as np

from .lttbc import (
downsample_double_double,
downsample_int_double,
Expand Down
1 change: 0 additions & 1 deletion plotly_resampler/figure_resampler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from .figure_resampler import FigureResampler
from .figurewidget_resampler import FigureWidgetResampler


__all__ = [
"FigureResampler",
"FigureWidgetResampler",
Expand Down
6 changes: 3 additions & 3 deletions plotly_resampler/figure_resampler/figure_resampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

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

import base64
import uuid
import warnings
from typing import Tuple, List
from typing import List, Tuple

import uuid
import base64
import dash
import plotly.graph_objects as go
from flask_cors import cross_origin
Expand Down
Loading