Metadata-Version: 2.4
Name: arrakis
Version: 0.7.0
Summary: Arrakis Python client library
Project-URL: Homepage, https://git.ligo.org/ngdd/arrakis-python
Project-URL: Documentation, https://docs.ligo.org/ngdd/arrakis-python
Project-URL: Issue Tracker, https://git.ligo.org/ngdd/arrakis-python/issues
Project-URL: Source Code, https://git.ligo.org/ngdd/arrakis-python.git
Author-email: Olivia Godwin <olivia.godwin@ligo.org>, Jameson Graef Rollins <jameson.rollins@ligo.org>
Maintainer-email: Olivia Godwin <olivia.godwin@ligo.org>
License-Expression: LGPL-3.0-or-later
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: arrakis-schema>=0.2
Requires-Dist: confluent-kafka>=1.8
Requires-Dist: gpstime
Requires-Dist: jsonschema
Requires-Dist: numpy
Requires-Dist: pyarrow
Requires-Dist: typing-extensions
Provides-Extra: dev
Requires-Dist: arrakis-server>=0.5; (python_version >= '3.11') and extra == 'dev'
Requires-Dist: markdown-callouts>=0.2; extra == 'dev'
Requires-Dist: markdown-exec>=0.5; extra == 'dev'
Requires-Dist: mkdocs-coverage>=0.2; extra == 'dev'
Requires-Dist: mkdocs-gen-files>=0.3; extra == 'dev'
Requires-Dist: mkdocs-literate-nav>=0.4; extra == 'dev'
Requires-Dist: mkdocs-material-igwn; extra == 'dev'
Requires-Dist: mkdocs-section-index>=0.3; extra == 'dev'
Requires-Dist: mkdocs>=1.3; extra == 'dev'
Requires-Dist: mkdocstrings[python]; extra == 'dev'
Requires-Dist: mockafka-py; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: mypy-extensions; extra == 'dev'
Requires-Dist: pip; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-console-scripts; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-freezer; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: toml>=0.10; extra == 'dev'
Provides-Extra: docs
Requires-Dist: markdown-callouts>=0.2; extra == 'docs'
Requires-Dist: markdown-exec>=0.5; extra == 'docs'
Requires-Dist: mkdocs-coverage>=0.2; extra == 'docs'
Requires-Dist: mkdocs-gen-files>=0.3; extra == 'docs'
Requires-Dist: mkdocs-literate-nav>=0.4; extra == 'docs'
Requires-Dist: mkdocs-material-igwn; extra == 'docs'
Requires-Dist: mkdocs-section-index>=0.3; extra == 'docs'
Requires-Dist: mkdocs>=1.3; extra == 'docs'
Requires-Dist: mkdocstrings[python]; extra == 'docs'
Requires-Dist: toml>=0.10; extra == 'docs'
Provides-Extra: lint
Requires-Dist: mypy; extra == 'lint'
Requires-Dist: mypy-extensions; extra == 'lint'
Requires-Dist: pip; extra == 'lint'
Requires-Dist: ruff; extra == 'lint'
Provides-Extra: publish
Requires-Dist: sympy; extra == 'publish'
Provides-Extra: test
Requires-Dist: arrakis-server>=0.5; (python_version >= '3.11') and extra == 'test'
Requires-Dist: mockafka-py; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: pytest-console-scripts; extra == 'test'
Requires-Dist: pytest-cov; extra == 'test'
Requires-Dist: pytest-freezer; extra == 'test'
Description-Content-Type: text/markdown

<h1 align="center">arrakis-python</h1>

<p align="center">Arrakis Python client library</p>

<p align="center">
  <a href="https://git.ligo.org/ngdd/arrakis-python/-/pipelines/latest">
    <img alt="ci" src="https://git.ligo.org/ngdd/arrakis-python/badges/main/pipeline.svg" />
  </a>
  <a href="https://git.ligo.org/ngdd/arrakis-python/-/pipelines/latest">
    <img alt="ci" src="https://git.ligo.org/ngdd/arrakis-python/badges/main/coverage.svg" />
  </a>
  <a href="https://ngdd.docs.ligo.org/arrakis-python/">
    <img alt="documentation" src="https://img.shields.io/badge/docs-mkdocs%20material-blue.svg?style=flat" />
  </a>
  <a href="https://pypi.org/project/arrakis/">
    <img alt="pypi version" src="https://img.shields.io/pypi/v/arrakis.svg" />
  </a>
  <a href="https://anaconda.org/conda-forge/arrakis-python">
    <img alt="conda version" src="https://img.shields.io/conda/vn/conda-forge/arrakis-python.svg" />
  </a>
</p>

---

## Resources

* [Documentation](https://docs.ligo.org/ngdd/arrakis-python)
* [Source Code](https://git.ligo.org/ngdd/arrakis-python)
* [Issue Tracker](https://git.ligo.org/ngdd/arrakis-python/-/issues)

## Installation

With `pip`:

```
pip install arrakis
```

With `conda`:

```
conda install -c conda-forge arrakis-python
```

## Features

* Query live and historical timeseries data
* Describe channel metadata
* Search for channels matching a set of conditions
* Publish timeseries data

## Quickstart

### Fetch timeseries

``` python
import arrakis

start = 1187000000
end = 1187001000
channels = [
    "H1:CAL-DELTAL_EXTERNAL_DQ",
    "H1:LSC-POP_A_LF_OUT_DQ",
]

block = arrakis.fetch(channels, start, end)
for channel, series in block.items():
    print(channel, series)
```

where `block` is a [arrakis.block.SeriesBlock][] and `series` is a
[arrakis.block.Series][].

### Stream timeseries

##### 1. Live data

``` python
import arrakis

channels = [
    "H1:CAL-DELTAL_EXTERNAL_DQ",
    "H1:LSC-POP_A_LF_OUT_DQ",
]

for block in arrakis.stream(channels):
	print(block)
```

##### 2. Historical data

``` python
import arrakis

start = 1187000000
end = 1187001000
channels = [
    "H1:CAL-DELTAL_EXTERNAL_DQ",
    "H1:LSC-POP_A_LF_OUT_DQ",
]

for block in arrakis.stream(channels, start, end):
    print(block)
```

### Describe metadata

``` python
import arrakis

channels = [
    "H1:CAL-DELTAL_EXTERNAL_DQ",
    "H1:LSC-POP_A_LF_OUT_DQ",
]

metadata = arrakis.describe(channels)
```

where `metadata` is a dictionary mapping channel names to
[arrakis.channel.Channel][].

### Find channels

``` python
import arrakis

for channel in arrakis.find("H1:LSC-*"):
    print(channel)
```

where `channel` is a [arrakis.channel.Channel][].

### Count channels

``` python
import arrakis

count = arrakis.count("H1:LSC-*")
```

### Publish timeseries

``` python
from arrakis import Channel, Publisher, SeriesBlock, Time
import numpy

# admin-assigned ID
publisher_id = "my_producer"

# define channel metadata
metadata = {
    "H1:FKE-TEST_CHANNEL1": Channel(
        "H1:FKE-TEST_CHANNEL1",
        data_type=numpy.float64,
        sample_rate=64,
    ),
    "H1:FKE-TEST_CHANNEL2": Channel(
        "H1:FKE-TEST_CHANNEL2",
        data_type=numpy.int32,
        sample_rate=32,
    ),
}

publisher = Publisher(publisher_id)
publisher.register()

with publisher:
    # create block to publish
    series = {
        "H1:FKE-TEST_CHANNEL1": numpy.array([0.1, 0.2, 0.3, 0.4], dtype=numpy.float64),
        "H1:FKE-TEST_CHANNEL2": numpy.array([1, 2], dtype=numpy.int32),
    }
    block = SeriesBlock(
        1234567890 * Time.SECONDS,  # time in nanoseconds for first sample
        series,                     # the data to publish
        metadata,                   # the channel metadata
    )

    # publish timeseries
    publisher.publish(block)
```
