Source code for sepal_ui.planetapi.planet_view

"""The ``Card`` widget to use in application to interface with Planet."""

from pathlib import Path
from typing import Optional

import ipyvuetify as v

import sepal_ui.sepalwidgets as sw
from sepal_ui.message import ms
from sepal_ui.planetapi.planet_model import PlanetModel
from sepal_ui.planetapi.planet_widgets import InfoView
from sepal_ui.scripts.decorator import loading_button


[docs] class PlanetView(sw.Layout): planet_model: Optional[PlanetModel] = None "Backend model to manipulate interface actions" btn: Optional[sw.Btn] = None "Button to trigger the validation process in the associated model" alert: Optional[sw.Alert] = None "Alert component to display end-user action results" info: bool = False "either to display or not a detailed description about the planet subscriptions" w_username: Optional[sw.TextField] = None "Widget to set credential username" w_password: Optional[sw.PasswordField] = None "Widget to set credential password" w_key: Optional[sw.PasswordField] = None "Widget to set credential API key" w_method: Optional[sw.Select] = None "Dropdown widget to select connection method"
[docs] def __init__( self, btn: Optional[sw.Btn] = None, alert: Optional[sw.Alert] = None, planet_model: Optional[PlanetModel] = None, info: bool = False, **kwargs, ): """Stand-alone interface to capture planet lab credentials. It also validate its subscription and connect to the client from_file in the model. Args: btn (sw.Btn, optional): Button to trigger the validation process in the associated model. alert (sw.Alert, v.Alert, optional): Alert component to display end-user action results. planet_model (sepal_ui.planetlab.PlanetModel): backend model to manipulate interface actions. """ self.class_ = "d-block flex-wrap" super().__init__(**kwargs) self.planet_model = planet_model if planet_model else PlanetModel() self.btn = btn if btn else sw.Btn("Validate", small=True, class_="mr-1") self.alert = alert if alert else sw.Alert() self.w_username = sw.TextField( label=ms.planet.widget.username, class_="mr-2", v_model="" ) self.w_password = sw.PasswordField(label=ms.planet.widget.password) self.w_key = sw.PasswordField(label=ms.planet.widget.apikey, v_model="").hide() self.w_secret_file = sw.TextField( label=ms.planet.widget.store, v_model=str(Path.home() / ".planet.json"), readonly=True, class_="mr-2", ).hide() self.w_info_view = InfoView(model=self.planet_model) self.w_method = v.Select( label=ms.planet.widget.method.label, class_="mr-2", v_model="", items=[ {"value": "from_file", "text": ms.planet.widget.method.from_file}, {"value": "credentials", "text": ms.planet.widget.method.credentials}, {"value": "api_key", "text": ms.planet.widget.method.api_key}, ], ) self.w_store = sw.Checkbox(label=ms.planet.widget.store, v_model=True) w_validation = v.Flex( style_="flex-grow: 0 !important;", children=[self.btn], class_="pr-1 flex-nowrap", ) self.children = [ self.w_method, sw.Layout( attributes={"id": "planet_credentials"}, class_="align-center", children=[ self.w_username, self.w_password, self.w_key, self.w_secret_file, ], ), self.w_store, ] if not btn: self.get_children(attr="id", value="planet_credentials")[0].set_children( w_validation, "last" ) # Set it here to avoid displacements when using button self.set_children(self.w_info_view, "last") if not alert: self.set_children(self.alert, "last") self.w_method.observe(self._swap_inputs, "v_model") self.btn.on_event("click", self.validate) self.set_initial_method()
[docs] def validate_secret_file(self) -> None: """Validate the secret file path.""" if not Path(self.w_secret_file.v_model).exists(): self.w_secret_file.error_messages = [ms.planet.exception.no_secret_file] return False self.w_secret_file.error_messages = [] return True
[docs] def set_initial_method(self) -> None: """Set the initial method to connect to planet lab.""" self.w_method.v_model = ( "from_file" if self.validate_secret_file() else "credentials" )
[docs] def reset(self) -> None: """Empty credentials fields and restart activation mode.""" self.w_username.v_model = "" self.w_password.v_model = "" self.w_key.v_model = "" self.planet_model.__init__() return
def _swap_inputs(self, change: dict) -> None: """Swap between credentials and api key inputs. Args: change.new: values of from_file, credentials, api_key """ self.alert.reset() self.reset() # small detail, but validate the file every time the method is changed self.validate_secret_file() if change["new"] == "credentials": self.w_username.show() self.w_password.show() self.w_secret_file.hide() self.w_store.show() self.w_key.hide() elif change["new"] == "api_key": self.w_username.hide() self.w_password.hide() self.w_secret_file.hide() self.w_store.show() self.w_key.show() else: self.w_username.hide() self.w_password.hide() self.w_key.hide() self.w_store.hide() self.w_secret_file.show() return
[docs] @loading_button() def validate(self, *args) -> None: """Initialize planet client and validate if is active.""" self.planet_model.__init__() if self.w_method.v_model == "credentials": credentials = [self.w_username.v_model, self.w_password.v_model] elif self.w_method.v_model == "api_key": credentials = self.w_key.v_model else: if not self.validate_secret_file(): raise Exception(ms.planet.exception.no_secret_file) credentials = self.w_secret_file.v_model self.planet_model.init_session(credentials, write_secrets=self.w_store.v_model) return