--------------------------------------------------------------------------- REQUIREMENT SUMMARY (mirrors pyproject.toml; that file is authoritative) Kept in this form for offline mirrors and air-gapped installs. --------------------------------------------------------------------------- numpy>=1.24,<3.0 PySide6>=6.5,<7.0 qtpy>=2.3,<3.0 python-dateutil>=2.8,<3.0 certifi>=2023.7.22 requests>=2.28,<3.0 Pillow>=10,<13 netCDF4>=1.7,<2.0 pyproj>=3.5,<4.0 metpy>=1.5,<2.0 ecape>=0.1,<1.0 [era5] cdsapi>=0.7.7,<0.8 herbie-data>=2026.3,<2027.0 cfgrib>=0.9.15,<0.10 eccodes>=2.48,<3.0 xarray>=2026.4,<2027.0 numcodecs>=0.11,<1.0 [wrf] xarray>=2024.7,<2027.0 [render] requests>=2.28,<3.0 [dev] pytest>=7.0,<10.0 hypothesis>=6.0,<7.0 pytest-xdist>=3.6,<4.0 pytest-timeout>=2.4,<3.0 PyYAML>=6.0,<7.0 [quality] pip-audit==2.10.1 pytest-cov==7.1.0 ruff==0.16.9 [rust-build] maturin>=1.15,<2 =========================================================================== SHARPpy Reimagined — INSTALLATION REFERENCE =========================================================================== Everything you need to INSTALL and run SHARPpy Reimagined is listed here. - How to USE the tools ..................... docs/USAGE.md - Short source setup ....................... README.md ("Get started") - 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,<3.14 (64-bit; supported versions are 3.11-3.13) - 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) --------------------------------------------------------------------------- # Core library + render dependencies + verified SHARPpy compatibility wheel. # This command finishes by running `pip check`. python scripts/install_sharppy_compat.py # Optional, only if you need them pip install -e ".[era5]" # forecast-model, area, and ERA5 extraction pip install -e ".[wrf]" # WRF-ARW (wrfout NetCDF) extraction pip install -e ".[dev]" # run the test suite pip install -e ".[quality]" # ruff, pip-audit, coverage pip install -e ".[rust-build]" # maturin frontend for a local Rust build pip install -e ".[render]" # accepted, but installs nothing new: its one # requirement (requests) is a core dependency. # Kept so older instructions keep working. 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) Pillow >=10,<13 self-contained GIF animation exports netCDF4 >=1.7,<2.0 GOES ABI fixed-grid file reader pyproj >=3.5,<4.0 GOES geostationary geolocation 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, 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 — verified upstream SHARPpy compatibility wheel --------------------------------------------------------------------------- Package : SHARPpy==1.4.0a5 Provides: sharppy, sutils, datasources, runsharp Install : python scripts/install_sharppy_compat.py WHY THE COMPATIBILITY INSTALLER IS REQUIRED: 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). Installing it with `--no-deps` avoids the downgrade but leaves a broken environment according to `pip check`. `scripts/install_sharppy_compat.py` pins the exact official wheel by URL, byte size, and SHA-256; validates every upstream RECORD entry; changes only the stale NumPy requirement to `numpy>=1.24,<3.0`; embeds an audit record; regenerates RECORD; installs the result; and requires `pip check` to pass. Every upstream package/data byte is retained unchanged. For offline use, pass `--source-wheel PATH`; use `--wheel-dir DIR --build-only` to retain an auditable corrected wheel without installing it. NEEDED ONLY FOR RENDERING (`sharpmod-render` or any `--render` flag). Fetching/extracting soundings does NOT require it. --------------------------------------------------------------------------- 5. OPTIONAL EXTRAS --------------------------------------------------------------------------- [era5] ERA5 reanalysis AND every public forecast-model extraction, which means the forecast-model tab, area/box soundings, and the gridded HRRR map fields all need this extra -- the model download library (herbie-data) and the GRIB readers live here, not in the core. cdsapi, herbie-data, cfgrib, ecCodes, xarray, numcodecs [wrf] WRF-ARW (wrfout NetCDF) point-sounding extraction xarray (the core runtime already provides netCDF4) [render] HTTP for the render path requests>=2.28,<3.0 [dev] test tooling pytest>=7.0,<10.0, hypothesis>=6.0,<7.0, pytest-xdist>=3.6,<4.0 (the -n/--workers parallel lanes), pytest-timeout>=2.4,<3.0 (the per-test safety timeout), PyYAML>=6.0,<7.0 [quality] lint, audit, and coverage, pinned exactly so a report is reproducible across machines ruff==0.16.9, pip-audit==2.10.1, pytest-cov==7.1.0 [rust-build] local native-extension build frontend maturin>=1.15,<2 (install the stable Rust toolchain separately) --------------------------------------------------------------------------- 6. RUST-PRIMARY BACKEND AND PYTHON FALLBACK --------------------------------------------------------------------------- Official 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 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 a forecast-model point sounding yes no [era5] Extract an area/box sounding yes no [era5] Draw gridded model fields on the map yes no [era5] Show radar or the SPC outlook on the map yes no - Show GOES / NWS surface map context yes no - Extract an ERA5 point sounding yes no [era5] Extract a WRF-ARW point sounding yes no [wrf] Run the test suite yes YES [dev] Lint / audit / coverage yes no [quality] Build the Rust backend locally yes no [rust-build] + Rust Note that [era5] is named for its first use but now carries every gridded model path: HRRR, RAP, NAM, GFS, RRFS, RDPS, the area/box sampler, and the map field overlays all go through the same download and GRIB stack. --------------------------------------------------------------------------- 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 observed-sounding fetch an observed sounding -> .npz model-extract forecast-model point sounding -> .npz [era5] model-batch-extract many model point soundings in one run -> .npz [era5] box-extract area/box sample over a model grid -> .npz [era5] era5-extract ERA5 point sounding -> .npz [era5] wrf-extract WRF-ARW point sounding -> .npz [wrf] 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. The commands marked [era5] need that extra, for the reason given in section 5.) --------------------------------------------------------------------------- 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: python scripts/install_sharppy_compat.py - ResolutionImpossible mentioning numpy==1.15: do not install the upstream wheel directly; use the compatibility installer above, which preserves its payload and fixes its metadata. - 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. - A model fetch logs "herbie.source_failed source=... trying the next source": informational, not an error. Each model file is mirrored on several archives and one of them was unreachable, so the next was used. Only "herbie.all_sources_failed" means nothing could be reached, which points at local networking (proxy, DNS, or TLS interception) rather than at the run being absent. - A model fetch appears to hang with no progress: the mirror signing service can accept a connection and then not answer, and the pinned download library sets no timeout on that request. Cancel and retry; a fix is in flight upstream as Herbie PR #554.