Skip to content

Commit 5f83704

Browse files
Merge branch 'main' into polish_README
2 parents 639efd0 + 49f5ba8 commit 5f83704

File tree

10 files changed

+259
-73
lines changed

10 files changed

+259
-73
lines changed

.readthedocs.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# .readthedocs.yaml
2+
# Read the Docs configuration file
3+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4+
5+
# Required
6+
version: 2
7+
8+
# Set the version of Python and other tools you might need
9+
build:
10+
os: ubuntu-lts-latest
11+
tools:
12+
# DO NOT use mambaforge-*; that is currently sunsetted
13+
python: "miniconda-latest"
14+
jobs:
15+
post_create_environment:
16+
- conda run -n ${CONDA_DEFAULT_ENV} pip install . --no-deps
17+
18+
# Declare the requirements required to build your docs
19+
conda:
20+
environment:
21+
environment.yml
22+
23+
# Build documentation in the doc directory with Sphinx
24+
sphinx:
25+
configuration: doc/conf.py
26+
fail_on_warning: true
27+
28+
# If using Sphinx, optionally build your docs in additional formats such as PDF
29+
formats:
30+
- pdf

conda-linux-64.lock

Lines changed: 37 additions & 37 deletions
Large diffs are not rendered by default.

doc/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
# The name of an image file (relative to this directory) to place at the top
166166
# of the sidebar.
167167
# FIXME add a logo
168-
html_logo = "figures/alpaca-logo.png"
168+
html_logo = "figures/PyActiveStorage-logo-complete.jpg"
169169

170170
# The name of an image file (within the static path) to use as favicon of the
171171
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32

doc/introduction.rst

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
Introduction
22
************
33

4-
About
5-
=====
4+
About PyActiveStorage
5+
=====================
66

7+
PyActiveStorage provides a Python client to local or remote “active” storage (aka “computational” storage), that is,
8+
storage that instead of just receiving reads and returning blocks of data, can receive requests for, and return the
9+
results of, computations on blocks of data. We have implemented active storage which supports a limited set of reduction
10+
computations. We have two implementations of active storage with which PyActiveStorage can interact:
11+
12+
* a prototype in DDN InfiniaTM
13+
* a production ready `“Reductionist” <https://github.com/stackhpc/reductionist-rs>`_ middleware software which can be
14+
deployed to turn any S3 object store into active storage
15+
16+
Using PyActiveStorage can speed up workflows, especially if the data is remote, or the local area network is congested.
17+
Early results accessing global fields of 10km resolution data on the CEDA-JASMIN S3 object store show that time-series
18+
of hemispheric means can be returned to remote users on low-bandwidth networks (and even in
19+
different hemispheres) in times which are competitive with local users accessing POSIX data across a LAN.
20+
21+
We anticipate this technology will be game-changing for remote access to data, particularly where there is
22+
insufficient local storage to make copies of data, or those with low-bandwidth networks – although anyone can benefit from
23+
minimising network contention and reducing the carbon cost of moving data.

doc/quickstart/configuration.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,61 @@
44
Configuration
55
*************
66

7+
Configuring a run with S3 data
8+
------------------------------
79

10+
As a standalone application, PyActiveStorage does not need any configuration, data being
11+
supplied directly to the ``Active`` class; however, some configuration is still needed to be
12+
able to access an S3 bucket.
13+
14+
For an example, suppose we are trying to access a file ``ch330a.pc19790301-def.nc`` on CEDA-JASMIN's S3 storage,
15+
for which one needs to supply ``Active`` the ``storage_options`` dictionary:
16+
17+
.. code-block:: bash
18+
19+
storage_options = {
20+
'key': "key.string",
21+
'secret': "sercret.string",
22+
'client_kwargs': {'endpoint_url': "https://uor-aces-o.s3-ext.jc.rl.ac.uk"},
23+
}
24+
25+
where ``key.string`` and ``secret.string`` are the key and secret strings needed to access the ``S3_BUCKET`` S3 bucket. Then,
26+
the call to ``Active`` is:
27+
28+
.. code-block:: bash
29+
30+
active = Active("S3_BUCKET/ch330a.pc19790301-def.nc", ncvar='UM_m01s16i202_vn1106',
31+
storage_options=storage_options,
32+
active_storage_url="https://reductionist.jasmin.ac.uk/")
33+
34+
Note that the `<https://reductionist.jasmin.ac.uk/>`_ specified here is the Reductionist server deployed
35+
on CEDA-JASMIN.
36+
37+
Configuring a Reductionist deployment
38+
-------------------------------------
39+
40+
A few points on how to deploy `Reductionist <https://github.com/stackhpc/reductionist-rs>`_ on a Rocky9 cloud machine:
41+
42+
* 99% of the deployment documentation is found in `Reductionist's nice deployment instructions <https://stackhpc.github.io/reductionist-rs/deployment/>`_
43+
* there are a few caveats specific to a pristine Rocky9 (and other distros) deployment though:
44+
* (n00b step) always have a system ``pip`` by installing it with: ``python -m ensurepip --upgrade``
45+
* system Python executable is ``python3`` - you can, of course, ``ln -s`` it to ``python``, or, better, run Ansible pointing it to the correct system Python3:
46+
47+
.. code-block:: bash
48+
49+
ansible-playbook -i reductionist-rs/deployment/inventory reductionist-rs/deployment/site.yml -e 'ansible_python_interpreter=/usr/bin/python3'
50+
51+
* that call *may result* (as in our case) in an error:
52+
53+
.. code-block:: bash
54+
55+
TASK [Ensure step RPM is installed] ****************************************************************************************************
56+
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to validate GPG signature for step-cli-0.24.4-1.x86_64: Package step-cli_0.24.4_amd643z16ickc.rpm is not signed"}
57+
58+
that's because, in our case, we missed the ``step-cli`` package, and a ``dfn`` install is not well liked by the system (it's not ``mamba`` business);
59+
that gets sorted out via `Step's install docs <https://smallstep.com/docs/step-cli/installation>`_:
60+
61+
.. code-block:: bash
62+
63+
wget https://dl.smallstep.com/cli/docs-cli-install/latest/step-cli_amd64.rpm
64+
sudo rpm -i step-cli_amd64.rpm

doc/quickstart/installation.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,48 @@
44
Installation
55
************
66

7+
Conda-mamba environment
8+
-----------------------
9+
10+
Use a Miniconda/Miniforge3 installer to create an environment using
11+
our conda ``environment.yml`` file; download the latest Miniconda3 for Linux installer from
12+
the `Miniconda project <https://docs.conda.io/en/latest/miniconda.html#linux-installers>`_,
13+
install it, then create and activate the PyActiveStorage environment:
14+
15+
.. code-block:: bash
16+
17+
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
18+
bash Miniconda3-latest-Linux-x86_64.sh
19+
(base) conda env create -n activestorage -f environment.yml
20+
(base) conda activate activestorage
21+
22+
.. note::
23+
24+
Our dependencies are all from ``conda-forge`` so there is no issue related
25+
to the buggy (and paid-for) Anaconda main/defaults channel!
26+
27+
Installing PyActiveStorage
28+
--------------------------
29+
30+
The installation then can proceed: installing with ``pip`` and installing ``all`` (ie
31+
installing the development and test install):
32+
33+
.. code-block:: bash
34+
35+
pip install -e .
36+
37+
After installing, you can run tests via ``pytest -n 2``.
38+
39+
Supported Python versions
40+
-------------------------
41+
42+
We adhere to `SPEC0 <https://scientific-python.org/specs/spec-0000/>`_ and support the following Python versions:
43+
44+
* 3.10
45+
* 3.11
46+
* 3.12
47+
* 3.13
48+
49+
.. note::
50+
51+
PyActiveStorage is fully compatible with ``numpy >=2.0.0``.

doc/quickstart/running.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,60 @@
44
Running
55
*******
66

7+
Example 1: S3 file
8+
------------------
9+
10+
Here is a basic example of of obtaining a minumum on a slice ``[0:3, 4:6, 7:9]`` on the data for a variable
11+
``UM_m01s16i202_vn1106`` in a file ``ch330a.pc19790301-def.nc`` hosted on JASMIN's S3 storage in a bucket called ``bnl``:
12+
13+
.. code-block:: python
14+
15+
import os
16+
17+
from activestorage.active import Active
18+
19+
20+
def s3_file():
21+
"""Run a simple active storage instance test with S3 file."""
22+
S3_BUCKET = "bnl"
23+
storage_options = {
24+
'key': "KEY",
25+
'secret': "SECRET",
26+
'client_kwargs': {'endpoint_url': "https://uor-aces-o.s3-ext.jc.rl.ac.uk"},
27+
}
28+
29+
active_storage_url = "https://reductionist.jasmin.ac.uk/"
30+
a_file = "ch330a.pc19790301-def.nc"
31+
32+
test_file_uri = os.path.join(
33+
S3_BUCKET,
34+
a_file
35+
)
36+
37+
active = Active(test_file_uri, ncvar='UM_m01s16i202_vn1106',
38+
storage_options=storage_options,
39+
active_storage_url=active_storage_url)
40+
active._version = 2
41+
result = active.min[0:3, 4:6, 7:9]
42+
43+
return result # 5098.625
44+
45+
Example 2: HTTPS file
46+
---------------------
47+
48+
Same as above, only the file is stored on an HTTPS-facing server (NGINX-enabled):
49+
50+
.. code-block:: python
51+
52+
from activestorage.active import Active
53+
54+
55+
def https_file():
56+
"""Run a simple active storage instance test with https file."""
57+
test_file_uri = "https://esgf.ceda.ac.uk/thredds/fileServer/esg_cmip6/CMIP6/AerChemMIP/MOHC/UKESM1-0-LL/ssp370SST-lowNTCF/r1i1p1f2/Amon/cl/gn/latest/cl_Amon_UKESM1-0-LL_ssp370SST-lowNTCF_r1i1p1f2_gn_205001-209912.nc"
58+
59+
active = Active(test_file_uri, ncvar="cl")
60+
active._version = 1
61+
result = active.min[0:3, 4:6, 7:9]
62+
63+
return result # numpy.array([0.6909787], dtype="float32")

docs_Reductionist_deployment/deploy.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

environment.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ dependencies:
2323
- pytest-html !=2.1.0
2424
- pytest-metadata >=1.5.1
2525
- pytest-xdist
26-
# Python packages needed for building docs
27-
# re-add when we deploy the docs
28-
# - autodocsumm >=0.2.2
29-
# - sphinx >=5
30-
# - sphinx_rtd_theme
26+
# docs
27+
- autodocsumm
28+
- sphinx
29+
- sphinx_rtd_theme

pyproject.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,27 @@ requires-python = ">=3.10"
5050

5151
[project.optional-dependencies]
5252
test = [
53-
"pytest>6.0.0",
53+
"pytest",
5454
"pytest-cov>=2.10.1",
5555
"pytest-html!=2.1.0",
56+
"pytest-metadata>=1.5.1",
5657
"pytest-xdist",
5758
"dask",
5859
"moto",
5960
]
60-
61-
# very possible these will be needed
62-
# at some point in the near future
63-
# doc = [
64-
# "sphinx>=6.1.3",
65-
# "pydata_sphinx_theme",
66-
# ]
61+
# build docs
62+
doc = [
63+
"autodocsumm",
64+
"sphinx",
65+
"sphinx_rtd_theme",
66+
]
67+
# to be added when functionality provided
6768
# develop = [
6869
# "pre-commit",
6970
# "pylint",
7071
# "pydocstyle",
7172
# ]
7273

73-
7474
[project.urls]
7575
Code = "https://github.com/NCAS-CMS/PyActiveStorage"
7676
# Documentation = ""

0 commit comments

Comments
 (0)