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

test: update the test suit #635

Merged
merged 6 commits into from
Nov 28, 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
3 changes: 1 addition & 2 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]

Expand Down Expand Up @@ -72,7 +71,7 @@ jobs:
assert len(unexpected) == 0

- name: test with pytest
run: coverage run -m pytest --color=yes tests
run: coverage run -m pytest --color=yes --instafail tests

- name: build the template panel application
if: matrix.python-version == '3.8'
Expand Down
67 changes: 44 additions & 23 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The tool is currently tranlated in the following languages:

English, Français, Español

You can contribute to the translation effort on our `pontoon project <https://sepal-ui-translation.herokuapp.com/projects/sepal-ui/>`__. Contributors can suggest new languages and new translation. The admin will review this modification as fast as possible. If nobody in the core team master the suggested language, we'll be force to trust you !
You can contribute to the translation effort on our `crowdin project <https://crowdin.com/project/sepal-ui/>`__. Contributors can suggest new languages and new translation. The admin will review this modification as fast as possible. If nobody in the core team master the suggested language, we'll be force to trust you !


Develop within the project
Expand All @@ -43,9 +43,9 @@ Since 2020-08-14, this repository follows these `development guidelines <https:/

Please consider using the :code:`--no-ff` option when merging to keep the repository consistent with PR.

In the project to adapt to :code:`JupyterLab` IntelSense, we decided to explicitly write the `return` statement for every function.
In the project to adapt to :code:`JupyterLab` IntelSense, we decided to explicitly write the ``return`` statement for every function.

As we are holding a single documentation page, we need to provide the users with version informations. When a new function or class is created please use the `Deprecated <https://pypi.org/project/Deprecated/>`__ lib to specify that the feature is new in the documentation.
When a new function or class is created please use the `Deprecated <https://pypi.org/project/Deprecated/>`__ lib to specify that the feature is new in the documentation.

.. code-block:: python

Expand Down Expand Up @@ -79,13 +79,13 @@ You can learn more about Conventional Commits following this `link <https://www.
What can I push and where
-------------------------

Our branching system embed some rules to avoid crash of the production environment. If you want to contribute to this framework, here are some basic rules that we try our best to follow :
Our branching system embed some rules to avoid crash of the production environment. If you want to contribute to this framework, here are some basic rules that we try our best to follow:

- the modification you offer is solving a critical bug in prod : **PR in hotfix**
- the modification you propose solve the following issues : test, documentation, typo, quality, refactoring, translation **PR in master**
- the modification you propose is a new feature : open an issue to discuss with the maintainers and then **PR to develop**
- the modification you offer is solving a critical bug in prod : **PR in main**
- the modification you propose solve the following issues : test, documentation, typo, quality, refactoring, translation **PR in main**
- the modification you propose is a new feature : open an issue to discuss with the maintainers and then **PR to main**

the maintainers will try their best to use PR for new features, to help the community follow the development, for other modification they will simply push to the appropriate branch
the maintainers will try their best to use PR for new features, to help the community follow the development, for other modification they will simply push to the appropriate branch.

Create a new release
--------------------
Expand All @@ -108,23 +108,22 @@ It should modify for you the version number in :code:`sepal_ui/__init__.py`, :co

It will also update the :code:`CHANGELOG.md` file with the latest commits, sorted by categories if you run the following code, using the version bumped in the previous commit.

.. code-block:: console
.. danger::

cz changelog --unreleased-version="v_x.x.x"
As long as https://github.com/commitizen-tools/commitizen/issues/463 remains open, the version names of this repository won't work with the commitizen lib and the changelog won't be updated. As a maintainer you need to clone the project and follow the instruction from https://github.com/commitizen-tools/commitizen/issues/463#issuecomment-1191653690.

Then push the current :code:`master` branch to the :code:`release` branch. You can now create a new tag with your new version number. use the same convention as the one found in :code:`.cz.yaml`: :code:`v_$minor.$major.$patch$prerelease`.
Then push the current :code:`main` branch to the :code:`release` branch. You can now create a new tag with your new version number. use the same convention as the one found in :code:`.cz.yaml`: :code:`v_$minor.$major.$patch$prerelease`.

.. warning::

The target branch of the new release is :code:`release` not :code:`master`.
The target branch of the new release is :code:`release` not :code:`main`.

The CI should take everything in control from here and execute the :code:`Upload Python Package` GitHub Action that is publishing the new version on `PyPi <https://badge.fury.io/py/sepal-ui>`_.
The CI should take everything in control from here and execute the :code:`Upload Python Package` GitHub Action that is publishing the new version on `PyPi <https://pypi.org/project/sepal-ui/>`_.

Once it's done you need to trigger the rebuild of SEPAL. modify the following `file <https://github.com/openforis/sepal/blob/master/modules/sandbox/docker/script/init_sepal_ui.sh>`_ with the latest version number and the rebuild will start automatically.


Setting ENV variables
---------------------
ENV for Planet components
-------------------------

Sometimes is useful to create enviromental variables to store some data that your workflows will receive (i.e. component testing). For example, to perform the local tests of the :code:`planetapi` sepal module, the :code:`PLANET_API_KEY` and :code:`PLANET_API_CREDENTIALS` env vars are required, even though they are also skippable.

Expand All @@ -134,17 +133,39 @@ To store a variable in your local session, just type :code:`export=` followed by

$ export PLANET_API_KEY="neverending_resourcesapi"

However, this variable will expire everytime you start a new session, to create it every session and make it live longer, go to your :code:`home` folder and save the previous line in the :code:`.bash_profile` file.
.. tip::

.. code-block:: console
In SEPAL this variable will expire everytime you start a new session, to create it every session and make it live longer, go to your :code:`home` folder and save the previous line in the :code:`.bash_profile` file.

.. code-block:: console

$ vim .bash_profile

$ vim .bash_profile
The current enviromental keys and its structure is the following:

.. note::
The current enviromental keys and its structure is the following:
- ``PLANET_API_CREDENTIALS='{"username": "[email protected]", "password": "secure"}'``
- ``PLANET_API_KEY="string_planet_api_key"``

ENV for GEE component
---------------------

- PLANET_API_CREDENTIALS: '{"username": "[email protected]", "password": "secure"}'
- PLANET_API_KEY: "string_planet_api_key"
To test/use the Google EarthEngine components, you need to run the `ìnit__ee`` script.

In a local development environment you can fully rely on your own GEE account. simply make sure to run at least once the authentification process from a terminal:

.. code-block:: console

$ earthengine authenticate

In a distant environment (such as GitHub Actions) it is compulsory to use a environment variable to link your earthengine account. First, find the Earth Engine credentials file on your computer.

.. code-block::

Windows: C:\Users\USERNAME\.config\earthengine\credentials
Linux: /home/USERNAME/.config/earthengine/credentials
MacOS: /Users/USERNAME/.config/earthengine/credentials

Open the credentials file and copy its content. On the **GitHub Actions** page, create a new **secret** with the name ``EARTHENGINE_TOKE``, and the value of the copied content.

Build the API documentation files
---------------------------------
Expand Down
9 changes: 5 additions & 4 deletions sepal_ui/aoi/aoi_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
import pandas as pd
from deprecated.sphinx import deprecated
from ipyleaflet import GeoJSON
from traitlets import Any

from sepal_ui import color
from sepal_ui.frontend import styles as ss
from sepal_ui.message import ms
from sepal_ui.model import Model
from sepal_ui.scripts import gee
from sepal_ui.scripts import utils as su
from traitlets import Any

__all__ = ["AoiModel"]

Expand Down Expand Up @@ -619,8 +620,8 @@ def get_ipygeojson(self):
style.update(color=color.success, fillColor=color.success)

# create a GeoJSON object
self.ipygeojson = GeoJSON(
data=data, style=style, name="aoi", attribution="SEPAL(c)"
)
# attribution="SEPAL(c)" is not recognized yet
# https://github.com/jupyter-widgets/ipyleaflet/issues/847
self.ipygeojson = GeoJSON(data=data, style=style, name="aoi")

return self.ipygeojson
1 change: 1 addition & 0 deletions sepal_ui/aoi/aoi_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from traitlets import Int

import sepal_ui.sepalwidgets as sw
from sepal_ui import mapping as sm
from sepal_ui.aoi.aoi_model import AoiModel
from sepal_ui.message import ms
from sepal_ui.scripts import decorator as sd
Expand Down
4 changes: 2 additions & 2 deletions sepal_ui/mapping/draw_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def show(self):
"""

self.clear()
self in self.m.controls or self.m.add_control(self)
self in self.m.controls or self.m.add(self)

return

Expand All @@ -51,7 +51,7 @@ def hide(self):
"""

self.clear()
self not in self.m.controls or self.m.remove_control(self)
self not in self.m.controls or self.m.remove(self)

return

Expand Down
24 changes: 12 additions & 12 deletions sepal_ui/mapping/sepal_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,30 +109,30 @@ def __init__(
not gee or su.init_ee()

# add the basemaps
self.clear_layers()
self.clear()
default_basemap = (
"CartoDB.DarkMatter" if v.theme.dark is True else "CartoDB.Positron"
)
basemaps = basemaps or [default_basemap]
[self.add_basemap(basemap) for basemap in set(basemaps)]

# add the base controls
self.add_control(ipl.ZoomControl(position="topright"))
self.add_control(ipl.LayersControl(position="topright"))
self.add_control(ipl.AttributionControl(position="bottomleft", prefix="SEPAL"))
self.add_control(ipl.ScaleControl(position="bottomleft", imperial=False))
self.add(ipl.ZoomControl(position="topright"))
self.add(ipl.LayersControl(position="topright"))
self.add(ipl.AttributionControl(position="bottomleft", prefix="SEPAL"))
self.add(ipl.ScaleControl(position="bottomleft", imperial=False))

# specific drawing control
self.dc = DrawControl(self)
not dc or self.add_control(self.dc)
not dc or self.add(self.dc)

# specific v_inspector
self.v_inspector = ValueInspector(self)
not vinspector or self.add_control(self.v_inspector)
not vinspector or self.add(self.v_inspector)

# specific statebar
self.state = LayerStateControl(self)
not statebar or self.add_control(self.state)
not statebar or self.add(self.state)

# create a proxy ID to the element
# this id should be unique and will be used by mutators to identify this map
Expand Down Expand Up @@ -466,7 +466,7 @@ def add_colorbar(
output.clear_output()
plt.show()

self.add_control(colormap_ctrl)
self.add(colormap_ctrl)

return

Expand Down Expand Up @@ -764,7 +764,7 @@ def remove_layer(self, key, base=False, none_ok=False):

# the error is catched in find_layer
if layer is not None:
super().remove_layer(layer)
super().remove(layer)

return

Expand Down Expand Up @@ -815,7 +815,7 @@ def add_layer(self, layer, hover=False):
hover_style = default_hover_style if hover else layer.hover_style
layer.hover_style = layer.hover_style or hover_style

super().add_layer(layer)
super().add(layer)

return

Expand Down Expand Up @@ -897,7 +897,7 @@ def add_legend(
legend_dict, title=title, vertical=vertical, position=position
)

return self.add_control(self.legend)
return self.add(self.legend)

# ##########################################################################
# ### overwrite geemap calls ###
Expand Down
21 changes: 12 additions & 9 deletions sepal_ui/reclassify/reclassify_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
from matplotlib.colors import to_rgba
from natsort import natsorted
from rasterio.windows import from_bounds
from traitlets import Any, Bool, Dict, Int

from sepal_ui.message import ms
from sepal_ui.model import Model
from sepal_ui.scripts import decorator as sd
from sepal_ui.scripts import gee
from sepal_ui.scripts import utils as su
from traitlets import Any, Bool, Dict, Int

from .parameters import NO_VALUE

Expand Down Expand Up @@ -216,12 +218,12 @@ def get_bands(self):
integer or str
"""

@su.need_ee
@sd.need_ee
def _ee_image():

return ee.Image(self.src_gee).bandNames().getInfo()

@su.need_ee
@sd.need_ee
def _ee_vector():

columns = ee.FeatureCollection(self.src_gee).first().getInfo()["properties"]
Expand Down Expand Up @@ -255,6 +257,9 @@ def _local_vector():
def get_aoi(self):
"""Validate and get feature collection from aoi_model"""

# by default it's none
aoi = None

# return None if no aoi_model is selected
if not self.aoi_model:
return
Expand All @@ -264,8 +269,6 @@ def get_aoi(self):
if self.aoi_model.gdf is None:
if self.enforce_aoi:
raise Exception("You have to select an area of interest before")
else:
aoi = None

else: # return the aoi as a vector
if self.gee:
Expand All @@ -288,7 +291,7 @@ def unique(self):
if not self.band:
raise Exception("You need to provide a band/property to reclassify.")

@su.need_ee
@sd.need_ee
def _ee_image():

# reduce the image
Expand All @@ -308,7 +311,7 @@ def _ee_image():

return values

@su.need_ee
@sd.need_ee
def _ee_vector():

collection = ee.FeatureCollection(self.src_gee)
Expand Down Expand Up @@ -370,7 +373,7 @@ def reclassify(self):
if not self.band:
raise Exception("You need to provide a band/property to reclassify.")

@su.need_ee
@sd.need_ee
def _ee_image():

if not self.src_gee:
Expand Down Expand Up @@ -437,7 +440,7 @@ def _ee_image():

return self.dst_gee

@su.need_ee
@sd.need_ee
def _ee_vector():

if not self.src_gee:
Expand Down
Loading