Metadata-Version: 2.5
Name: sciencehub
Version: 0.1.2
Summary: Load the functions and data of ScienceHub projects in Python.
Project-URL: Homepage, https://sciencehub.sh
Project-URL: Documentation, https://sciencehub.sh/docs/python
Author: ScienceHub
License-Expression: Apache-2.0
Keywords: datasets,marimo,notebooks,reproducibility,science
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Requires-Dist: marimo>=0.13
Provides-Extra: fsspec
Requires-Dist: fsspec>=2023.1; extra == 'fsspec'
Description-Content-Type: text/markdown

# sciencehub

Use the functions and data of [ScienceHub](https://sciencehub.sh) projects
from Python.

A ScienceHub project is a [marimo](https://marimo.io) notebook and the files
beside it. Every function its author wrote as a reusable function
(`@app.function`) can be called from your own code, and every file can be
read. Each project page lists them under **Functions** and **Files**.

```sh
pip install sciencehub
```

## Load a project

```python
import sciencehub as sh

keeling_curve = sh.load("sciencehub-team/keeling-curve")
keeling_curve
```

```
sciencehub-team/keeling-curve · Keeling curve
version NS52YCXV, release 1, https://doi.org/10.83371/sh.2610.jd9q4 · https://sciencehub.sh/sciencehub-team/keeling-curve
Monthly CO₂ at Mauna Loa since 1958: NOAA's record and the functions that read it.

Functions
  load_co2(path: str = DATA) -> pd.DataFrame
      Monthly mean CO₂ in the air at Mauna Loa, Hawaii, in ppm, from March 1958.
  yearly_mean(path: str = DATA) -> pd.Series
      The deseasonalized concentration averaged over each complete year, in ppm, by year.
  growth_rate(start_year: int, end_year: int, path: str = DATA) -> float
      Average growth of CO₂ between two complete years, in ppm a year.
  seasonal_cycle(path: str = DATA) -> pd.Series
      Each month's mean departure from the deseasonalized trend, in ppm: the breath of the northern forests.

Files
  data/co2_mm_mlo.csv  38.8 kB
  README.md            1.2 kB
```

`sh.load` takes the name from the project's address: `"owner/project"` for
its main notebook, `"owner/project/notebook"` for another one, or the address
itself.

## Call a function

```python
help(keeling_curve.growth_rate)
keeling_curve.growth_rate(2015, 2025)   # 2.63
```

`help()`, `inspect.signature`, Jupyter's `?` and editor completion show the
signature and docstring the author wrote, before anything is downloaded.

The first call downloads the notebook and its files into a cache, imports the
notebook, and calls the function on your computer, with the notebook's folder
as the working directory: `load_co2()` finds `data/co2_mm_mlo.csv` there, as
it does on ScienceHub.

The notebook's dependencies have to be installed in your Python. If one is
missing, the error names it; `keeling_curve.install()` installs everything the
notebook declares, with pip or uv.

Calling a function runs its author's code, as installing their package would.

## Read the data

Any library that reads through [fsspec](https://filesystem-spec.readthedocs.io)
reads a project's files by their `sciencehub://` address (`sh://` for short):
pandas, polars, xarray, Dask and DuckDB among them.

```sh
pip install "sciencehub[fsspec]"
```

```python
import pandas as pd

co2 = pd.read_csv("sciencehub://sciencehub-team/keeling-curve/data/co2_mm_mlo.csv", comment="#")
```

The address is `owner/project[@version]/path`: `@release-1` reads what release
1's DOI names, `@ver_…` one saved version. Files are downloaded once and
checked against their SHA-256.

The package reads files without fsspec too:

```python
path = keeling_curve.path("data/co2_mm_mlo.csv")   # downloaded once, checked, then read from disk
keeling_curve.download()                            # the notebook and every file, in one folder
```

Files of public projects also have a plain address any program can read:
`https://sciencehub.sh/sciencehub-team/keeling-curve/raw/data/co2_mm_mlo.csv`.

## Run it on your computer

One command copies a version of the notebook with its files into a folder
and opens it in marimo; with [uv](https://docs.astral.sh/uv/) installed it
runs in a sandbox that installs what the notebook declares.

```sh
uvx sciencehub edit sciencehub-team/keeling-curve              # into ./keeling-curve, in marimo's editor
uvx sciencehub run sciencehub-team/keeling-curve --release 1   # what DOI release 1 names, as an app
uvx sciencehub download sciencehub-team/keeling-curve          # only the copy
```

Changes stay on your computer. Upload the notebook on the project's History
page to make them a version.

## Pin a version

A load is always one version, and `keeling_curve.version` says which. Pin it so
your results do not change when the author saves a new one:

```python
sh.load("sciencehub-team/keeling-curve", version="ver_01M4V36RH5ZV0RGFPSNS52YCXV")   # one saved version
sh.load("sciencehub-team/keeling-curve", release=1)            # what DOI release 1 names, files included
```

## Private projects

Make a personal access token with the read scope at
[sciencehub.sh/settings/tokens](https://sciencehub.sh/settings/tokens) and
set it as `SCIENCEHUB_TOKEN`, or pass `token=` to `sh.load`.

## Settings

| Variable           | What it does                                         |
| ------------------ | ---------------------------------------------------- |
| `SCIENCEHUB_TOKEN` | A personal access token, for private projects        |
| `SCIENCEHUB_URL`   | Another ScienceHub site than `https://sciencehub.sh` |
| `SCIENCEHUB_CACHE` | Where versions are kept; the user cache by default   |

Apache 2.0.
