From fb2f1858fb9b0127eddbd8b212ccb98831fe700e Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Tue, 9 May 2023 11:57:06 -0700 Subject: [PATCH] Fix `style` unknown prop error on `mpc.Switch` (#335) * fix TypeError: The dash_mp_components.Switch component received an unexpected keyword argument: style * add ruff rule sets: ICN, ISC, PD, PIE, PT, PYI, RET, RSE * fix all ruff errors --- .../apps/examples/diffraction_dynamic.py | 3 +- crystal_toolkit/apps/examples/kwarg_inputs.py | 4 +- .../matbench_dielectric_datatable_xrd.py | 4 +- .../apps/examples/mpcontribs/catalysis.py | 14 ++--- crystal_toolkit/apps/main.py | 8 +-- crystal_toolkit/components/__init__.py | 4 +- crystal_toolkit/components/bandstructure.py | 46 +++++++-------- crystal_toolkit/components/diffraction.py | 21 +++---- crystal_toolkit/components/diffraction_tem.py | 3 +- crystal_toolkit/components/localenv.py | 13 ++--- crystal_toolkit/components/phase_diagram.py | 45 ++++++-------- crystal_toolkit/components/phonon.py | 50 ++++++++-------- crystal_toolkit/components/pourbaix.py | 12 +--- crystal_toolkit/components/search.py | 10 +--- crystal_toolkit/components/structure.py | 17 +++--- crystal_toolkit/components/submit_snl.py | 10 +--- .../components/transformations/core.py | 18 +++--- .../components/transformations/slab.py | 4 +- .../components/transformations/supercell.py | 4 +- crystal_toolkit/components/upload.py | 21 ++++--- crystal_toolkit/components/xas.py | 9 ++- crystal_toolkit/core/legend.py | 3 +- crystal_toolkit/core/mpcomponent.py | 28 +++++---- crystal_toolkit/core/panelcomponent.py | 4 +- crystal_toolkit/core/scene.py | 3 +- crystal_toolkit/helpers/asymptote_renderer.py | 58 +++++++------------ crystal_toolkit/helpers/layouts.py | 9 +-- crystal_toolkit/helpers/povray_renderer.py | 3 +- crystal_toolkit/helpers/utils.py | 44 ++++++-------- crystal_toolkit/msonable.py | 5 +- crystal_toolkit/renderables/__init__.py | 16 ++--- crystal_toolkit/renderables/site.py | 6 +- pyproject.toml | 21 +++++-- 33 files changed, 217 insertions(+), 303 deletions(-) diff --git a/crystal_toolkit/apps/examples/diffraction_dynamic.py b/crystal_toolkit/apps/examples/diffraction_dynamic.py index 907ee9ff..4c96e73d 100644 --- a/crystal_toolkit/apps/examples/diffraction_dynamic.py +++ b/crystal_toolkit/apps/examples/diffraction_dynamic.py @@ -25,8 +25,7 @@ @app.callback(Output(xrd_component.id(), "data"), Input(load_btn, "n_clicks")) def load_structure(n_clicks: int) -> Structure: """Load a cubic structure on button click.""" - structure = Structure(Lattice.cubic(4.2), ["Na", "K"], [[0, 0, 0], [0.5, 0.5, 0.5]]) - return structure + return Structure(Lattice.cubic(4.2), ["Na", "K"], [[0, 0, 0], [0.5, 0.5, 0.5]]) # run this app with "python path/to/this/file.py" diff --git a/crystal_toolkit/apps/examples/kwarg_inputs.py b/crystal_toolkit/apps/examples/kwarg_inputs.py index 91a25ad0..7d18baed 100644 --- a/crystal_toolkit/apps/examples/kwarg_inputs.py +++ b/crystal_toolkit/apps/examples/kwarg_inputs.py @@ -77,15 +77,13 @@ def add_inputs(n_clicks): raise PreventUpdate element = random.choice(["Li", "Na", "K"]) - slider_input = your_component.get_slider_input( + return your_component.get_slider_input( kwarg_label=f"slider_{element}", default=random.uniform(0, 1), label=f"{element} Slider Input", help_str="This can explain to the user what this slider input controls.", ) - return slider_input - # tell Crystal Toolkit about the app and layout we want to display ctc.register_crystal_toolkit(app=app, layout=my_layout, cache=None) diff --git a/crystal_toolkit/apps/examples/matbench_dielectric_datatable_xrd.py b/crystal_toolkit/apps/examples/matbench_dielectric_datatable_xrd.py index 049bed51..a3886f1d 100644 --- a/crystal_toolkit/apps/examples/matbench_dielectric_datatable_xrd.py +++ b/crystal_toolkit/apps/examples/matbench_dielectric_datatable_xrd.py @@ -71,9 +71,7 @@ def update_structure(active_cell: dict[str, int | str]) -> Structure: point. """ row_idx = active_cell["row"] - structure = df_diel.structure[row_idx] - - return structure + return df_diel.structure[row_idx] if __name__ == "__main__": diff --git a/crystal_toolkit/apps/examples/mpcontribs/catalysis.py b/crystal_toolkit/apps/examples/mpcontribs/catalysis.py index 195d1191..29bdfd3b 100644 --- a/crystal_toolkit/apps/examples/mpcontribs/catalysis.py +++ b/crystal_toolkit/apps/examples/mpcontribs/catalysis.py @@ -220,8 +220,7 @@ def get_plot_data(smile: str) -> pd.DataFrame: } for resp in contributions["data"] ] - df = pd.DataFrame(records) - return df + return pd.DataFrame(records) @app.callback( Output(self.id("heat_map"), "figure"), @@ -239,8 +238,7 @@ def update_figure(smile, mid_E, range_E, active_tab): smile = smile[0] df = get_plot_data(smile) df_full, df_min_E = self.modify_df(df) - plot = self.get_plot(df_full, df_min_E, mid_E, range_E, 1) - return plot + return self.get_plot(df_full, df_min_E, mid_E, range_E, 1) @app.callback( Output(self.id("display_table"), "children"), @@ -300,7 +298,7 @@ def get_visualization(self, structure): ).layout() def get_layout(self, payload=None): - tabs = dcc.Tabs( + return dcc.Tabs( [ dcc.Tab( children=[html.Br(), self.get_search_layout(payload=payload)], @@ -322,8 +320,6 @@ def get_layout(self, payload=None): id=self.id("tabs"), ) - return tabs - def get_visualization_layout(self, payload=None): state = {"smiles": "*C", "targetE": 0.2, "range_E": 1} smiles_input = self.get_choice_input( @@ -366,7 +362,7 @@ def get_visualization_layout(self, payload=None): [description, html.Br(), html.Br(), smiles_input, E_input, range_input] ) - viz_div = html.Div( + return html.Div( ctl.Columns( [ ctl.Column( @@ -407,8 +403,6 @@ def get_visualization_layout(self, payload=None): ) ) - return viz_div - def get_search_layout(self, payload=None): if not payload: return self.get_catalysis_explorer() diff --git a/crystal_toolkit/apps/main.py b/crystal_toolkit/apps/main.py index 443b7e62..dc5ec5c6 100644 --- a/crystal_toolkit/apps/main.py +++ b/crystal_toolkit/apps/main.py @@ -440,10 +440,9 @@ def update_search_term_on_page_load(href: str) -> str: pathname = str(parse.urlparse(href).path).split("/") if len(pathname) <= 1: raise PreventUpdate - elif not pathname[1]: + if not pathname[1]: return choice(DEFAULT_MPIDS) - else: - return pathname[1].replace("+", " ") + return pathname[1].replace("+", " ") @app.callback( @@ -468,8 +467,7 @@ def perform_search_on_page_load( # TODO: could be a client side callback if n_submit is None: return 1, int(round(time() * 1000)) - else: - raise PreventUpdate + raise PreventUpdate @app.callback(Output("url", "pathname"), Input(search_component.id(), "data")) diff --git a/crystal_toolkit/components/__init__.py b/crystal_toolkit/components/__init__.py index ce6c5a43..4c1dd231 100644 --- a/crystal_toolkit/components/__init__.py +++ b/crystal_toolkit/components/__init__.py @@ -5,10 +5,10 @@ BandstructureAndDosPanelComponent, ) from crystal_toolkit.components.diffraction import ( - XRayDiffractionComponent as XRayDiffractionComponent, + XRayDiffractionComponent, ) from crystal_toolkit.components.diffraction_tem import ( - TEMDiffractionComponent as TEMDiffractionComponent, + TEMDiffractionComponent, ) from crystal_toolkit.components.fermi_surface import FermiSurfaceComponent from crystal_toolkit.components.localenv import LocalEnvironmentPanel diff --git a/crystal_toolkit/components/bandstructure.py b/crystal_toolkit/components/bandstructure.py index b6bc68af..b1540c0c 100644 --- a/crystal_toolkit/components/bandstructure.py +++ b/crystal_toolkit/components/bandstructure.py @@ -804,11 +804,10 @@ def update_graph(traces): def update_label_select(mpid, path_convention): if not mpid: raise PreventUpdate - else: - label_value = path_convention - label_style = {"maxWidth": "200"} + label_value = path_convention + label_style = {"maxWidth": "200"} - return label_value, label_style + return label_value, label_style @app.callback( Output(self.id("dos-select"), "options"), @@ -820,7 +819,7 @@ def update_label_select(mpid, path_convention): def update_select(elements, mpid): if elements is None: raise PreventUpdate - elif not mpid: + if not mpid: dos_options = ( [{"label": "Element Projected", "value": "ap"}] + [{"label": "Orbital Projected - Total", "value": "op"}] @@ -837,28 +836,27 @@ def update_select(elements, mpid): path_style = {"maxWidth": "200", "display": "none"} return [dos_options, path_options, path_style] - else: - dos_options = ( - [{"label": "Element Projected", "value": "ap"}] - + [{"label": "Orbital Projected - Total", "value": "op"}] - + [ - { - "label": f"Orbital Projected - {ele_label}", - "value": f"orb{ele_label}", - } - for ele_label in elements - ] - ) - - path_options = [ - {"label": "Setyawan-Curtarolo", "value": "sc"}, - {"label": "Latimer-Munro", "value": "lm"}, - {"label": "Hinuma et al.", "value": "hin"}, + dos_options = ( + [{"label": "Element Projected", "value": "ap"}] + + [{"label": "Orbital Projected - Total", "value": "op"}] + + [ + { + "label": f"Orbital Projected - {ele_label}", + "value": f"orb{ele_label}", + } + for ele_label in elements ] + ) + + path_options = [ + {"label": "Setyawan-Curtarolo", "value": "sc"}, + {"label": "Latimer-Munro", "value": "lm"}, + {"label": "Hinuma et al.", "value": "hin"}, + ] - path_style = {"maxWidth": "200"} + path_style = {"maxWidth": "200"} - return dos_options, path_options, path_style + return dos_options, path_options, path_style @app.callback( Output(self.id("traces"), "data"), diff --git a/crystal_toolkit/components/diffraction.py b/crystal_toolkit/components/diffraction.py index e546406d..f51d5d45 100644 --- a/crystal_toolkit/components/diffraction.py +++ b/crystal_toolkit/components/diffraction.py @@ -409,9 +409,7 @@ def get_figure( if broadening: plotdata.append(go.Scatter(x=x, y=y, hoverinfo="none")) - plot = go.Figure(data=plotdata, layout=layout) - - return plot + return go.Figure(data=plotdata, layout=layout) def generate_callbacks(self, app, cache) -> None: @app.callback( @@ -449,7 +447,7 @@ def update_graph(data, logsize, rad_source, peak_profile, K, x_axis, structure): # suppress broadening for larger cell broadening = len(self.from_data(structure).sites) < SITES_LIMIT - plot = self.get_figure( + return self.get_figure( peak_profile, K, rad_source, @@ -462,8 +460,6 @@ def update_graph(data, logsize, rad_source, peak_profile, K, x_axis, structure): broadening, ) - return plot - @app.callback( Output(self.id(), "data"), [ @@ -500,14 +496,13 @@ def pattern_from_struct(struct, rad_source): def update_message(structure): if len(self.from_data(structure).sites) < SITES_LIMIT: return html.Div([]) - else: - return MessageContainer( - MessageBody( - "Peak broadening is currently disabled for materials with " - f"more than {SITES_LIMIT} sites due to long compute time. Please contact " - "feedback@materialsproject.org if you need assistance with the graph." - ) + return MessageContainer( + MessageBody( + "Peak broadening is currently disabled for materials with " + f"more than {SITES_LIMIT} sites due to long compute time. Please contact " + "feedback@materialsproject.org if you need assistance with the graph." ) + ) # @app.callback( # Output(self.id("static-image"), "src"), Input(self.id("xrd-plot"), "figure") diff --git a/crystal_toolkit/components/diffraction_tem.py b/crystal_toolkit/components/diffraction_tem.py index 9ea16ab3..404d128b 100644 --- a/crystal_toolkit/components/diffraction_tem.py +++ b/crystal_toolkit/components/diffraction_tem.py @@ -387,5 +387,4 @@ def pointlist_to_spots(self, pattern, beam_direction, gamma): paper_bgcolor="white", plot_bgcolor="white", ) - fig = go.Figure(data=data, layout=layout) - return fig + return go.Figure(data=data, layout=layout) diff --git a/crystal_toolkit/components/localenv.py b/crystal_toolkit/components/localenv.py index ba472a10..044c84d9 100644 --- a/crystal_toolkit/components/localenv.py +++ b/crystal_toolkit/components/localenv.py @@ -99,8 +99,7 @@ def _get_local_order_parameters(structure_graph, n): for i, lostop in enumerate(lostop_vals): d[names[i]] = lostop return d - else: - return None + return None class LocalEnvironmentPanel(PanelComponent): @@ -262,7 +261,7 @@ def run_algorithm(algorithm): ] ) - elif algorithm == "localenv": + if algorithm == "localenv": description = ( "The LocalEnv algorithm is developed by Nils Zimmerman et al. whereby " "an 'order parameter' is calculated that measures how well that " @@ -283,7 +282,7 @@ def run_algorithm(algorithm): ] ) - elif algorithm == "bondinggraph": + if algorithm == "bondinggraph": description = ( "This is an alternative way to display the same bonds present in the " "visualizer. Here, the bonding is displayed as a crystal graph, with " @@ -299,7 +298,7 @@ def run_algorithm(algorithm): ] ) - elif algorithm == "soap": + if algorithm == "soap": state = { "rcut": 5.0, "nmax": 2, @@ -487,6 +486,7 @@ def run_algorithm(algorithm): Loading(id=self.id("soap_similarities")), ] ) + return None def _get_soap_graph(feature, label): spectrum = { @@ -766,8 +766,7 @@ def get_valences(struct): valences = [v for v in valences if v is not None] if len(valences) == len(struct): return valences - else: - return "undefined" + return "undefined" # decide which indices to present to user sga = SpacegroupAnalyzer(struct) diff --git a/crystal_toolkit/components/phase_diagram.py b/crystal_toolkit/components/phase_diagram.py index ca8ed0a0..3abc4ef5 100644 --- a/crystal_toolkit/components/phase_diagram.py +++ b/crystal_toolkit/components/phase_diagram.py @@ -198,8 +198,7 @@ def figure_layout(self, plotter, pd): if dim == 4: if not entry.composition.is_element: continue - else: - z = coords[2] + z = coords[2] formula = list(entry.composition.reduced_formula) @@ -333,7 +332,7 @@ def create_unstable_markers(self, plotter, pd): energy = round(pd.get_form_energy_per_atom(unstable_entry), 3) text_list.append( - f"{clean_formula} ({mpid})
" f"{energy} eV (+{e_above_hull} eV)" + f"{clean_formula} ({mpid})
{energy} eV (+{e_above_hull} eV)" ) if dim == 2 or dim == 3: @@ -403,9 +402,7 @@ def clean_formula(formula): else: s.append(char) - clean_formula = "".join(s) - - return clean_formula + return "".join(s) @staticmethod def ternary_plot(plot_data): @@ -548,29 +545,25 @@ def generate_callbacks(self, app, cache) -> None: def update_graph(figure): if figure is None: raise PreventUpdate - elif figure == "error": - search_error = ( - MessageContainer( - [ - MessageBody( - dcc.Markdown( - "Plotting is only available for phase diagrams containing 2-4 components." - ) + if figure == "error": + search_error = MessageContainer( + [ + MessageBody( + dcc.Markdown( + "Plotting is only available for phase diagrams containing 2-4 components." ) - ], - kind="warning", - ), + ) + ], + kind="warning", ) return search_error - else: - plot = [ - dcc.Graph( - figure=figure, - config={"displayModeBar": False, "displaylogo": False}, - ) - ] - return plot + return [ + dcc.Graph( + figure=figure, + config={"displayModeBar": False, "displaylogo": False}, + ) + ] @app.callback(Output(self.id("figure"), "data"), Input(self.id(), "data")) def make_figure(pd): @@ -687,7 +680,7 @@ def create_table(chemsys, pd_time, n_clicks, pd, rows): if trigger["prop_id"] == f"{self.id()}.modified_timestamp": table_content = self.create_table_content(self.from_data(pd)) return table_content - elif ( + if ( trigger["prop_id"] == f"{self.id('editing-rows-button')}.n_clicks" and n_clicks > 0 and rows diff --git a/crystal_toolkit/components/phonon.py b/crystal_toolkit/components/phonon.py index 2eccccb4..6ac7cda0 100644 --- a/crystal_toolkit/components/phonon.py +++ b/crystal_toolkit/components/phonon.py @@ -586,12 +586,10 @@ def update_graph(traces): bs, dos = self._get_ph_bs_dos(self.initial_data["default"]) figure = self.get_figure(bs, dos) - graph = dcc.Graph( + return dcc.Graph( figure=figure, config={"displayModeBar": False}, responsive=True ) - return graph - @app.callback( Output(self.id("label-select"), "value"), Output(self.id("label-container"), "style"), @@ -601,11 +599,10 @@ def update_graph(traces): def update_label_select(mpid, path_convention): if not mpid: raise PreventUpdate - else: - label_value = path_convention - label_style = {"maxWidth": "200"} + label_value = path_convention + label_style = {"maxWidth": "200"} - return label_value, label_style + return label_value, label_style @app.callback( Output(self.id("dos-select"), "options"), @@ -617,7 +614,7 @@ def update_label_select(mpid, path_convention): def update_select(elements, mpid): if elements is None: raise PreventUpdate - elif not mpid: + if not mpid: dos_options = ( [{"label": "Element Projected", "value": "ap"}] + [{"label": "Orbital Projected - Total", "value": "op"}] @@ -634,28 +631,27 @@ def update_select(elements, mpid): path_style = {"maxWidth": "200", "display": "none"} return dos_options, path_options, path_style - else: - dos_options = ( - [{"label": "Element Projected", "value": "ap"}] - + [{"label": "Orbital Projected - Total", "value": "op"}] - + [ - { - "label": "Orbital Projected - " + str(ele_label), - "value": "orb" + str(ele_label), - } - for ele_label in elements - ] - ) - - path_options = [ - {"label": "Setyawan-Curtarolo", "value": "sc"}, - {"label": "Latimer-Munro", "value": "lm"}, - {"label": "Hinuma et al.", "value": "hin"}, + dos_options = ( + [{"label": "Element Projected", "value": "ap"}] + + [{"label": "Orbital Projected - Total", "value": "op"}] + + [ + { + "label": "Orbital Projected - " + str(ele_label), + "value": "orb" + str(ele_label), + } + for ele_label in elements ] + ) + + path_options = [ + {"label": "Setyawan-Curtarolo", "value": "sc"}, + {"label": "Latimer-Munro", "value": "lm"}, + {"label": "Hinuma et al.", "value": "hin"}, + ] - path_style = {"maxWidth": "200"} + path_style = {"maxWidth": "200"} - return dos_options, path_options, path_style + return dos_options, path_options, path_style @app.callback( Output(self.id("traces"), "data"), diff --git a/crystal_toolkit/components/pourbaix.py b/crystal_toolkit/components/pourbaix.py index 5be9163f..3bff3239 100644 --- a/crystal_toolkit/components/pourbaix.py +++ b/crystal_toolkit/components/pourbaix.py @@ -524,9 +524,7 @@ def get_text_size(available_vertical_space): # # # # )) - figure = go.Figure(data=data, layout=layout) - - return figure + return go.Figure(data=data, layout=layout) # TODO: format formula @staticmethod @@ -612,7 +610,7 @@ def update_heatmap_choices(entries): mpid = entry["entry_id"] options.append({"label": f"{formula} ({mpid})", "value": mpid}) - heatmap_options = self.get_choice_input( + return self.get_choice_input( "heatmap_choice", state={}, label="Heatmap Entry", @@ -621,8 +619,6 @@ def update_heatmap_choices(entries): disabled=False, ) - return heatmap_options - @app.callback( Output(self.id("element_specific_controls"), "children"), Input(self.id(), "data"), @@ -795,13 +791,11 @@ def make_figure(pourbaix_entries, *args) -> go.Figure: comp_dict, ) - fig = self.get_figure( + return self.get_figure( pourbaix_diagram, heatmap_entry=heatmap_entry, ) - return fig - # TODO # def graph_layout(self): # return self._sub_layouts["graph"] diff --git a/crystal_toolkit/components/search.py b/crystal_toolkit/components/search.py index c5fc948a..856f1e85 100644 --- a/crystal_toolkit/components/search.py +++ b/crystal_toolkit/components/search.py @@ -143,7 +143,7 @@ def get_human_readable_results_from_search_term(search_term): e_hull_str = np.format_float_scientific(e_hull, precision=2) human_readable_hull_labels.append(f"+{e_hull_str} eV/atom") - human_readable_results = { + return { entry.material_id: f"{unicodeify(entry.formula_pretty)} " f"({unicodeify_spacegroup(entry.symmetry.symbol)}) " f"{human_readable_hull_label}" @@ -152,8 +152,6 @@ def get_human_readable_results_from_search_term(search_term): ) } - return human_readable_results - @app.callback( Output(self.id("results"), "data"), Input(self.id("input"), "n_submit"), @@ -195,8 +193,7 @@ def update_dropdown_value(results): def hide_show_dropdown(results): if not results or len(results) <= 1: return {"display": "none"} - else: - return {} + return {} @app.callback( Output(self.id("warning"), "children"), Input(self.id("results"), "data") @@ -204,8 +201,7 @@ def hide_show_dropdown(results): def show_warning(results): if results and "error" in results: return MessageContainer(MessageBody(results["error"])) - else: - return html.Div() + return html.Div() @app.callback( Output(self.id("search_container"), "children"), diff --git a/crystal_toolkit/components/structure.py b/crystal_toolkit/components/structure.py index fdec05dc..3bb8fffd 100644 --- a/crystal_toolkit/components/structure.py +++ b/crystal_toolkit/components/structure.py @@ -572,12 +572,11 @@ def _make_legend(self, legend): def get_font_color(hex_code): # ensures contrasting font color for background color c = tuple(int(hex_code[1:][i : i + 2], 16) for i in (0, 2, 4)) - font_color = ( + return ( "#000000" if 1 - (c[0] * 0.299 + c[1] * 0.587 + c[2] * 0.114) / 255 < 0.5 else "#ffffff" ) - return font_color try: formula = Composition.from_dict(legend["composition"]).reduced_formula @@ -652,11 +651,10 @@ def _make_bonding_algorithm_custom_cuffoff_data(graph): chain.from_iterable([list(c) for c in struct_or_mol.species_and_occu]), ) ) - rows = [ + return [ # rows {"A": combination[0], "B": combination[1], "A—B": 0} for combination in combinations_with_replacement(species, 2) ] - return rows @property def _sub_layouts(self) -> dict[str, Component]: @@ -1002,14 +1000,13 @@ def _get_struct_or_mol( ) -> Structure | Molecule: if isinstance(graph, StructureGraph): return graph.structure - elif isinstance(graph, MoleculeGraph): + if isinstance(graph, MoleculeGraph): return graph.molecule - elif isinstance(graph, (Structure, Molecule)): + if isinstance(graph, (Structure, Molecule)): return graph - else: - raise ValueError( - f"Invalid input type {graph}, expected one of Structure, Molecule, StructureGraph or MoleculeGraph" - ) + raise ValueError( + f"Invalid input type {graph}, expected one of Structure, Molecule, StructureGraph or MoleculeGraph" + ) @staticmethod def get_scene_and_legend( diff --git a/crystal_toolkit/components/submit_snl.py b/crystal_toolkit/components/submit_snl.py index 28e62415..693f1510 100644 --- a/crystal_toolkit/components/submit_snl.py +++ b/crystal_toolkit/components/submit_snl.py @@ -71,17 +71,14 @@ def parse_token(url): return None if url.startswith("?"): url = url[1:] - token = dict(parse.parse_qsl(url)).get("token") - return token + return dict(parse.parse_qsl(url)).get("token") @cache.memoize(timeout=60 * 60 * 24) def get_token_response(token): url = "https://materialsproject.org/rest/v2/snl/get_user_info" payload = {"token": token, "client_key": MP_CLIENT_KEY} - contents = requests.post(url, data=payload).json()["response"] - - return contents + return requests.post(url, data=payload).json()["response"] @app.callback( Output(self.id("panel"), "style"), @@ -94,8 +91,7 @@ def hide_panel_if_no_token(url): if not token: return {"display": "none"}, {} - else: - return {}, {} # {"display": "none"} + return {}, {} # {"display": "none"} @app.callback( Output(self.id("info"), "children"), diff --git a/crystal_toolkit/components/transformations/core.py b/crystal_toolkit/components/transformations/core.py index 76d7b702..464c2324 100644 --- a/crystal_toolkit/components/transformations/core.py +++ b/crystal_toolkit/components/transformations/core.py @@ -51,7 +51,9 @@ def is_one_to_many(self) -> bool: def _sub_layouts(self) -> dict[str, Component]: enable = mpc.Switch( id=self.id("enable_transformation"), - style={"display": "inline-block", "vertical-align": "middle"}, + # style used to be passed to dash_daq.ToggleSwitch component, but not + # supported by mpc.Switch + # style={"display": "inline-block", "vertical-align": "middle"}, ) message = html.Div(id=self.id("message")) @@ -83,7 +85,7 @@ def _sub_layouts(self) -> dict[str, Component]: def container_layout(self, state=None, structure=None) -> html.Div: """Layout defining transformation and its options.""" - container = MessageContainer( + return MessageContainer( [ MessageHeader( html.Div( @@ -125,8 +127,6 @@ def container_layout(self, state=None, structure=None) -> html.Div: id=self.id("container"), ) - return container - def options_layouts(self, state=None, structure=None) -> list[html.Div]: """Return a layout to change the transformation options (that is, that controls the args and kwargs that will be passed to pymatgen). @@ -231,8 +231,7 @@ def update_transformation(enabled, states): if not enabled: input_state = (False,) * len(states) return None, "message is-dark", html.Div(), input_state - else: - input_state = (True,) * len(states) + input_state = (True,) * len(states) try: trans = self.transformation(**kwargs) @@ -249,8 +248,7 @@ def update_transformation(enabled, states): input_state, ) - else: - return trans, "message is-success", html.Div(), input_state + return trans, "message is-success", html.Div(), input_state class AllTransformationsComponent(MPComponent): @@ -378,7 +376,7 @@ def show_transformation_options(structure, values, *args): structure = self.from_data(structure) - transformation_options = html.Div( + return html.Div( # transformation_options [ self.transformations[name].container_layout( state=state, structure=structure @@ -387,8 +385,6 @@ def show_transformation_options(structure, values, *args): ] ) - return transformation_options - @app.callback( Output(self.id("enabled-transformations"), "data"), Input(self.id("choices"), "value"), diff --git a/crystal_toolkit/components/transformations/slab.py b/crystal_toolkit/components/transformations/slab.py index 49b09301..cfe1d760 100644 --- a/crystal_toolkit/components/transformations/slab.py +++ b/crystal_toolkit/components/transformations/slab.py @@ -110,7 +110,7 @@ def options_layouts(self, state=None, structure=None): shape=(), ) - options = html.Div( + return html.Div( [ miller_index, min_slab_size, @@ -123,5 +123,3 @@ def options_layouts(self, state=None, structure=None): tol, ] ) - - return options diff --git a/crystal_toolkit/components/transformations/supercell.py b/crystal_toolkit/components/transformations/supercell.py index d133de45..eee8588d 100644 --- a/crystal_toolkit/components/transformations/supercell.py +++ b/crystal_toolkit/components/transformations/supercell.py @@ -32,7 +32,7 @@ def transformation(self): def options_layouts(self, state=None, structure=None): state = state or {"scaling_matrix": ((1, 0, 0), (0, 1, 0), (0, 0, 1))} - options = self.get_numerical_input( + return self.get_numerical_input( label="Scaling matrix", kwarg_label="scaling_matrix", state=state, @@ -41,8 +41,6 @@ def options_layouts(self, state=None, structure=None): shape=(3, 3), ) - return options - def get_preview_layout(self, struct_in, struct_out): if struct_in.lattice == struct_out.lattice: return html.Div() diff --git a/crystal_toolkit/components/upload.py b/crystal_toolkit/components/upload.py index d564f447..8c9b4c45 100644 --- a/crystal_toolkit/components/upload.py +++ b/crystal_toolkit/components/upload.py @@ -79,17 +79,16 @@ def update_error_message(data): raise PreventUpdate if not data["error"]: return html.Div() - else: - return html.Div( - [ - html.Br(), - MessageContainer( - [MessageHeader("Error"), MessageBody([data["error"]])], - kind="danger", - size="small", - ), - ] - ) + return html.Div( + [ + html.Br(), + MessageContainer( + [MessageHeader("Error"), MessageBody([data["error"]])], + kind="danger", + size="small", + ), + ] + ) @app.callback( Output(self.id(), "data"), diff --git a/crystal_toolkit/components/xas.py b/crystal_toolkit/components/xas.py index 92a005f3..a7c39159 100644 --- a/crystal_toolkit/components/xas.py +++ b/crystal_toolkit/components/xas.py @@ -136,11 +136,10 @@ def update_graph(plotdata): kind="warning", ) return search_error - else: - return dcc.Graph( - figure=go.Figure(data=plotdata, layout=self.default_xas_layout), - config={"displayModeBar": False}, - ) + return dcc.Graph( + figure=go.Figure(data=plotdata, layout=self.default_xas_layout), + config={"displayModeBar": False}, + ) @app.callback( Output(self.id(), "data"), diff --git a/crystal_toolkit/core/legend.py b/crystal_toolkit/core/legend.py index 894b7110..09802c16 100644 --- a/crystal_toolkit/core/legend.py +++ b/crystal_toolkit/core/legend.py @@ -264,8 +264,7 @@ def get_color(self, sp: Species | Element, site: Site | None = None) -> str: color = color[0] if isinstance(color, list): return html5_serialize_simple_color(color) - else: - return html5_serialize_simple_color(html5_parse_legacy_color(color)) + return html5_serialize_simple_color(html5_parse_legacy_color(color)) if self.color_scheme in ("VESTA", "Jmol", "accessible"): el = sp.as_dict()["element"] diff --git a/crystal_toolkit/core/mpcomponent.py b/crystal_toolkit/core/mpcomponent.py index 673ae32b..717e6f5c 100644 --- a/crystal_toolkit/core/mpcomponent.py +++ b/crystal_toolkit/core/mpcomponent.py @@ -269,8 +269,7 @@ def id( # otherwise create a new id self._all_ids.add(name) - name = f"{self._id}_{name}" if name != "default" else f"{self._id}" - return name + return f"{self._id}_{name}" if name != "default" else f"{self._id}" def create_store( self, @@ -372,7 +371,7 @@ def generate_callbacks(self, app, cache) -> None: all layouts will be displayed to the end user at all times, but it's important the callbacks are defined on the server. """ - return None + return def get_numerical_input( self, @@ -433,18 +432,17 @@ def matrix_element(idx, value=0): type="number", **kwargs, ) - else: - return dcc.Input( - id=mid, - inputMode="numeric", - debounce=True, - className="input", - style=style, - value=int(value) if value is not None else None, - persistence=True, - type="number", - **kwargs, - ) + return dcc.Input( + id=mid, + inputMode="numeric", + debounce=True, + className="input", + style=style, + value=int(value) if value is not None else None, + persistence=True, + type="number", + **kwargs, + ) # dict of row indices, column indices to element matrix_contents: dict[int, dict[int, Any]] = defaultdict(dict) diff --git a/crystal_toolkit/core/panelcomponent.py b/crystal_toolkit/core/panelcomponent.py index 1abf5fa4..dc6b647f 100644 --- a/crystal_toolkit/core/panelcomponent.py +++ b/crystal_toolkit/core/panelcomponent.py @@ -35,7 +35,7 @@ def panel_layout(self, open_by_default=False): initial_contents = html.Div(id=self.id("contents")) - panel = Reveal( + return Reveal( title=self.title, children=[message, description, html.Br(), initial_contents], id=self.id("panel"), @@ -43,8 +43,6 @@ def panel_layout(self, open_by_default=False): open=open_by_default, ) - return panel - def contents_layout(self) -> html.Div: raise NotImplementedError diff --git a/crystal_toolkit/core/scene.py b/crystal_toolkit/core/scene.py index 7ad71bae..f58730eb 100644 --- a/crystal_toolkit/core/scene.py +++ b/crystal_toolkit/core/scene.py @@ -137,8 +137,7 @@ def bounding_box(self) -> list[list[float]]: max_x, max_y, max_z = map(max, zip(*max_list)) return [[min_x, min_y, min_z], [max_x, max_y, max_z]] - else: - return [[0, 0, 0], [0, 0, 0]] + return [[0, 0, 0], [0, 0, 0]] @staticmethod def merge_primitives(primitives): diff --git a/crystal_toolkit/helpers/asymptote_renderer.py b/crystal_toolkit/helpers/asymptote_renderer.py index 54a23813..a13da871 100644 --- a/crystal_toolkit/helpers/asymptote_renderer.py +++ b/crystal_toolkit/helpers/asymptote_renderer.py @@ -261,16 +261,11 @@ def __str__(self): opac=self.opac, ) ) - else: - return ( - Environment() - .from_string(TEMP_SPHERE_NOLIGHT) - .render( - positions=self.positions, - radius=self.radius, - color=self.color, - ) - ) + return ( + Environment() + .from_string(TEMP_SPHERE_NOLIGHT) + .render(positions=self.positions, radius=self.radius, color=self.color) + ) @classmethod def from_ctk( @@ -336,16 +331,11 @@ def __str__(self): opac=self.opac, ) ) - else: - return ( - Environment() - .from_string(TEMP_CYLINDER_NOLIGHT) - .render( - posPairs=self.pos_pairs, - radius=self.radius, - color=self.color, - ) - ) + return ( + Environment() + .from_string(TEMP_CYLINDER_NOLIGHT) + .render(posPairs=self.pos_pairs, radius=self.radius, color=self.color) + ) @classmethod def from_ctk( @@ -397,21 +387,13 @@ def __str__(self): return ( Environment() .from_string(TEMP_SURF) - .render( - positions=self.positions, - color=self.color, - opac=self.opac, - ) - ) - else: - return ( - Environment() - .from_string(TEMP_SURF_NOLIGHT) - .render( - positions=self.positions, - color=self.color, - ) + .render(positions=self.positions, color=self.color, opac=self.opac) ) + return ( + Environment() + .from_string(TEMP_SURF_NOLIGHT) + .render(positions=self.positions, color=self.color) + ) @classmethod def from_ctk( @@ -519,7 +501,7 @@ def _read_properties( return _DEFAULTS["scene"].get(scene_name, {}).get(property) -def _read_color(ctk_scene: Scene, user_settings: dict | None = None) -> str: +def _read_color(ctk_scene: Scene, user_settings: dict | None = None) -> str | None: """Read the color from the ctk scene or the user settings. Args: @@ -529,7 +511,7 @@ def _read_color(ctk_scene: Scene, user_settings: dict | None = None) -> str: color = _read_properties(ctk_scene, "color", user_settings) # strip the # from the color if it exists if color is None: - return + return None # if is string if isinstance(color, str): @@ -587,7 +569,7 @@ def asy_write_data( asy_out = asy_obj.from_ctk(ctk_scene=input_scene_comp, user_settings=user_settings) fstream.write(str(asy_out)) - # TODO we can make the line solide for the foreground and dashed for the background + # TODO we can make the line solid for the foreground and dashed for the background # This will require use to modify the way the line objects are generated # at each vertex in the unit cell, we can evaluate the sum of all three lattice vectors from the point # then the for each vertex. The smallest @@ -601,7 +583,7 @@ def traverse_scene_object(scene_data, fstream, user_settings=None) -> None: for iobj in sub_object: traverse_scene_object(iobj) continue - elif hasattr(sub_object, "type"): + if hasattr(sub_object, "type"): asy_write_data(sub_object, fstream, user_settings=user_settings) else: traverse_scene_object(sub_object, fstream, user_settings=user_settings) diff --git a/crystal_toolkit/helpers/layouts.py b/crystal_toolkit/helpers/layouts.py index 82490a72..dda6708d 100644 --- a/crystal_toolkit/helpers/layouts.py +++ b/crystal_toolkit/helpers/layouts.py @@ -397,9 +397,8 @@ def get_table(rows: list[list[Any]], header: list[str] | None = None) -> html.Ta contents.append(html.Tr([html.Td(item) for item in row])) if not header: return html.Table([html.Tbody(contents)], className="table") - else: - header = html.Thead([html.Tr([html.Th(item) for item in header])]) - return html.Table([header, html.Tbody(contents)], className="table") + header = html.Thead([html.Tr([html.Th(item) for item in header])]) + return html.Table([header, html.Tbody(contents)], className="table") DOI_CACHE = loadfn(MODULE_PATH / "apps/assets/doi_cache.json") @@ -457,6 +456,4 @@ def get_breadcrumb(parts): ) for idx, (name, link) in enumerate(parts.items()) ] - breadcrumbs = html.Nav(html.Ul(links), className="breadcrumb") - - return breadcrumbs + return html.Nav(html.Ul(links), className="breadcrumb") diff --git a/crystal_toolkit/helpers/povray_renderer.py b/crystal_toolkit/helpers/povray_renderer.py index 4ac67aa3..94a7bc69 100644 --- a/crystal_toolkit/helpers/povray_renderer.py +++ b/crystal_toolkit/helpers/povray_renderer.py @@ -222,7 +222,7 @@ def get_render_settings(file_name): """Creates a POV-Ray render.ini file.""" image_name = f"{file_name[:-4]}.png" - settings = f""" + return f""" Input_File_Name = {file_name} Output_File_Name = {image_name} Display = 1 @@ -245,4 +245,3 @@ def get_render_settings(file_name): Declare=jj=0 Declare=kk=0 """ - return settings diff --git a/crystal_toolkit/helpers/utils.py b/crystal_toolkit/helpers/utils.py index f3b357f6..462e0de8 100644 --- a/crystal_toolkit/helpers/utils.py +++ b/crystal_toolkit/helpers/utils.py @@ -40,7 +40,7 @@ def update_object_args(d_args, object_name, allowed_args): Returns: dict: Properties of object after user input and default values are considered """ - obj_args = {k: v for k, v in (_DEFAULTS["scene"][object_name] or {}).items()} + obj_args = dict((_DEFAULTS["scene"][object_name] or {}).items()) obj_args.update( {k: v for k, v in (d_args or {}).items() if k in allowed_args and v is not None} ) @@ -109,10 +109,9 @@ def get_user_api_key(consumer=None) -> str | None: if is_localhost(): return SETTINGS.API_KEY - elif is_logged_in_user(consumer): + if is_logged_in_user(consumer): return consumer["X-Consumer-Custom-Id"] - else: - return None + return None def get_contribs_client(): @@ -127,8 +126,7 @@ def get_contribs_client(): if is_localhost(): return Client(apikey=get_user_api_key()) - else: - return Client(headers=headers) + return Client(headers=headers) def get_contribs_api_base_url(request_url=None, deployment="contribs"): @@ -147,8 +145,7 @@ def parse_request_url(request_url, subdomain): pre, suf = parsed_url.netloc.split("next-gen") netloc = pre + subdomain + suf scheme = "http" if netloc.startswith("localhost.") else "https" - base_url = f"{scheme}://{netloc}" - return base_url + return f"{scheme}://{netloc}" HELP_STRINGS = loadfn(MODULE_PATH / "apps/help.yaml") @@ -175,19 +172,18 @@ def get_box_title(use_point: str, title: str, id=None): if use_point not in HELP_STRINGS: return html.H5(title, className="title is-6 mb-2", **args) - else: - div = html.H5( - get_tooltip( - tooltip_label=HELP_STRINGS[use_point][title]["label"], - tooltip_text=HELP_STRINGS[use_point][title]["help"], - className="has-tooltip-multiline", - ), - className="title is-6 mb-2", - **args, - ) - if link := HELP_STRINGS[use_point][title]["link"]: - div = html.A(div, href=link) - return div + div = html.H5( + get_tooltip( + tooltip_label=HELP_STRINGS[use_point][title]["label"], + tooltip_text=HELP_STRINGS[use_point][title]["help"], + className="has-tooltip-multiline", + ), + className="title is-6 mb-2", + **args, + ) + if link := HELP_STRINGS[use_point][title]["link"]: + div = html.A(div, href=link) + return div def get_tooltip( @@ -332,8 +328,7 @@ def get_data_table( ), ] ) - else: - return dt.DataTable(**datatable_kwargs) + return dt.DataTable(**datatable_kwargs) def get_section_heading(title, dois=None, docs_url=None, app_button_id=None): @@ -495,8 +490,7 @@ def is_mpid(value: str) -> str | bool: """ if re.match(r"(mp|mvc)\-\d+$", value): return value - else: - return False + return False def pretty_frac_format(x: float) -> str: diff --git a/crystal_toolkit/msonable.py b/crystal_toolkit/msonable.py index b32c3331..4f781d82 100644 --- a/crystal_toolkit/msonable.py +++ b/crystal_toolkit/msonable.py @@ -32,13 +32,12 @@ def _repr_mimebundle_(self, include=None, exclude=None): "application/vnd.mp.ctk+json": self.get_scene().to_json(), "text/plain": help_text_ct + repr(self), } - elif hasattr(self, "get_plot"): + if hasattr(self, "get_plot"): return { "application/vnd.plotly.v1+json": self.get_plot().to_plotly_json(), "text/plain": help_text_plotly + repr(self), } - else: - return {"application/json": self.as_dict(), "text/plain": repr(self)} + return {"application/json": self.as_dict(), "text/plain": repr(self)} def show_json(self): diff --git a/crystal_toolkit/renderables/__init__.py b/crystal_toolkit/renderables/__init__.py index e150d598..4f851c89 100644 --- a/crystal_toolkit/renderables/__init__.py +++ b/crystal_toolkit/renderables/__init__.py @@ -1,10 +1,10 @@ from __future__ import annotations -from crystal_toolkit.renderables.lattice import Lattice as Lattice -from crystal_toolkit.renderables.molecule import Molecule as Molecule -from crystal_toolkit.renderables.moleculegraph import MoleculeGraph as MoleculeGraph -from crystal_toolkit.renderables.phasediagram import PhaseDiagram as PhaseDiagram -from crystal_toolkit.renderables.site import Site as Site -from crystal_toolkit.renderables.structure import Structure as Structure -from crystal_toolkit.renderables.structuregraph import StructureGraph as StructureGraph -from crystal_toolkit.renderables.volumetric import VolumetricData as VolumetricData +from crystal_toolkit.renderables.lattice import Lattice +from crystal_toolkit.renderables.molecule import Molecule +from crystal_toolkit.renderables.moleculegraph import MoleculeGraph +from crystal_toolkit.renderables.phasediagram import PhaseDiagram +from crystal_toolkit.renderables.site import Site +from crystal_toolkit.renderables.structure import Structure +from crystal_toolkit.renderables.structuregraph import StructureGraph +from crystal_toolkit.renderables.volumetric import VolumetricData diff --git a/crystal_toolkit/renderables/site.py b/crystal_toolkit/renderables/site.py index 40807d08..6a348a80 100644 --- a/crystal_toolkit/renderables/site.py +++ b/crystal_toolkit/renderables/site.py @@ -119,7 +119,7 @@ def get_site_scene( name += f" ({position[0]:.3f}, {position[1]:.3f}, {position[2]:.3f})" if show_atom_idx: - name += "\n" + "index:" + str(site_idx) + name += f"\nindex:{site_idx}" if self.properties: for k, v in self.properties.items(): @@ -177,10 +177,10 @@ def get_site_scene( for idx, connected_site in enumerate(connected_sites): if show_bond_order and connected_site.weight is not None: - name_cyl = "bond order:" + str(f"{connected_site.weight:.2f}") + name_cyl = f"bond order:{connected_site.weight:.2f}" if show_bond_length and connected_site.dist is not None: - name_cyl += "\n" + "bond length:" + str(f"{connected_site.dist:.3f}") + name_cyl += f"\nbond length:{connected_site.dist:.3f}" connected_position = connected_site.site.coords bond_midpoint = np.add(position, connected_position) / 2 diff --git a/pyproject.toml b/pyproject.toml index 66df3bb8..41191a27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,8 +12,8 @@ authors = [{ name = "Matt Horton", email = "mkhorton@lbl.gov" }] dependencies = [ "crystaltoolkit-extension", - "dash-mp-components", "dash", + "dash-mp-components", "flask-caching", "pymatgen", "scikit-image", @@ -60,19 +60,26 @@ build-backend = "setuptools.build_meta" target-version = "py38" select = [ "B", # flake8-bugbear - "C40", # flake8-comprehensions + "C4", # flake8-comprehensions "D", # pydocstyle - "E", # pycodestyle + "E", # pycodestyle error "F", # pyflakes "I", # isort - "PLE", # pylint error - "PLW", # pylint warning + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "PD", # pandas-vet + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PYI", # flakes8-pyi "Q", # flake8-quotes + "RET", # flake8-return + "RSE", # flake8-raise "RUF", # Ruff-specific rules "SIM", # flake8-simplify "TID", # tidy imports "UP", # pyupgrade - "W", # pycodestyle + "W", # pycodestyle warning "YTT", # flake8-2020 ] ignore = [ @@ -86,6 +93,8 @@ ignore = [ "D205", # 1 blank line required between summary line and description "E501", # Line too long "E731", # Do not assign a lambda expression, use a def + "PD901", # pandas-df-variable-name + "PLR", # pylint refactor "SIM105", # Use contextlib.suppress(ValueError) instead of try-except-pass "SIM115", # Use context handler for opening files ]