numpy<3.0,>=1.24 PySide6<7.0,>=6.5 qtpy<3.0,>=2.3 python-dateutil<3.0,>=2.8 certifi>=2023.7.22 requests<3.0,>=2.28 metpy<2.0,>=1.5 ecape<1.0,>=0.1 [dev] pytest>=7.0 hypothesis>=6.0 [rust-build] maturin>=1.9,<2 [era5] herbie-data cfgrib xarray [render] requests<3.0,>=2.28 [wrf] xarray netCDF4 =========================================================================== SHARPpy Reimagined — INSTALLATION REFERENCE =========================================================================== Everything you need to INSTALL and run SHARPpy Reimagined is listed here. - How to USE the tools ..................... docs/USAGE.md - Narrative install walkthrough ........... README.md ("Installation") - Rust-primary backend and fallback ........ docs/RUST_BACKEND.md The Python import package is still named `sharpmod` (that is the module name and the pip distribution name); "SHARPpy Reimagined" is the project name. --------------------------------------------------------------------------- 1. SYSTEM REQUIREMENTS --------------------------------------------------------------------------- - Python >= 3.11 (64-bit; use 3.11-3.13 for Windows source GUI runs) - pip >= 23 (needed for editable installs + modern resolver) - OS : Windows, Linux, or macOS - Disk : ~1.5 GB for the full render + scientific stack - Network : required for `pip install`, UWyo fetch, and ERA5 retrieval - Display : required ONLY for the interactive desktop GUI (`sharpmod-gui`); CLI rendering runs headless (Qt "offscreen") and needs no display - Rust : stable 1.88+ toolchain required ONLY to build `sharpmod_rs` locally; official Windows binaries include the extension, and Python-fallback installs do not need a Rust toolchain --------------------------------------------------------------------------- 2. QUICK INSTALL (copy/paste) --------------------------------------------------------------------------- # 1) core library + CLI tools + render transitive deps pip install -e ".[render]" # 2) rendering engine (separate step — see section 4 for why) pip install --no-deps "SHARPpy==1.4.0a5" # 3) optional, only if you need them pip install -e ".[era5]" # ERA5 point-sounding extraction pip install -e ".[wrf]" # WRF-ARW (wrfout NetCDF) extraction pip install -e ".[dev]" # run the test suite pip install -e ".[rust-build]" # maturin frontend for a local Rust build On Windows, create/activate a venv first: py -3.11 -m venv .venv .venv\Scripts\activate --------------------------------------------------------------------------- 3. CORE RUNTIME LIBRARIES (installed by `pip install -e .`) --------------------------------------------------------------------------- Package Version pin Purpose ---------------- --------------- ------------------------------------- numpy >=1.24,<3.0 arrays / numerical math PySide6 >=6.5,<7.0 Qt6 GUI toolkit (used for rendering) qtpy >=2.3,<3.0 Qt binding abstraction layer python-dateutil >=2.8,<3.0 flexible date/time parsing certifi >=2023.7.22 CA bundle for verified HTTPS fetches requests >=2.28,<3.0 HTTP (UWyo + SHARPpy datasources) metpy >=1.5,<2.0 meteorological calcs (ECAPE reference) ecape >=0.1,<1.0 entraining CAPE implementation Notable second-level libraries pulled in automatically (mainly by MetPy and PySide6), listed for offline mirrors / air-gapped installs: shiboken6, PySide6-Essentials, PySide6-Addons (Qt6 runtime) pandas, scipy, matplotlib, xarray, pint, pooch, pyproj, contourpy, kiwisolver, fonttools, cycler, pillow, pyparsing, packaging, platformdirs, flexcache, flexparser, traitlets, six, tzdata, urllib3, idna, charset-normalizer, typing-extensions (plus their own transitive dependencies) --------------------------------------------------------------------------- 4. RENDERING ENGINE — upstream SHARPpy (installed with --no-deps) --------------------------------------------------------------------------- Package : SHARPpy==1.4.0a5 Provides: sharppy, sutils, datasources, runsharp Install : pip install --no-deps "SHARPpy==1.4.0a5" WHY A SEPARATE --no-deps STEP: SHARPpy 1.4.0a5's wheel metadata pins `numpy==1.15.*`, which conflicts with the modern NumPy required above (a normal `pip install SHARPpy` would fail to resolve, or try to downgrade NumPy and break everything). Its real runtime needs — python-dateutil, requests, numpy — are ALREADY provided by the core install, so --no-deps is safe. NEEDED ONLY FOR RENDERING (`sharpmod-render` or any `--render` flag). Fetching/extracting soundings does NOT require it. --------------------------------------------------------------------------- 5. OPTIONAL EXTRAS --------------------------------------------------------------------------- [era5] ERA5 reanalysis and public forecast-model point extraction cdsapi, herbie-data, cfgrib, ecCodes, xarray, numcodecs, pyproj [wrf] WRF-ARW (wrfout NetCDF) point-sounding extraction xarray, netCDF4 [dev] test tooling pytest>=7.0, hypothesis>=6.0, PyYAML>=6.0,<7.0 [rust-build] local native-extension build frontend maturin>=1.9,<2 (install the stable Rust toolchain separately) --------------------------------------------------------------------------- 6. RUST-PRIMARY BACKEND AND PYTHON FALLBACK --------------------------------------------------------------------------- Official v0.4 Windows executables bundle the supported `sharpmod_rs` extension. The default `auto` mode validates and selects Rust when that extension is present. The independently optimized Python implementation remains a fully functional portable fallback, so a source or Python-only installation works without Rust, Cargo, maturin, or `sharpmod_rs`. To build the extension locally, install Rust 1.88 or newer on the stable channel first, then use the same Python environment that runs `sharpmod`: pip install -e ".[rust-build]" sharpmod-rust-sync sharpmod-rust-sync --check The default command rebuilds only when the extension is missing or its installed version does not match the checkout, then verifies forced Rust in a fresh Python process. --check never modifies the environment; use sharpmod-rust-sync --force after changing native source. Lower-level extension-development command: cd rust/sharpmod-rs maturin develop --release --locked cd ../.. Set SHARPMOD_BACKEND before starting Python or the GUI: auto default; use Rust when loadable, otherwise use Python and retain the fallback reason python force the optimized Python backend rust require Rust; fail clearly if the extension is absent or broken Local forecast GRIB decoding defaults to direct point extraction with a safe xarray fallback. Set SHARPMOD_GRIB_DECODER=xarray to force the compatibility path or SHARPMOD_GRIB_DECODER=direct to make a direct-decode failure explicit. PowerShell: $env:SHARPMOD_BACKEND = "rust" POSIX shell: export SHARPMOD_BACKEND=rust Inspect the requested/active backend, extension version, and fallback reason: python -c "from sharpmod.backends import backend_info; print(backend_info())" The official v0.4 release workflow builds and installs `sharpmod_rs` before PyInstaller runs, so the published executable uses Rust in `auto` mode. A custom local build collects a compatible installed extension when present; otherwise it logs a warning and produces a fully functional Python-fallback executable. Source-build steps, tests, platform status, and limitations are documented in docs/RUST_BACKEND.md. --------------------------------------------------------------------------- 7. WHAT YOU NEED FOR EACH TASK --------------------------------------------------------------------------- Task Core +SHARPpy +extra ------------------------------------- ----- --------- ---------- Run the interactive GUI (sharpmod-gui) yes YES - List / search / fetch UWyo soundings yes no - Render a sounding to PNG yes YES - Extract an ERA5 point sounding yes no [era5] Extract a WRF-ARW point sounding yes no [wrf] Run the test suite yes YES [dev] Build the Rust backend locally yes no [rust-build] + Rust --------------------------------------------------------------------------- 8. CONSOLE COMMANDS INSTALLED --------------------------------------------------------------------------- sharpmod-gui interactive desktop app (station map / list / open file) sharpmod-render render a sounding file to PNG uwyo-sounding list / search / fetch University of Wyoming soundings era5-extract ERA5 point sounding -> .npz wrf-extract WRF-ARW point sounding -> .npz sharpmod-rust-sync check / repair / verify the local Rust extension (sharpmod-gui is a windowed/no-console entry point; it needs a display and the SHARPpy render stack from section 4.) --------------------------------------------------------------------------- 9. VERIFY THE INSTALL --------------------------------------------------------------------------- # imports resolve python -c "import sharpmod, sharppy, sutils; print('imports OK')" # backend selection resolves (works with or without the Rust extension) python -c "from sharpmod.backends import backend_info; print(backend_info())" # render a bundled example (needs the SHARPpy step) sharpmod-render examples/soundings/hrrr_point_36.68N_95.66W_f018.npz out.png # full test suite (needs [dev] + the SHARPpy step) pytest --------------------------------------------------------------------------- 10. TROUBLESHOOTING --------------------------------------------------------------------------- - "No module named sharppy/sutils" or a Qt enum error when rendering: pip install --no-deps "SHARPpy==1.4.0a5" - ResolutionImpossible mentioning numpy==1.15: you tried to install SHARPpy WITHOUT --no-deps; use the --no-deps form. - ImportError for herbie/cfgrib or netCDF4: install the matching extra: pip install -e ".[era5]" / ".[wrf]" - ERA5 reports missing CDS API credentials: create a free CDS account, accept the ERA5 pressure-level licence, then copy the profile from https://cds.climate.copernicus.eu/how-to-api into %USERPROFILE%\.cdsapirc (Windows) or $HOME/.cdsapirc. - A blank window / QpaPlatform error on a headless server: ensure QT_QPA_PLATFORM=offscreen (the renderer sets this by default). - SHARPMOD_BACKEND=rust reports that sharpmod_rs is unavailable: activate the source environment and run sharpmod-rust-sync, or use SHARPMOD_BACKEND=auto/python when a native build is not wanted. - An invalid SHARPMOD_BACKEND value raises ValueError: use exactly auto, python, or rust.