Skip to content
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

Add contributing guide and Taskfile #219

Merged
merged 14 commits into from
Sep 28, 2024
19 changes: 19 additions & 0 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This workflow is used to run the pre-commit checks on the codebase, particularly
# linting and formatting.

name: Linting, formatting, and type checking

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/[email protected]
8 changes: 3 additions & 5 deletions .github/workflows/run_tests_each_PR.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# This workflow will install Python dependencies and run tests with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Run tests each PR
Expand All @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v3
Expand All @@ -33,10 +33,8 @@ jobs:
- name: Install python dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest pytest-playwright
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
pip install -r tests/requirements.txt
pip install -e .
- uses: pre-commit/[email protected]
- name: Install playwright dependencies
run: |
playwright install --with-deps
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,6 @@ package-lock.json

.streamlit/
.venv/
test-results.xml
test-results.xml

.task/
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repos:
hooks:
# Run the linter.
- id: ruff
args: [--fix]
args: [--fix, --unsafe-fixes]
randyzwitch marked this conversation as resolved.
Show resolved Hide resolved
# Run the formatter.
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
Expand Down
47 changes: 47 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Contributing to streamlit-folium

All of the necessary commands to get the project running are in the
[Taskfile](https://taskfile.dev/).

### Linting and formatting

We use [Ruff](https://github.com/astral-sh/ruff) for linting and formatting, and
[mypy](https://github.com/python/mypy) for type checking.

To run ruff and mypy, you can use the following command:

```bash
task lint
```

### Running tests

To run the tests, you can use the following command:

```bash
task test
```

### Adding tests

If you add a new feature, or fix a bug, please add a test to ensure that the feature works as expected.

The pattern for creating tests is to use the example streamlit app, and use
[playwright](https://playwright.dev/python/docs/intro) to create and
run tests on the app.

These tests are primarily located in the `tests/frontend.py` file.

If you are making a change that only affects the python code, you can
run the playwright [codegen](https://playwright.dev/python/docs/codegen) tool to
help generate the tests by running `task generate-tests`.

If you are making a change that affects the javascript code, you need to set up
folium to use your local frontend code. This can be done by:

1. Edit `streamlit_folium/__init__.py` to set `_RELEASE = False`
2. Run `task generate-tests-frontend`
3. Add tests as appropriate in `tests/frontend.py`
4. Run `task test-frontend` to run the tests
* Note that `test_release` will fail while `_RELEASE = False` -- this is expected
5. Set `_RELEASE = True` in `streamlit_folium/__init__.py` before opening a PR
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ Currently, there are two functions defined:
![streamlit_folium example](https://raw.githubusercontent.com/randyzwitch/streamlit-folium/master/tests/visual_baseline/test_basic/first_test/baseline.png)


## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
65 changes: 65 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
version: "3"

tasks:
install-pre-commit:
desc: Install pre-commit hooks
cmds:
- pip install pre-commit
- pre-commit install
sources:
- .pre-commit-config.yaml

install-package:
desc: Install the package
cmds:
- pip install -e .
sources:
- requirements.txt
- setup.py

install-test-deps:
desc: Install the dependencies for testing
cmds:
- pip install -r tests/requirements.txt
sources:
- tests/requirements.txt

lint:
desc: Run linting checks
deps:
- install-pre-commit
cmds:
- pre-commit run --all-files

test:
desc: Run all tests
deps:
- install-package
- install-test-deps
cmds:
- pytest

test-frontend:
cmds:
- task --parallel run-frontend test

run-frontend:
desc: Run the frontend for testing purposes
dir: streamlit_folium/frontend/
cmds:
- npm install
- npm run start

_run-streamlit: streamlit run examples/streamlit_app.py --server.port 8599 --server.headless true

_run-playwright: playwright codegen localhost:8599 --target=python-pytest

generate-tests:
desc: Generate tests for the frontend
cmds:
- task --parallel _run-streamlit _run-playwright

generate-tests-frontend:
desc: Generate tests for the frontend
cmds:
- task --parallel run-frontend _run-streamlit _run-playwright
4 changes: 2 additions & 2 deletions examples/pages/dynamic_layer_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
"dashArray": "5, 5",
}

polygon_folium1 = folium.GeoJson(data=gdf1, style_function=lambda x: style_parcels)
polygon_folium2 = folium.GeoJson(data=gdf2, style_function=lambda x: style_buildings)
polygon_folium1 = folium.GeoJson(data=gdf1, style_function=lambda _x: style_parcels)
randyzwitch marked this conversation as resolved.
Show resolved Hide resolved
polygon_folium2 = folium.GeoJson(data=gdf2, style_function=lambda _x: style_buildings)

map = folium.Map(
location=START_LOCATION,
Expand Down
17 changes: 8 additions & 9 deletions examples/pages/dynamic_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@
@st.cache_data
def _get_all_state_bounds() -> dict:
url = "https://raw.githubusercontent.com/PublicaMundi/MappingAPI/master/data/geojson/us-states.json"
data = requests.get(url).json()
return data
return requests.get(url).json()


@st.cache_data
def get_state_bounds(state: str) -> dict:
data = _get_all_state_bounds()
state_entry = [f for f in data["features"] if f["properties"]["name"] == state][0]
state_entry = next(f for f in data["features"] if f["properties"]["name"] == state)
return {"type": "FeatureCollection", "features": [state_entry]}


Expand Down Expand Up @@ -109,8 +108,8 @@ def main():

st.write("## Dynamic feature group updates")

START_LOCATION = [37.7944347109497, -122.398077892527]
START_ZOOM = 17
start_location = [37.7944347109497, -122.398077892527]
start_zoom = 17

if "feature_group" not in st.session_state:
st.session_state["feature_group"] = None
Expand Down Expand Up @@ -146,14 +145,14 @@ def main():
"dashArray": "5, 5",
}

polygon_folium1 = folium.GeoJson(data=gdf1, style_function=lambda x: style_parcels)
polygon_folium1 = folium.GeoJson(data=gdf1, style_function=lambda _x: style_parcels)
polygon_folium2 = folium.GeoJson(
data=gdf2, style_function=lambda x: style_buildings
data=gdf2, style_function=lambda _x: style_buildings
)

map = folium.Map(
location=START_LOCATION,
zoom_start=START_ZOOM,
location=start_location,
zoom_start=start_zoom,
tiles="OpenStreetMap",
max_zoom=21,
)
Expand Down
2 changes: 1 addition & 1 deletion examples/pages/geojson_styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

style_parcels = {"fillColor": "red", "fillOpacity": 0.2}

polygon_folium = folium.GeoJson(data=gdf, style_function=lambda x: style_parcels)
polygon_folium = folium.GeoJson(data=gdf, style_function=lambda _x: style_parcels)

map = folium.Map(
location=START_LOCATION, zoom_start=START_ZOOM, tiles="OpenStreetMap", max_zoom=21
Expand Down
5 changes: 2 additions & 3 deletions examples/park_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ class Point:
def from_dict(cls, data: Dict) -> "Point":
if "lat" in data:
return cls(float(data["lat"]), float(data["lng"]))
elif "latitude" in data:
if "latitude" in data:
randyzwitch marked this conversation as resolved.
Show resolved Hide resolved
return cls(float(data["latitude"]), float(data["longitude"]))
else:
raise NotImplementedError(data.keys())
raise NotImplementedError(data.keys())

def is_close_to(self, other: "Point") -> bool:
close_lat = self.lat - 0.0001 <= other.lat <= self.lat + 0.0001
Expand Down
27 changes: 25 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
[tool.ruff]
line-length = 88
select = ["E", "F", "I001"]

[tool.ruff.lint]
ignore = ["B008", "ISC001", "E501", "W191", "B018"]
select = [
"B",
"E",
"F",
"W",
"I",
"N",
"C4",
"EXE",
"ISC",
"ICN",
"PIE",
"PT",
"RET",
"SIM",
"ERA",
"PLC",
"RUF",
"ARG",
]


[tool.mypy]
files = ["**/*.py"]
follow_imports = "silent"
ignore_missing_imports = true
scripts_are_modules = true
python_version = 3.9
python_version = "3.9"
Loading
Loading