psann


Namepsann JSON
Version 0.10.9 PyPI version JSON
download
home_pageNone
SummaryPSANN: Parameterized Sine-Activated Neural Networks (primary-output, sklearn-style, PyTorch backend)
upload_time2025-10-22 11:27:52
maintainerNone
docs_urlNone
authorNicholas Milinkovich
requires_python>=3.9
licenseMIT License Copyright (c) 2025 Nicholas Milinkovich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords classification neural-networks pytorch regression sine siren sklearn time-series
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PSANN - Parameterized Sine-Activated Neural Networks

PSANN packages sine-activated Torch models behind a sklearn-style estimator surface. The stack combines:
- learnable sine activations with SIREN-friendly initialisation,
- optional learned sparse (LSM) expanders and scalers,
- persistent state controllers for streaming inference, and
- Horizon-Informed Sampling Strategy Optimisation (HISSO) for episodic training.

The current line targets **primary outputs only** so there are no predictive extras, secondary heads, or legacy growth schedules to maintain.

Quick links:
- API reference: `docs/API.md`
- Scenario walkthroughs: `docs/examples/README.md`
- Migration notes: `docs/migration.md`
- Results compendium: `docs/PSANN_Results_Compendium.md`
- Contributor guide: `docs/CONTRIBUTING.md`
- Technical design notes: `TECHNICAL_DETAILS.md`

## Installation

```bash
python -m venv .venv
.\.venv\Scripts\Activate.ps1   # Windows PowerShell
# source .venv/bin/activate     # macOS/Linux
pip install --upgrade pip
pip install -e .                # editable install from source
```

Optional extras in `pyproject.toml`:
- `psann[sklearn]`: adds scikit-learn conveniences for estimator mixins and metrics.
- `psann[viz]`: plotting helpers used in benchmarks and notebooks.
- `psann[dev]`: pytest, ruff, black, coverage, build, pre-commit tooling.

Need pre-pinned builds (e.g. on Windows or air-gapped envs)? Use the compatibility extra:

```bash
pip install -e .[compat]
```

The `compat` extra pins NumPy, SciPy, scikit-learn, and PyTorch to the newest widely available wheels while keeping `pyproject.toml` as the single source of truth.

## Running Tests

Install the development extras in editable mode so the test suite imports the packaged code without manual `sys.path` tweaks:

```bash
pip install -e .[dev]
python -m pytest
```

HISSO integration suites are marked as `slow`; skip them during quick iterations with:

```bash
python -m pytest -m "not slow"
```

The suite exercises the supported supervised, streaming, and HISSO flows. GPU-specific checks are skipped automatically when CUDA is unavailable.

Common linting commands:

```bash
python -m ruff check src tests scripts examples
python -m black --check src tests scripts examples
```

Set up local hooks (formatting, linting, notebook output stripping) with `pre-commit`:

```bash
pre-commit install
pre-commit run --all-files  # optional one-time sweep
```

## Quick Start

### Supervised regression

```python
import numpy as np
from psann import PSANNRegressor

rs = np.random.RandomState(42)
X = np.linspace(-4, 4, 1000, dtype=np.float32).reshape(-1, 1)
y = 0.8 * np.exp(-0.25 * np.abs(X)) * np.sin(3.5 * X)

model = PSANNRegressor(
    hidden_layers=2,
    hidden_units=64,
    epochs=200,
    lr=1e-3,
    early_stopping=True,
    patience=20,
    random_state=42,
)
model.fit(X, y, verbose=1)
print("R^2:", model.score(X, y))
```

Behind the scenes the estimator normalises arguments via `normalise_fit_args` and prepares data/scalers through `psann.estimators._fit_utils.prepare_inputs_and_scaler`, so dense, residual, and convolutional variants share the same fit surface.

### Episodic HISSO with `HISSOOptions`

```python
import numpy as np
from psann import PSANNRegressor, get_reward_strategy, HISSOOptions

rng = np.random.default_rng(7)
X = rng.normal(size=(512, 4)).astype(np.float32)
targets = np.sin(X.sum(axis=1, keepdims=True)).astype(np.float32)

model = PSANNRegressor(hidden_layers=2, hidden_units=48, epochs=40, batch_size=64)
model.fit(X, targets, verbose=1)  # supervised warm start

finance = get_reward_strategy("finance")
options = HISSOOptions.from_kwargs(
    window=64,
    reward_fn=finance.reward_fn,
    context_extractor=finance.context_extractor,
    primary_transform="softmax",
    transition_penalty=0.05,
    input_noise=0.0,
    supervised={"y": targets},
)

model.fit(
    X,
    y=None,
    hisso=True,
    hisso_window=options.episode_length,
    hisso_reward_fn=options.reward_fn,
    hisso_context_extractor=options.context_extractor,
    hisso_primary_transform=options.primary_transform,
    hisso_transition_penalty=options.transition_penalty,
    hisso_supervised=options.supervised,
    verbose=1,
)
```

`HISSOOptions` keeps reward, context, noise, and transformation choices in one place. The estimator records the resolved options after fitting so helpers such as `psann.hisso.hisso_infer_series` and `psann.hisso.hisso_evaluate_reward` can reuse them.

### Custom data preparation

```python
from psann import PSANNRegressor
from psann.estimators._fit_utils import normalise_fit_args, prepare_inputs_and_scaler

est = PSANNRegressor(hidden_layers=1, hidden_units=16, scaler="standard")
fit_args = normalise_fit_args(est, X_train, y_train, hisso=False, verbose=0, lr_max=None, lr_min=None)
prepared, primary_dim, _ = prepare_inputs_and_scaler(est, fit_args)
# prepared.train_inputs / prepared.train_targets feed straight into custom loops
```

This keeps bespoke research loops aligned with the estimator's preprocessing contract without relying on deprecated extras heads.

## Core components

- **Sine activations** (`psann.activations.SineParam`) expose learnable amplitude, frequency, and decay with optional bounds and SIREN-friendly initialisation.
- **LSM expanders** (`psann.lsm`) provide sparse learned feature maps; `build_preprocessor` wires dict specs or modules into estimators with optional pretraining and separate learning rates.
- **State controllers** (`psann.state.StateController`) keep per-feature persistent gains for streaming/online workflows. Configurable via `StateConfig`.
- **Shared fit helpers** (`psann.estimators._fit_utils`) normalise arguments, materialise scalers, route through residual and convolutional builders, and orchestrate HISSO plans.
- **Wave backbones** (`psann.models`) surface `WaveResNet`, `WaveEncoder`, `WaveRNNCell`, and `scan_regimes` for standalone experiments and spectral diagnostics outside the sklearn wrappers.
- **HISSO** (`psann.hisso`) offers declarative reward configuration (`HISSOOptions`), supervised warm starts, episode construction, and inference helpers that reuse the cached configuration.
- **Utilities** (`psann.utils`) include Jacobian/NTK probes, participation ratio, mutual-information proxies, and linear probes for diagnostics.
- **Token helpers** (`SimpleWordTokenizer`, `SineTokenEmbedder`) remain for experiments that need sine embeddings, but no language-model trainer ships in this release.

## HISSO at a glance

1. Call `HISSOOptions.from_kwargs(...)` (or supply equivalent kwargs to `fit`) to resolve episode length, reward function, primary transform, transition penalty, context extractor, and optional noise.
2. Provide `hisso_supervised` to run a warm-start supervised phase before episodic optimisation.
3. `PSANNRegressor.fit(..., hisso=True, ...)` builds the episodic trainer using the shared fit pipeline.
4. After training, `hisso_infer_series(estimator, series)` and `hisso_evaluate_reward(estimator, series, targets=None)` reuse the cached configuration to score new data.

The project ships CPU benchmark baselines (`docs/benchmarks/`) and CI scripts (`scripts/benchmark_hisso_variants.py`, `scripts/compare_hisso_benchmarks.py`) to catch HISSO regressions.

## Docs and examples

- Examples live in `examples/`; see `docs/examples/README.md` for the curated list (supervised, streaming, HISSO, benchmarks, diagnostics).
- Detailed internals are captured in `TECHNICAL_DETAILS.md`.
- Reward registry usage and custom strategy registration are described in `docs/API.md` under the HISSO section.

## Current status and roadmap

- Predictive extras and growth schedules are gone; legacy `extras_*` arguments are accepted but ignored with warnings for backward compatibility.
- Terminology has converged on `transition_penalty` within HISSO; the `trans_cost` alias still functions but will be removed in a later release.
- CPU benchmarks run in CI; GPU baselines remain on the roadmap once shared hardware is available.
- Upcoming work highlighted in `REPO_CLEANUP_TODO.md` includes broader reward coverage, lint/type sweeps, and release tooling improvements.

### Reproducibility

The notebook **PSANN_Parity_and_Probes.ipynb** (now under `notebooks/`) reproduces all key results under compute parity.  
- **Release:** [v1.0.0](https://github.com/Nickm1128/psann/releases/tag/v1.0.0)  
- **DOI:** [doi.org/10.5281/zenodo.17391523](https://doi.org/doi.org/10.5281/zenodo.17391523)  
- **Permalink:** [GitHub](https://github.com/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)  
- **Render:** [nbviewer](https://nbviewer.org/github/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)  
- **Run:** [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)

Experiments used **Python 3.9**, dependencies pinned in `pyproject.toml` (install `[compat]` for constrained environments).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "psann",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "classification, neural-networks, pytorch, regression, sine, siren, sklearn, time-series",
    "author": "Nicholas Milinkovich",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/5f/df/92dd34d846e7f2d65fb2f9dcdc9f364984d54f543b81208aad2d3c82ff13/psann-0.10.9.tar.gz",
    "platform": null,
    "description": "# PSANN - Parameterized Sine-Activated Neural Networks\n\nPSANN packages sine-activated Torch models behind a sklearn-style estimator surface. The stack combines:\n- learnable sine activations with SIREN-friendly initialisation,\n- optional learned sparse (LSM) expanders and scalers,\n- persistent state controllers for streaming inference, and\n- Horizon-Informed Sampling Strategy Optimisation (HISSO) for episodic training.\n\nThe current line targets **primary outputs only** so there are no predictive extras, secondary heads, or legacy growth schedules to maintain.\n\nQuick links:\n- API reference: `docs/API.md`\n- Scenario walkthroughs: `docs/examples/README.md`\n- Migration notes: `docs/migration.md`\n- Results compendium: `docs/PSANN_Results_Compendium.md`\n- Contributor guide: `docs/CONTRIBUTING.md`\n- Technical design notes: `TECHNICAL_DETAILS.md`\n\n## Installation\n\n```bash\npython -m venv .venv\n.\\.venv\\Scripts\\Activate.ps1   # Windows PowerShell\n# source .venv/bin/activate     # macOS/Linux\npip install --upgrade pip\npip install -e .                # editable install from source\n```\n\nOptional extras in `pyproject.toml`:\n- `psann[sklearn]`: adds scikit-learn conveniences for estimator mixins and metrics.\n- `psann[viz]`: plotting helpers used in benchmarks and notebooks.\n- `psann[dev]`: pytest, ruff, black, coverage, build, pre-commit tooling.\n\nNeed pre-pinned builds (e.g. on Windows or air-gapped envs)? Use the compatibility extra:\n\n```bash\npip install -e .[compat]\n```\n\nThe `compat` extra pins NumPy, SciPy, scikit-learn, and PyTorch to the newest widely available wheels while keeping `pyproject.toml` as the single source of truth.\n\n## Running Tests\n\nInstall the development extras in editable mode so the test suite imports the packaged code without manual `sys.path` tweaks:\n\n```bash\npip install -e .[dev]\npython -m pytest\n```\n\nHISSO integration suites are marked as `slow`; skip them during quick iterations with:\n\n```bash\npython -m pytest -m \"not slow\"\n```\n\nThe suite exercises the supported supervised, streaming, and HISSO flows. GPU-specific checks are skipped automatically when CUDA is unavailable.\n\nCommon linting commands:\n\n```bash\npython -m ruff check src tests scripts examples\npython -m black --check src tests scripts examples\n```\n\nSet up local hooks (formatting, linting, notebook output stripping) with `pre-commit`:\n\n```bash\npre-commit install\npre-commit run --all-files  # optional one-time sweep\n```\n\n## Quick Start\n\n### Supervised regression\n\n```python\nimport numpy as np\nfrom psann import PSANNRegressor\n\nrs = np.random.RandomState(42)\nX = np.linspace(-4, 4, 1000, dtype=np.float32).reshape(-1, 1)\ny = 0.8 * np.exp(-0.25 * np.abs(X)) * np.sin(3.5 * X)\n\nmodel = PSANNRegressor(\n    hidden_layers=2,\n    hidden_units=64,\n    epochs=200,\n    lr=1e-3,\n    early_stopping=True,\n    patience=20,\n    random_state=42,\n)\nmodel.fit(X, y, verbose=1)\nprint(\"R^2:\", model.score(X, y))\n```\n\nBehind the scenes the estimator normalises arguments via `normalise_fit_args` and prepares data/scalers through `psann.estimators._fit_utils.prepare_inputs_and_scaler`, so dense, residual, and convolutional variants share the same fit surface.\n\n### Episodic HISSO with `HISSOOptions`\n\n```python\nimport numpy as np\nfrom psann import PSANNRegressor, get_reward_strategy, HISSOOptions\n\nrng = np.random.default_rng(7)\nX = rng.normal(size=(512, 4)).astype(np.float32)\ntargets = np.sin(X.sum(axis=1, keepdims=True)).astype(np.float32)\n\nmodel = PSANNRegressor(hidden_layers=2, hidden_units=48, epochs=40, batch_size=64)\nmodel.fit(X, targets, verbose=1)  # supervised warm start\n\nfinance = get_reward_strategy(\"finance\")\noptions = HISSOOptions.from_kwargs(\n    window=64,\n    reward_fn=finance.reward_fn,\n    context_extractor=finance.context_extractor,\n    primary_transform=\"softmax\",\n    transition_penalty=0.05,\n    input_noise=0.0,\n    supervised={\"y\": targets},\n)\n\nmodel.fit(\n    X,\n    y=None,\n    hisso=True,\n    hisso_window=options.episode_length,\n    hisso_reward_fn=options.reward_fn,\n    hisso_context_extractor=options.context_extractor,\n    hisso_primary_transform=options.primary_transform,\n    hisso_transition_penalty=options.transition_penalty,\n    hisso_supervised=options.supervised,\n    verbose=1,\n)\n```\n\n`HISSOOptions` keeps reward, context, noise, and transformation choices in one place. The estimator records the resolved options after fitting so helpers such as `psann.hisso.hisso_infer_series` and `psann.hisso.hisso_evaluate_reward` can reuse them.\n\n### Custom data preparation\n\n```python\nfrom psann import PSANNRegressor\nfrom psann.estimators._fit_utils import normalise_fit_args, prepare_inputs_and_scaler\n\nest = PSANNRegressor(hidden_layers=1, hidden_units=16, scaler=\"standard\")\nfit_args = normalise_fit_args(est, X_train, y_train, hisso=False, verbose=0, lr_max=None, lr_min=None)\nprepared, primary_dim, _ = prepare_inputs_and_scaler(est, fit_args)\n# prepared.train_inputs / prepared.train_targets feed straight into custom loops\n```\n\nThis keeps bespoke research loops aligned with the estimator's preprocessing contract without relying on deprecated extras heads.\n\n## Core components\n\n- **Sine activations** (`psann.activations.SineParam`) expose learnable amplitude, frequency, and decay with optional bounds and SIREN-friendly initialisation.\n- **LSM expanders** (`psann.lsm`) provide sparse learned feature maps; `build_preprocessor` wires dict specs or modules into estimators with optional pretraining and separate learning rates.\n- **State controllers** (`psann.state.StateController`) keep per-feature persistent gains for streaming/online workflows. Configurable via `StateConfig`.\n- **Shared fit helpers** (`psann.estimators._fit_utils`) normalise arguments, materialise scalers, route through residual and convolutional builders, and orchestrate HISSO plans.\n- **Wave backbones** (`psann.models`) surface `WaveResNet`, `WaveEncoder`, `WaveRNNCell`, and `scan_regimes` for standalone experiments and spectral diagnostics outside the sklearn wrappers.\n- **HISSO** (`psann.hisso`) offers declarative reward configuration (`HISSOOptions`), supervised warm starts, episode construction, and inference helpers that reuse the cached configuration.\n- **Utilities** (`psann.utils`) include Jacobian/NTK probes, participation ratio, mutual-information proxies, and linear probes for diagnostics.\n- **Token helpers** (`SimpleWordTokenizer`, `SineTokenEmbedder`) remain for experiments that need sine embeddings, but no language-model trainer ships in this release.\n\n## HISSO at a glance\n\n1. Call `HISSOOptions.from_kwargs(...)` (or supply equivalent kwargs to `fit`) to resolve episode length, reward function, primary transform, transition penalty, context extractor, and optional noise.\n2. Provide `hisso_supervised` to run a warm-start supervised phase before episodic optimisation.\n3. `PSANNRegressor.fit(..., hisso=True, ...)` builds the episodic trainer using the shared fit pipeline.\n4. After training, `hisso_infer_series(estimator, series)` and `hisso_evaluate_reward(estimator, series, targets=None)` reuse the cached configuration to score new data.\n\nThe project ships CPU benchmark baselines (`docs/benchmarks/`) and CI scripts (`scripts/benchmark_hisso_variants.py`, `scripts/compare_hisso_benchmarks.py`) to catch HISSO regressions.\n\n## Docs and examples\n\n- Examples live in `examples/`; see `docs/examples/README.md` for the curated list (supervised, streaming, HISSO, benchmarks, diagnostics).\n- Detailed internals are captured in `TECHNICAL_DETAILS.md`.\n- Reward registry usage and custom strategy registration are described in `docs/API.md` under the HISSO section.\n\n## Current status and roadmap\n\n- Predictive extras and growth schedules are gone; legacy `extras_*` arguments are accepted but ignored with warnings for backward compatibility.\n- Terminology has converged on `transition_penalty` within HISSO; the `trans_cost` alias still functions but will be removed in a later release.\n- CPU benchmarks run in CI; GPU baselines remain on the roadmap once shared hardware is available.\n- Upcoming work highlighted in `REPO_CLEANUP_TODO.md` includes broader reward coverage, lint/type sweeps, and release tooling improvements.\n\n### Reproducibility\n\nThe notebook **PSANN_Parity_and_Probes.ipynb** (now under `notebooks/`) reproduces all key results under compute parity.  \n- **Release:** [v1.0.0](https://github.com/Nickm1128/psann/releases/tag/v1.0.0)  \n- **DOI:** [doi.org/10.5281/zenodo.17391523](https://doi.org/doi.org/10.5281/zenodo.17391523)  \n- **Permalink:** [GitHub](https://github.com/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)  \n- **Render:** [nbviewer](https://nbviewer.org/github/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)  \n- **Run:** [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nickm1128/psann/blob/v1.0.0/notebooks/PSANN_Parity_and_Probes.ipynb)\n\nExperiments used **Python 3.9**, dependencies pinned in `pyproject.toml` (install `[compat]` for constrained environments).\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Nicholas Milinkovich\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "PSANN: Parameterized Sine-Activated Neural Networks (primary-output, sklearn-style, PyTorch backend)",
    "version": "0.10.9",
    "project_urls": {
        "Changelog": "https://github.com/psann-project/psann/blob/main/docs/migration.md",
        "Contributing": "https://github.com/psann-project/psann/blob/main/docs/CONTRIBUTING.md",
        "Documentation": "https://github.com/psann-project/psann/tree/main/docs",
        "Homepage": "https://github.com/psann-project/psann",
        "Issues": "https://github.com/psann-project/psann/issues",
        "Repository": "https://github.com/psann-project/psann"
    },
    "split_keywords": [
        "classification",
        " neural-networks",
        " pytorch",
        " regression",
        " sine",
        " siren",
        " sklearn",
        " time-series"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b27898554cfa2b89455cdb8429946552923b833d0581cfe56db10c9682aa8505",
                "md5": "776a5fdec2d98d8a3e00a76231b9fb88",
                "sha256": "d828ae5d0a201931c5b2dd6b1418aaf021f3204dad59d5d4283c7655e8bb5712"
            },
            "downloads": -1,
            "filename": "psann-0.10.9-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "776a5fdec2d98d8a3e00a76231b9fb88",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 86239,
            "upload_time": "2025-10-22T11:27:51",
            "upload_time_iso_8601": "2025-10-22T11:27:51.606182Z",
            "url": "https://files.pythonhosted.org/packages/b2/78/98554cfa2b89455cdb8429946552923b833d0581cfe56db10c9682aa8505/psann-0.10.9-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5fdf92dd34d846e7f2d65fb2f9dcdc9f364984d54f543b81208aad2d3c82ff13",
                "md5": "a876ef678a690baa144258666d6b74b0",
                "sha256": "f1db80d48f94c320c0300b7a04e6fb51ad56de955b92cc0076ba20ecab7cf456"
            },
            "downloads": -1,
            "filename": "psann-0.10.9.tar.gz",
            "has_sig": false,
            "md5_digest": "a876ef678a690baa144258666d6b74b0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 93193,
            "upload_time": "2025-10-22T11:27:52",
            "upload_time_iso_8601": "2025-10-22T11:27:52.520464Z",
            "url": "https://files.pythonhosted.org/packages/5f/df/92dd34d846e7f2d65fb2f9dcdc9f364984d54f543b81208aad2d3c82ff13/psann-0.10.9.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-22 11:27:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "psann-project",
    "github_project": "psann",
    "github_not_found": true,
    "lcname": "psann"
}
        
Elapsed time: 0.67944s