DescripyTor 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of DescripyTor might be problematic. Click here for more details.
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/gui_server.py +23 -8
- descripytor-0.3.2/M3_modeler/bassa_explorer/running.py +61 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/server.py +10 -3
- {descripytor-0.3.1/descripytor.egg-info → descripytor-0.3.2}/PKG-INFO +1 -1
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/__init__.py +1 -1
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/cli.py +13 -2
- {descripytor-0.3.1 → descripytor-0.3.2/descripytor.egg-info}/PKG-INFO +1 -1
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor.egg-info/SOURCES.txt +1 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/pyproject.toml +1 -1
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_bassa_explorer.py +89 -35
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_gui_server.py +35 -28
- {descripytor-0.3.1 → descripytor-0.3.2}/Getting_started_with_examples/descriptor_extraction_toolkit/config_example.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/Getting_started_with_examples/input_example.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/LICENSE +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/esp_grid_driver.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/main.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/outwards_senders.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/adopt.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/build.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/checks.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/cluster.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/examples/phosphines.csv +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/examples/protocol_bgu.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/protocol.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/stages.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/_folder_dialog.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/atom_picker.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/crest_boltzmann_sterimol.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/cube_sterimol.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/data_extractor.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/descriptor_extractor.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/bond_angle_length_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/bond_graph.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/dipole_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/esp_grid_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/sterimol_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/vibrations_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feather_extractor.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/build.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/data.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/feature_explorer.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/009_phos.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/009_phos_CuCl.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/026_box_CuCl.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/026_lig.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/032_lig.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/041_lig.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/045_box_CuCl.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/045_lig.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/046_lig.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/055_phos.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_008.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_018.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_020.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_047.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_PyOx_041.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_1.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_1.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_12.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_12.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_13_str_target.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_13_str_target.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_7.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_7.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Ni_BOX_072.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Ni_BOX_078.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/benzoic_acid.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-CN.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-CN.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-CN_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-CN_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-OMe.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-OMe.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-OMe_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-OMe_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-SO2Me_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/m-SO2Me_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/naphthyl_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/naphthyl_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/o-Me_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/o-Me_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-CF3.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-CF3.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-CF3_substrate.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-CO2Me_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-CO2Me_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-COMe_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-COMe_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-Cl_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-Cl_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-F_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-F_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-H_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-H_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-NO2.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-NO2.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-OMe_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-OMe_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-Otf.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-Otf.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-Otf_substrate.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-t-Bu_BA.data.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/p-t-Bu_BA.xyz +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/gate.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/gate_pos.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/make_pos_refs.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/make_refs.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/pos_refs.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/promol.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/rdkit/RDKit_minimal.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/rdkit/RDKit_minimal.wasm +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/refs.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/render_presets.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/scene.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/smarts.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/smoke.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/sterimol.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/template.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/vbur.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_extraction_gui.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_packages.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/gaussian_handler.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/ligand_topology.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/metal_complex.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/morfeus_sterics.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/placement_search.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/static/3Dmol-min.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/sterimol_standalone.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/theta_explorer/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/theta_explorer/build.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/theta_explorer/data.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/theta_explorer/sterimol.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/theta_explorer/theta_explorer.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/xtb_singlepoint.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/xyz_io.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/batch.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/build_case.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/core_fixed.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/engine.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/example.js +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/example_cs2.csv +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/example_small.csv +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/index.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/influence_check.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/read_structures.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/settings.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/bassa_explorer/test_page.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/modeling.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/modeling_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/nested_cv.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/plot.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/ridge_search.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/M3_modeler/validation.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MANIFEST.in +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/MCS_optimization.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/RDKIT_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/df_funs.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/fmcs.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/gaussian_handler.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/loss.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/renumbering.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/MolAlign/rotations.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/README.md +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/__main__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/compat.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/README.md +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/m-CN.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/m-COMe.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/m-NO2.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/m-OMe.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/m-cyclo.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/o-CN.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/outcomes.csv +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-CF3.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-CHO.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-CN.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-COOMe.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-Cl.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-MeO.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-NO2.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-OMe.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/p-Otf.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/presets.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/pyridine-m-OMe.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/thiophene.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/baptiste_products/unsub.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/config_example.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/README.md +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/basic.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/input_example.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/m_Br.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/m_Cl.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/m_nitro.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/o_Br.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/o_Cl.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/o_F.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/p_Cl.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/p_F.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/p_I.feather +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/feather_example/presets.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor/examples/input_example.json +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor.egg-info/dependency_links.txt +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor.egg-info/entry_points.txt +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor.egg-info/requires.txt +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/descripytor.egg-info/top_level.txt +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/setup.cfg +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/setup.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_arm_fixes.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_bond_graph.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_cli.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_compat.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_connectivity.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_esp_grid.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_examples.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_extract_and_model.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_feature_fixes.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_metal_complex.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_metal_complex_frame.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_pipeline.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_ridge_search.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_sterimol_b1_normal.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_sterimol_loc_b1.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_two_csv.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/tests/test_validation.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/__init__.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/console.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/constants.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/file_handlers.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/help_functions.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/mode_viewer.html +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/mode_viewer.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/rdkit_utils.py +0 -0
- {descripytor-0.3.1 → descripytor-0.3.2}/utils/visualize.py +0 -0
|
@@ -241,7 +241,7 @@ def status():
|
|
|
241
241
|
return jsonify({
|
|
242
242
|
"ok": True,
|
|
243
243
|
"version": "1.0",
|
|
244
|
-
"api":
|
|
244
|
+
"api": GUI_API,
|
|
245
245
|
"example_feather_dir": example_feather_dir(),
|
|
246
246
|
"example_basic_feather": example_basic_feather(),
|
|
247
247
|
"example_reference_feather": example_reference_feather(),
|
|
@@ -275,12 +275,25 @@ def _listening(port):
|
|
|
275
275
|
return s.connect_ex(("127.0.0.1", port)) == 0
|
|
276
276
|
|
|
277
277
|
|
|
278
|
+
def _bassa_running():
|
|
279
|
+
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
280
|
+
if root_dir not in sys.path:
|
|
281
|
+
sys.path.insert(0, root_dir)
|
|
282
|
+
from M3_modeler.bassa_explorer import running
|
|
283
|
+
return running
|
|
284
|
+
|
|
285
|
+
|
|
278
286
|
def _bassa_url():
|
|
279
287
|
"""The BASSA model explorer's address. It has its own server (it may run under another Python): started here if it
|
|
280
|
-
is not up. None when it does not come up."""
|
|
288
|
+
is not up. None when it does not come up, or when the port is held by a server from before an update."""
|
|
281
289
|
import subprocess
|
|
282
290
|
import time
|
|
291
|
+
global BASSA_DOWN
|
|
283
292
|
port = int(os.environ.get("BASSA_EXPLORER_PORT", "8765"))
|
|
293
|
+
BASSA_DOWN = BASSA_NOT_STARTED
|
|
294
|
+
if _bassa_running().state(port) == "old":
|
|
295
|
+
BASSA_DOWN = _bassa_running().stop_hint(port, "the BASSA model explorer")
|
|
296
|
+
return None
|
|
284
297
|
if not _listening(port):
|
|
285
298
|
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
286
299
|
env = dict(os.environ, PYTHONPATH=root_dir + os.pathsep + os.environ.get("PYTHONPATH", ""))
|
|
@@ -294,7 +307,8 @@ def _bassa_url():
|
|
|
294
307
|
return f"http://127.0.0.1:{port}/"
|
|
295
308
|
|
|
296
309
|
|
|
297
|
-
|
|
310
|
+
BASSA_NOT_STARTED = "The BASSA model explorer did not start; run `descripytor bassa_explorer` to see why."
|
|
311
|
+
BASSA_DOWN = BASSA_NOT_STARTED # what the last failed _bassa_url() has to say
|
|
298
312
|
|
|
299
313
|
|
|
300
314
|
@app.route("/bassa_explorer")
|
|
@@ -2253,7 +2267,10 @@ def _pd_from_numpy(arr, index, columns):
|
|
|
2253
2267
|
return pd.DataFrame(arr, index=index, columns=columns)
|
|
2254
2268
|
|
|
2255
2269
|
|
|
2256
|
-
|
|
2270
|
+
# Raised whenever the pages need a route an older server does not have. A server still running from before then answers
|
|
2271
|
+
# /status with a lower number, and a new start tells the user to stop it instead of reusing it (its pages are read from
|
|
2272
|
+
# disk, so they would be new while its routes are old: the links to /feature_explorer and /bassa_explorer gave Not Found).
|
|
2273
|
+
GUI_API = 3
|
|
2257
2274
|
|
|
2258
2275
|
|
|
2259
2276
|
def _tcp_port_open(port):
|
|
@@ -2280,9 +2297,7 @@ def _status_from_running_gui(port):
|
|
|
2280
2297
|
def _gui_payload_is_current(payload):
|
|
2281
2298
|
if not isinstance(payload, dict) or not payload.get("ok"):
|
|
2282
2299
|
return False
|
|
2283
|
-
|
|
2284
|
-
return True
|
|
2285
|
-
return "example_presets" in payload and "example_reference_name" in payload
|
|
2300
|
+
return payload.get("api") == GUI_API
|
|
2286
2301
|
|
|
2287
2302
|
|
|
2288
2303
|
def _pids_listening_on_port(port):
|
|
@@ -2347,7 +2362,7 @@ def _reuse_or_refuse_existing_gui(host, port, open_browser, page="/visual"):
|
|
|
2347
2362
|
if payload is not None or _tcp_port_open(port):
|
|
2348
2363
|
pids = _pids_listening_on_port(port)
|
|
2349
2364
|
print(f"\n Port {port} is already in use by an older or different process.")
|
|
2350
|
-
print("
|
|
2365
|
+
print(" It was started before the package was updated, so it lacks the newer pages. Stop it, then run the command again.")
|
|
2351
2366
|
if pids:
|
|
2352
2367
|
print(" PID(s): " + ", ".join(pids))
|
|
2353
2368
|
if os.name == "nt":
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Is a BASSA explorer server already on a port, and is it this version's?
|
|
2
|
+
|
|
3
|
+
A server left running from before an update keeps its old code while the page it serves is read from disk, so
|
|
4
|
+
reusing it gives a new page on old routes. Everything that would reuse a running server asks here first.
|
|
5
|
+
Standard library only: the command line, the visual extractor's server and server.py all import it.
|
|
6
|
+
"""
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import socket
|
|
10
|
+
import subprocess
|
|
11
|
+
import urllib.request
|
|
12
|
+
|
|
13
|
+
API = 1 # raised whenever the page needs something an older server.py does not have
|
|
14
|
+
GUI_API_NEEDED = 3 # the lowest /status "api" of the visual extractor's server that has the pages this one links to
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def listening(port):
|
|
18
|
+
with socket.socket() as s:
|
|
19
|
+
s.settimeout(0.3)
|
|
20
|
+
return s.connect_ex(("127.0.0.1", int(port))) == 0
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _status(port):
|
|
24
|
+
try:
|
|
25
|
+
return json.loads(urllib.request.urlopen("http://127.0.0.1:%d/status" % int(port), timeout=3).read())
|
|
26
|
+
except Exception:
|
|
27
|
+
return None # no /status: something else, or a server from before this check
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def state(port):
|
|
31
|
+
"""None: nothing listens on the port. "current": this version's BASSA explorer. "old": anything else."""
|
|
32
|
+
if not listening(port):
|
|
33
|
+
return None
|
|
34
|
+
d = _status(port)
|
|
35
|
+
return "current" if isinstance(d, dict) and d.get("app") == "bassa_explorer" and d.get("api") == API else "old"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def gui_state(port):
|
|
39
|
+
"""the same for the visual extractor's server, seen from here: None, "current" or "old\""""
|
|
40
|
+
if not listening(port):
|
|
41
|
+
return None
|
|
42
|
+
d = _status(port)
|
|
43
|
+
return "current" if isinstance(d, dict) and d.get("ok") and int(d.get("api") or 0) >= GUI_API_NEEDED else "old"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def stop_hint(port, what):
|
|
47
|
+
"""what to tell the user when the port is held by an older server"""
|
|
48
|
+
pids = []
|
|
49
|
+
try:
|
|
50
|
+
if os.name == "nt":
|
|
51
|
+
out = subprocess.run(["netstat", "-ano", "-p", "tcp"], capture_output=True, text=True, timeout=4).stdout
|
|
52
|
+
for p in (line.split() for line in out.splitlines()):
|
|
53
|
+
if len(p) >= 5 and p[0].upper() == "TCP" and "LISTEN" in p[3].upper() and p[1].endswith(":%d" % int(port)) and p[-1].isdigit() and p[-1] not in pids:
|
|
54
|
+
pids.append(p[-1])
|
|
55
|
+
else:
|
|
56
|
+
pids = subprocess.run(["lsof", "-iTCP:%d" % int(port), "-sTCP:LISTEN", "-n", "-P", "-t"], capture_output=True, text=True, timeout=4).stdout.split()
|
|
57
|
+
except Exception:
|
|
58
|
+
pass
|
|
59
|
+
how = ("taskkill /PID %s /F" if os.name == "nt" else "kill %s") % " ".join(pids) if pids else "stop the process that listens on that port"
|
|
60
|
+
return ("Port %d is held by an older or different process, not by this version of %s (it was probably started before the "
|
|
61
|
+
"package was updated). Stop it, then try again: %s" % (int(port), what, how))
|
|
@@ -10,6 +10,7 @@ POST /run {csv, response, iters, name, structures} -> the same data the pa
|
|
|
10
10
|
POST /checks {csv, response} -> {job}; the reference lines and the fold counts are computed in the background
|
|
11
11
|
POST /handoff {csv, response, structures, name} -> {id}; another page (the atom picker) leaves a table here
|
|
12
12
|
GET /handoff?id=N -> that table, once: the page opened with #handoff=N runs it
|
|
13
|
+
GET /status -> {ok, app, api, sampler, cases}: lets a new start tell this server from an older one
|
|
13
14
|
GET /checks?job=N -> {done, total, chance, nested_q2, fold_top, n_folds, error}
|
|
14
15
|
POST /keep {name, case} -> writes <name>.js beside the page and lists it, so the case is there next time
|
|
15
16
|
POST /export {cases} -> one HTML file holding the page, the explorer and those cases
|
|
@@ -28,6 +29,7 @@ from urllib.parse import parse_qs, urlparse
|
|
|
28
29
|
import numpy as np, pandas as pd
|
|
29
30
|
|
|
30
31
|
import build_case as BC
|
|
32
|
+
import running as RUN
|
|
31
33
|
|
|
32
34
|
H = Path(__file__).resolve().parent; C = BC.C; LOCK = threading.Lock(); JOBS = {}; HANDOFF = {}; N_PERM, NULL_ITERS = 100, 6000
|
|
33
35
|
READER = BC.S["reader_python"]
|
|
@@ -39,13 +41,14 @@ STYLE = dict(look="descriptors", preset="glossy", palette="cylview", ink="colour
|
|
|
39
41
|
NEEDS = "new tables need the sampler: pip install bassa-reg into this Python, or start with --bassa-python <a Python that has it>" # the environment with pyarrow and the DescriPyTor readers
|
|
40
42
|
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
with socket.socket() as s: s.settimeout(0.3); return s.connect_ex(("127.0.0.1", port)) == 0
|
|
44
|
+
listening = RUN.listening
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
def gui(page):
|
|
47
|
-
"""the address of a page of the package's other server (the atom picker, the full feature explorer); that server is
|
|
48
|
+
"""the address of a page of the package's other server (the atom picker, the full feature explorer); that server is
|
|
49
|
+
started if it is not up. None when the port is held by a server from before an update: its routes would be old."""
|
|
48
50
|
port = int(os.environ.get("GUI_PORT", "7432"))
|
|
51
|
+
if RUN.gui_state(port) == "old": return None
|
|
49
52
|
if not listening(port):
|
|
50
53
|
env = dict(os.environ, PYTHONPATH=BC.S["descripytor"] + os.pathsep + os.environ.get("PYTHONPATH", ""))
|
|
51
54
|
subprocess.Popen([READER, "-m", "descripytor.cli", "visual_extractor", "--no-browser", "--port", str(port)], env=env)
|
|
@@ -136,7 +139,11 @@ class Handler(SimpleHTTPRequestHandler):
|
|
|
136
139
|
body = b'window.CASE_FILES = ["example"];\n'; self.send_response(200); self.send_header("Content-Type", "text/javascript"); self.send_header("Content-Length", str(len(body))); self.end_headers(); return self.wfile.write(body)
|
|
137
140
|
if u.path in ("/visual_extractor", "/feature_explorer", "/bassa_explorer"): # the three pages link to each other by these names
|
|
138
141
|
to = "/" if u.path == "/bassa_explorer" else gui("/visual" if u.path == "/visual_extractor" else u.path)
|
|
142
|
+
if to is None:
|
|
143
|
+
body = RUN.stop_hint(int(os.environ.get("GUI_PORT", "7432")), "the visual extractor").encode("utf-8")
|
|
144
|
+
self.send_response(503); self.send_header("Content-Type", "text/plain; charset=utf-8"); self.send_header("Content-Length", str(len(body))); self.end_headers(); return self.wfile.write(body)
|
|
139
145
|
self.send_response(302); self.send_header("Location", to); self.send_header("Content-Length", "0"); return self.end_headers()
|
|
146
|
+
if u.path == "/status": return self.answer(dict(ok=True, app="bassa_explorer", api=RUN.API, sampler=SAMPLER, cases=str(C))) # who is on this port, and which version
|
|
140
147
|
if u.path == "/handoff": q = HANDOFF.pop(parse_qs(u.query).get("id", [""])[0], None); return self.answer(q or dict(error="this table was already taken, or the server was restarted"), 200 if q else 404)
|
|
141
148
|
if u.path != "/checks": return super().do_GET()
|
|
142
149
|
job = JOBS.get(parse_qs(u.query).get("job", [""])[0]); self.answer(job or dict(error="no such job"), 200 if job else 404)
|
|
@@ -74,7 +74,7 @@ def get_local_setup_version():
|
|
|
74
74
|
from descripytor import __version__ as version
|
|
75
75
|
return version
|
|
76
76
|
except Exception:
|
|
77
|
-
return "0.3.
|
|
77
|
+
return "0.3.2"
|
|
78
78
|
|
|
79
79
|
__version__ = get_local_setup_version()
|
|
80
80
|
|
|
@@ -342,6 +342,17 @@ def run_bassa_explorer(cases=None, host=None, port=None, open_browser=True, bass
|
|
|
342
342
|
url = f"http://{'127.0.0.1' if host in ('0.0.0.0', '') else host}:{port}/"
|
|
343
343
|
print(f"\n BASSA model explorer\n Open: {url}\n Press Ctrl+C to stop\n", flush=True)
|
|
344
344
|
python = bassa_python or os.environ.get("DESCRIPYTOR_BASSA_PYTHON") or sys.executable
|
|
345
|
+
_ensure_project_on_path()
|
|
346
|
+
from M3_modeler.bassa_explorer import running
|
|
347
|
+
already = running.state(port)
|
|
348
|
+
if already == "current": # this version's server is up: use it
|
|
349
|
+
print(" It is already running; this process will not start a second server." + chr(10), flush=True)
|
|
350
|
+
if open_browser:
|
|
351
|
+
webbrowser.open(url)
|
|
352
|
+
return 0
|
|
353
|
+
if already == "old": # a server from before an update would give a new page on old routes
|
|
354
|
+
print(" " + running.stop_hint(port, "the BASSA model explorer") + chr(10), flush=True)
|
|
355
|
+
return 1
|
|
345
356
|
|
|
346
357
|
def open_when_up(): # the first import of the sampler can take a while
|
|
347
358
|
import socket
|
|
@@ -628,6 +639,6 @@ def main():
|
|
|
628
639
|
parser.print_help()
|
|
629
640
|
|
|
630
641
|
if __name__ == "__main__":
|
|
631
|
-
main()
|
|
642
|
+
sys.exit(main()) # as the installed command does: a refused start exits with 1
|
|
632
643
|
|
|
633
644
|
|
|
@@ -150,6 +150,7 @@ M3_modeler/bassa_explorer/example_small.csv
|
|
|
150
150
|
M3_modeler/bassa_explorer/index.html
|
|
151
151
|
M3_modeler/bassa_explorer/influence_check.py
|
|
152
152
|
M3_modeler/bassa_explorer/read_structures.py
|
|
153
|
+
M3_modeler/bassa_explorer/running.py
|
|
153
154
|
M3_modeler/bassa_explorer/server.py
|
|
154
155
|
M3_modeler/bassa_explorer/settings.py
|
|
155
156
|
M3_modeler/bassa_explorer/test_page.py
|
|
@@ -86,38 +86,92 @@ def test_the_three_pages_have_one_address_each(server):
|
|
|
86
86
|
assert 'href="/feature_explorer"' in picker and 'href="/bassa_explorer"' in picker
|
|
87
87
|
explorer = (ROOT / "M2_data_extractor" / "feature_explorer" / "template.html").read_text(encoding="utf-8")
|
|
88
88
|
assert 'href="/visual_extractor"' in explorer and 'href="/bassa_explorer"' in explorer
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def test_a_table_left_by_another_page_is_taken_once(server):
|
|
92
|
-
"""The picker's one-click hand-off: POST /handoff leaves a table, the page opened with #handoff=id takes it."""
|
|
93
|
-
url, _ = server
|
|
94
|
-
body = dict(csv=(TOOL / "example_small.csv").read_text(), response="ddG", structures="", name="extracted")
|
|
95
|
-
q = urllib.request.Request(url + "handoff", data=json.dumps(body).encode(), headers={"Content-Type": "application/json"})
|
|
96
|
-
token = json.loads(urllib.request.urlopen(q, timeout=30).read())["id"]
|
|
97
|
-
got = json.loads(_get(url + "handoff?id=" + token))
|
|
98
|
-
assert got["response"] == "ddG" and got["csv"] == body["csv"]
|
|
99
|
-
with pytest.raises(urllib.error.HTTPError) as e:
|
|
100
|
-
_get(url + "handoff?id=" + token)
|
|
101
|
-
assert e.value.code == 404
|
|
102
|
-
bad = urllib.request.Request(url + "handoff", data=json.dumps(dict(csv="name,a,y\nm1,1,2\n", response="y")).encode(), headers={"Content-Type": "application/json"})
|
|
103
|
-
with pytest.raises(urllib.error.HTTPError) as e: # a table a run would refuse is refused at the door
|
|
104
|
-
urllib.request.urlopen(bad, timeout=30)
|
|
105
|
-
assert "at least 6 compounds" in json.loads(e.value.read())["error"]
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def test_the_extractor_s_own_column_names_are_drawn():
|
|
109
|
-
"""A table straight from `descripytor extractor` / the visual extractor: its dipole, Sterimol and vibration columns map to drawings."""
|
|
110
|
-
code = (
|
|
111
|
-
"import build_case as B\n"
|
|
112
|
-
"want = {'dipole_x_1-2-19': 'dipole', 'total_dipole_1-2-19': 'dipole_total', 'loc_B1_1-4': 'sterimol', 'B1_B5_azimuth_4-1': 'sterimol',\n"
|
|
113
|
-
" 'B1_B5_acute_1-4': 'sterimol', 'Frequency_Stretch_1_2': 'mark', 'Frequency_Bending_5-6': 'mark', 'Cross_mag_Bending_5-6': 'mark',\n"
|
|
114
|
-
" 'cross_9_0': 'mark', 'cross_angle_9_0': 'mark', 'para_9_0': 'mark', 'para_angle_9_0': 'mark', 'B1_1-4': 'sterimol',\n"
|
|
115
|
-
" '0_bond_length_1-2': 'bond_length', 'nbo_atom_3': 'charge', 'nbo_diff_3-5': 'charge_diff'}\n"
|
|
116
|
-
"for c, k in want.items():\n"
|
|
117
|
-
" w = B.drawing(c); assert w and w['kind'] == k, (c, w)\n"
|
|
118
|
-
" assert B.label(c, w) != c and B.describe(c, w)\n"
|
|
119
|
-
"d = B.drawing('dipole_y_20-19-27'); assert (d['origin'], d['y'], d['plane'], d['comp']) == (20, 19, 27, 'u')\n"
|
|
120
|
-
"assert B.drawing('cross_9_0')['atoms'] == [9] and B.drawing('aniso') is None and B.label('aniso', None) != 'aniso'\n"
|
|
121
|
-
)
|
|
122
|
-
r = subprocess.run([sys.executable, "-c", code], cwd=str(TOOL), capture_output=True, text=True)
|
|
123
|
-
assert r.returncode == 0, r.stderr[-600:]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_a_table_left_by_another_page_is_taken_once(server):
|
|
92
|
+
"""The picker's one-click hand-off: POST /handoff leaves a table, the page opened with #handoff=id takes it."""
|
|
93
|
+
url, _ = server
|
|
94
|
+
body = dict(csv=(TOOL / "example_small.csv").read_text(), response="ddG", structures="", name="extracted")
|
|
95
|
+
q = urllib.request.Request(url + "handoff", data=json.dumps(body).encode(), headers={"Content-Type": "application/json"})
|
|
96
|
+
token = json.loads(urllib.request.urlopen(q, timeout=30).read())["id"]
|
|
97
|
+
got = json.loads(_get(url + "handoff?id=" + token))
|
|
98
|
+
assert got["response"] == "ddG" and got["csv"] == body["csv"]
|
|
99
|
+
with pytest.raises(urllib.error.HTTPError) as e:
|
|
100
|
+
_get(url + "handoff?id=" + token)
|
|
101
|
+
assert e.value.code == 404
|
|
102
|
+
bad = urllib.request.Request(url + "handoff", data=json.dumps(dict(csv="name,a,y\nm1,1,2\n", response="y")).encode(), headers={"Content-Type": "application/json"})
|
|
103
|
+
with pytest.raises(urllib.error.HTTPError) as e: # a table a run would refuse is refused at the door
|
|
104
|
+
urllib.request.urlopen(bad, timeout=30)
|
|
105
|
+
assert "at least 6 compounds" in json.loads(e.value.read())["error"]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_the_extractor_s_own_column_names_are_drawn():
|
|
109
|
+
"""A table straight from `descripytor extractor` / the visual extractor: its dipole, Sterimol and vibration columns map to drawings."""
|
|
110
|
+
code = (
|
|
111
|
+
"import build_case as B\n"
|
|
112
|
+
"want = {'dipole_x_1-2-19': 'dipole', 'total_dipole_1-2-19': 'dipole_total', 'loc_B1_1-4': 'sterimol', 'B1_B5_azimuth_4-1': 'sterimol',\n"
|
|
113
|
+
" 'B1_B5_acute_1-4': 'sterimol', 'Frequency_Stretch_1_2': 'mark', 'Frequency_Bending_5-6': 'mark', 'Cross_mag_Bending_5-6': 'mark',\n"
|
|
114
|
+
" 'cross_9_0': 'mark', 'cross_angle_9_0': 'mark', 'para_9_0': 'mark', 'para_angle_9_0': 'mark', 'B1_1-4': 'sterimol',\n"
|
|
115
|
+
" '0_bond_length_1-2': 'bond_length', 'nbo_atom_3': 'charge', 'nbo_diff_3-5': 'charge_diff'}\n"
|
|
116
|
+
"for c, k in want.items():\n"
|
|
117
|
+
" w = B.drawing(c); assert w and w['kind'] == k, (c, w)\n"
|
|
118
|
+
" assert B.label(c, w) != c and B.describe(c, w)\n"
|
|
119
|
+
"d = B.drawing('dipole_y_20-19-27'); assert (d['origin'], d['y'], d['plane'], d['comp']) == (20, 19, 27, 'u')\n"
|
|
120
|
+
"assert B.drawing('cross_9_0')['atoms'] == [9] and B.drawing('aniso') is None and B.label('aniso', None) != 'aniso'\n"
|
|
121
|
+
)
|
|
122
|
+
r = subprocess.run([sys.executable, "-c", code], cwd=str(TOOL), capture_output=True, text=True)
|
|
123
|
+
assert r.returncode == 0, r.stderr[-600:]
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@pytest.fixture()
|
|
127
|
+
def other_server():
|
|
128
|
+
"""Something else on a port: no /status of ours, as a BASSA explorer from before the check, or any other program."""
|
|
129
|
+
with socket.socket() as s:
|
|
130
|
+
s.bind(("127.0.0.1", 0)); port = s.getsockname()[1]
|
|
131
|
+
p = subprocess.Popen([sys.executable, "-m", "http.server", str(port), "--bind", "127.0.0.1"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
132
|
+
try:
|
|
133
|
+
for _ in range(60):
|
|
134
|
+
try: urllib.request.urlopen(f"http://127.0.0.1:{port}/", timeout=2); break
|
|
135
|
+
except Exception: time.sleep(0.25)
|
|
136
|
+
yield port
|
|
137
|
+
finally:
|
|
138
|
+
p.kill()
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _running():
|
|
142
|
+
sys.path.insert(0, str(ROOT))
|
|
143
|
+
from M3_modeler.bassa_explorer import running
|
|
144
|
+
return running
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_a_running_server_says_which_version_it_is(server):
|
|
148
|
+
url, _ = server
|
|
149
|
+
running = _running()
|
|
150
|
+
st = json.loads(_get(url + "status"))
|
|
151
|
+
assert st["app"] == "bassa_explorer" and st["api"] == running.API
|
|
152
|
+
port = int(url.rsplit(":", 1)[1].strip("/"))
|
|
153
|
+
assert running.state(port) == "current"
|
|
154
|
+
with socket.socket() as s:
|
|
155
|
+
s.bind(("127.0.0.1", 0)); free = s.getsockname()[1]
|
|
156
|
+
assert running.state(free) is None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def test_an_older_server_on_the_port_is_not_reused(other_server):
|
|
160
|
+
"""A server left from before an update would serve the new page on old routes; every way in refuses it and says how to stop it."""
|
|
161
|
+
running = _running()
|
|
162
|
+
assert running.state(other_server) == "old"
|
|
163
|
+
assert str(other_server) in running.stop_hint(other_server, "the BASSA model explorer")
|
|
164
|
+
# the command
|
|
165
|
+
r = subprocess.run([sys.executable, "-m", "descripytor.cli", "bassa_explorer", "--no-browser", "--port", str(other_server)],
|
|
166
|
+
cwd=str(ROOT), capture_output=True, text=True, timeout=120)
|
|
167
|
+
assert r.returncode == 1 and "older or different process" in r.stdout
|
|
168
|
+
# the visual extractor's link and its one-click hand-off
|
|
169
|
+
env = dict(os.environ, BASSA_EXPLORER_PORT=str(other_server))
|
|
170
|
+
code = ("import sys; sys.path.insert(0, %r)\n"
|
|
171
|
+
"import M2_data_extractor.gui_server as gs\n"
|
|
172
|
+
"c = gs.app.test_client()\n"
|
|
173
|
+
"r = c.get('/bassa_explorer'); assert r.status_code == 503 and b'older or different process' in r.data, r.data\n"
|
|
174
|
+
"csv = 'name,a,b,c,d,y' + chr(10) + chr(10).join('m%%d,%%d,%%d,%%d,%%d,%%d' %% (i, i, i * i %% 7, i * 3 %% 5, i * 5 %% 11, i %% 4) for i in range(8))\n"
|
|
175
|
+
"r = c.post('/bassa_explorer/handoff', json={'csv': csv, 'y_column': 'y'}); assert r.status_code == 503 and 'older' in r.get_json()['error'], r.data\n") % str(ROOT)
|
|
176
|
+
r = subprocess.run([sys.executable, "-c", code], env=env, capture_output=True, text=True, timeout=120)
|
|
177
|
+
assert r.returncode == 0, r.stderr[-800:]
|
|
@@ -40,7 +40,8 @@ def test_status(client):
|
|
|
40
40
|
assert response.status_code == 200
|
|
41
41
|
payload = response.get_json()
|
|
42
42
|
assert payload["ok"] is True
|
|
43
|
-
|
|
43
|
+
from M2_data_extractor.gui_server import GUI_API
|
|
44
|
+
assert payload.get("api") == GUI_API
|
|
44
45
|
assert "example_feather_dir" in payload
|
|
45
46
|
assert "example_outcomes" in payload
|
|
46
47
|
assert "example_presets" in payload
|
|
@@ -625,15 +626,11 @@ def test_placeholder_path_ignores_double_underscore_in_real_paths():
|
|
|
625
626
|
|
|
626
627
|
|
|
627
628
|
def test_gui_payload_is_current():
|
|
628
|
-
from M2_data_extractor.gui_server import _gui_payload_is_current
|
|
629
|
+
from M2_data_extractor.gui_server import GUI_API, _gui_payload_is_current
|
|
629
630
|
|
|
630
631
|
assert not _gui_payload_is_current({"ok": True, "version": "1.0"})
|
|
631
|
-
assert _gui_payload_is_current({"ok": True, "api":
|
|
632
|
-
assert _gui_payload_is_current({
|
|
633
|
-
"ok": True,
|
|
634
|
-
"example_presets": {},
|
|
635
|
-
"example_reference_name": "basic",
|
|
636
|
-
})
|
|
632
|
+
assert _gui_payload_is_current({"ok": True, "api": GUI_API})
|
|
633
|
+
assert not _gui_payload_is_current({"ok": True, "api": GUI_API - 1}) # a server from before the last update
|
|
637
634
|
assert not _gui_payload_is_current(None)
|
|
638
635
|
|
|
639
636
|
|
|
@@ -740,23 +737,33 @@ def test_the_old_explorer_folder_still_imports():
|
|
|
740
737
|
def test_visual_extractor_address_is_the_picker():
|
|
741
738
|
r = _load_app().test_client().get("/visual_extractor")
|
|
742
739
|
assert r.status_code == 302 and r.headers["Location"].endswith("/visual")
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
def test_handoff_needs_a_table_and_a_target():
|
|
746
|
-
client = _load_app().test_client()
|
|
747
|
-
assert "Extract features first" in client.post("/bassa_explorer/handoff", json={}).get_json()["error"]
|
|
748
|
-
r = client.post("/bassa_explorer/handoff", json={"csv": "name,a\nm1,1\nm2,2\n"})
|
|
749
|
-
assert r.status_code == 400 and "target" in r.get_json()["error"]
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
def test_the_extraction_engine_is_inside_the_package():
|
|
753
|
-
"""Extract CSV runs descriptor_extractor; an installed package has no examples folder, so it must sit in M2_data_extractor."""
|
|
754
|
-
app = _load_app()
|
|
755
|
-
import M2_data_extractor.gui_server as gs
|
|
756
|
-
dx = gs._load_descriptor_extractor()
|
|
757
|
-
assert Path(dx.__file__).resolve().parent == ROOT / "M2_data_extractor"
|
|
758
|
-
assert (ROOT / "M2_data_extractor" / "feature_packages.py").is_file()
|
|
759
|
-
import subprocess, sys
|
|
760
|
-
old = ROOT / "Getting_started_with_examples" / "descriptor_extraction_toolkit"
|
|
761
|
-
code = "import sys; sys.path.insert(0, %r); import descriptor_extractor as d, feature_packages as f; assert d.run_from_config and f" % str(old)
|
|
762
|
-
assert subprocess.run([sys.executable, "-c", code]).returncode == 0 # the toolkit's old import path still works
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
def test_handoff_needs_a_table_and_a_target():
|
|
743
|
+
client = _load_app().test_client()
|
|
744
|
+
assert "Extract features first" in client.post("/bassa_explorer/handoff", json={}).get_json()["error"]
|
|
745
|
+
r = client.post("/bassa_explorer/handoff", json={"csv": "name,a\nm1,1\nm2,2\n"})
|
|
746
|
+
assert r.status_code == 400 and "target" in r.get_json()["error"]
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
def test_the_extraction_engine_is_inside_the_package():
|
|
750
|
+
"""Extract CSV runs descriptor_extractor; an installed package has no examples folder, so it must sit in M2_data_extractor."""
|
|
751
|
+
app = _load_app()
|
|
752
|
+
import M2_data_extractor.gui_server as gs
|
|
753
|
+
dx = gs._load_descriptor_extractor()
|
|
754
|
+
assert Path(dx.__file__).resolve().parent == ROOT / "M2_data_extractor"
|
|
755
|
+
assert (ROOT / "M2_data_extractor" / "feature_packages.py").is_file()
|
|
756
|
+
import subprocess, sys
|
|
757
|
+
old = ROOT / "Getting_started_with_examples" / "descriptor_extraction_toolkit"
|
|
758
|
+
code = "import sys; sys.path.insert(0, %r); import descriptor_extractor as d, feature_packages as f; assert d.run_from_config and f" % str(old)
|
|
759
|
+
assert subprocess.run([sys.executable, "-c", code]).returncode == 0 # the toolkit's old import path still works
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
def test_a_server_from_before_the_update_is_not_reused():
|
|
763
|
+
"""Its pages are read from disk (new) while its routes are old: the header links gave Not Found."""
|
|
764
|
+
_load_app()
|
|
765
|
+
import M2_data_extractor.gui_server as gs
|
|
766
|
+
old = {"ok": True, "api": 2, "example_presets": {}, "example_reference_name": "basic"}
|
|
767
|
+
assert not gs._gui_payload_is_current(old)
|
|
768
|
+
assert gs._gui_payload_is_current({"ok": True, "api": gs.GUI_API})
|
|
769
|
+
assert _load_app().test_client().get("/status").get_json()["api"] == gs.GUI_API
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/examples/phosphines.csv
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M1_pre_calculations/pipeline/examples/protocol_bgu.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/bond_angle_length_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/extractor_utils/vibrations_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/feature_explorer.html
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/009_phos.xyz
RENAMED
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/026_box_CuCl.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/026_lig.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/032_lig.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/041_lig.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/045_box_CuCl.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/045_lig.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/046_lig.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/055_phos.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_008.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_018.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_020.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_BOX_047.xyz
RENAMED
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/Cu_PyOx_041.xyz
RENAMED
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_1.xyz
RENAMED
|
File without changes
|
|
File without changes
|
{descripytor-0.3.1 → descripytor-0.3.2}/M2_data_extractor/feature_explorer/fixtures/FL_lig_12.xyz
RENAMED
|
File without changes
|