# Client for EPICS Archive Appliance
Utilities for interacting with an EPICS
[Archiver Appliance](https://slacmshankar.github.io/epicsarchiver_docs/)
server.
With the exception of `aaget --how plot ...` PV name strings are passed through
verbatim, and may include AA binning operators.
See the [Processing of data](https://slacmshankar.github.io/epicsarchiver_docs/userguide.html)
section for a list.
For fidelity, data is retrieved in the binary protobuf encoding native to AA.
Intended to supplant https://github.com/epicsdeb/carchivetools
## Building
Dependencies from the python ecosystem (eg. pip)
* python >= 3.7
* aiohttp >= 3.7.0 (and perhaps earlier)
* numpy >= 1.7
* Cython >= 0.20
* setuptools >= 40.9.0
* h5py (optional)
Dependencies from outside the python ecosystem (eg. rpm, deb, etc.)
* Working C++11 toolchain
* protobuf compiler, protobuf-lite library, and headers for >= 3.0
- These compiler and library versions must match
```sh
apt-get install protobuf-compiler libprotobuf-dev
yum install protobuf-compiler libprotobuf-devel
dnf install protobuf-compiler libprotobuf-devel
brew install protobuf
```
(Getting protobuf on windows is difficult...
See [for an example](.github/workflows/cibuildwheel.yml) using [vcpkg](https://github.com/microsoft/vcpkg).)
Build and install with pip
```sh
virtualenv aa
. aa/bin/activate
pip install -U pip
pip install Cython
./setup.py sdist
pip install dist/aaclient-*.tar.gz
aaget -h
```
Alternately, for in-place usage (eg. evaluation or troubleshooting).
```sh
./setup.py build_ext -i
python -m aaclient.cmd.get -h
```
In either case a configuration file is **required**.
```sh
cp aaclient.conf.example aaclient.conf
# edit aaclient.conf and fill in at least "host="
```
## Command Line Interface
This package provides several CLI tools for interacting with
an Archiver Appliance server.
See the [example configuration file](aaclient.conf.example).
### `aagrep` Searching for PVs
Running `aagrep` without arguments will attempt to print a full
list of PV names being archived.
Otherwise query patterns (wildcard or regexp) will be applied.
If multiple patterns are provided, the output will be all
PV names which matched any pattern.
```
$ aagrep RH
CO2:RH-I
```
### `aaget` Printing data
Query data from a set of PV names for a certain time range
and print the results.
```
$ aaget --start='-1 h' --end=now CO2:RH-I
01-30 07:50:11.958813 CO2:RH-I 45.10040283203125
01-30 08:13:04.816086 CO2:RH-I 44.56939697265625
01-30 08:40:41.527406 CO2:RH-I 44.06585693359375
```
### `aah5` Extract to HDF5 file
Queries like `aaget`, with results written to a HDF5 file
instead of being printed to screen.
```
$ aah5 --start='-1 h' --end=now out.h5 CO2:RH-I
INFO:__main__:'CO2:RH-I' : (3, 1)
$ h5ls -r out.h5
/ Group
/CO2:RH-I Group
/CO2:RH-I/meta Dataset {3/Inf}
/CO2:RH-I/value Dataset {3/Inf, 1/Inf}
```
### Alternate entry points.
* `aaget` -> `python -m aaclient.cmd.get`
* `aagrep` -> `python -m aaclient.cmd.grep`
* `aah5` -> `python -m aaclient.cmd.h5`
## API
The API behind the CLI executables is (primarily) asyncio based.
```py
import asyncio
from aaclient import getArchive
async def demo():
A= await getArchive()
with A:
V,M = await A.raw('CO2:CO2-I', T0='-12 h')
print(V.shape, M.shape)
asyncio.run(demo())
```
The entry point for API usage is `aaclient.getArchive()`,
which returns an object inheriting from `aaclient.IArchive`.
### Streaming
The `aaclient.IArchive.raw_iter()` method allows for incremental
retrieval of arbitrarily large data for long time range.
Async. iteration will yield samples in batches.
### Blocking API
A blocking (threaded) API is also provided as a convenience
for interactive usage.
```py
from matplotlib.pyplot import *
from aaclient.threading import getArchive
A=getArchive()
# Request ~1000 points of "caplotbinning" data
# suitable for quick/efficient visualization of a
# long time range
V,M = A.plot('CO2:CO2-I', T0='-7 d', count=1000)
figure()
plot_date(M.time_mpl, V[:,0], '-')
grid(True)
# Request complete (raw) data for a (shorter)
# time range
figure()
V,M = A.raw('CO2:CO2-I', T0='-12 h')
plot_date(M.time_mpl, V[:,0], '-')
grid(True)
show()
```
Raw data
{
"_id": null,
"home_page": "https://github.com/mdavidsaver/aaclient",
"name": "aaclient",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": null,
"author": "Michael Davidsaver",
"author_email": "mdavidsaver@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/96/79/3b4f948bd01be11c6748ac0f021573db318597c6c2f9fe41115f76f5e129/aaclient-0.0.3.tar.gz",
"platform": null,
"description": "# Client for EPICS Archive Appliance\n\nUtilities for interacting with an EPICS\n[Archiver Appliance](https://slacmshankar.github.io/epicsarchiver_docs/)\nserver.\n\nWith the exception of `aaget --how plot ...` PV name strings are passed through\nverbatim, and may include AA binning operators.\nSee the [Processing of data](https://slacmshankar.github.io/epicsarchiver_docs/userguide.html)\nsection for a list.\n\nFor fidelity, data is retrieved in the binary protobuf encoding native to AA.\n\nIntended to supplant https://github.com/epicsdeb/carchivetools\n\n## Building\n\nDependencies from the python ecosystem (eg. pip)\n\n* python >= 3.7\n* aiohttp >= 3.7.0 (and perhaps earlier)\n* numpy >= 1.7\n* Cython >= 0.20\n* setuptools >= 40.9.0\n* h5py (optional)\n\nDependencies from outside the python ecosystem (eg. rpm, deb, etc.)\n\n* Working C++11 toolchain\n* protobuf compiler, protobuf-lite library, and headers for >= 3.0\n - These compiler and library versions must match\n\n```sh\napt-get install protobuf-compiler libprotobuf-dev\n\nyum install protobuf-compiler libprotobuf-devel\n\ndnf install protobuf-compiler libprotobuf-devel\n\nbrew install protobuf\n```\n\n(Getting protobuf on windows is difficult...\nSee [for an example](.github/workflows/cibuildwheel.yml) using [vcpkg](https://github.com/microsoft/vcpkg).)\n\nBuild and install with pip\n\n```sh\nvirtualenv aa\n. aa/bin/activate\npip install -U pip\npip install Cython\n./setup.py sdist\npip install dist/aaclient-*.tar.gz\naaget -h\n```\n\nAlternately, for in-place usage (eg. evaluation or troubleshooting).\n\n```sh\n./setup.py build_ext -i\npython -m aaclient.cmd.get -h\n```\n\nIn either case a configuration file is **required**.\n\n```sh\ncp aaclient.conf.example aaclient.conf\n# edit aaclient.conf and fill in at least \"host=\"\n```\n\n## Command Line Interface\n\nThis package provides several CLI tools for interacting with\nan Archiver Appliance server.\n\nSee the [example configuration file](aaclient.conf.example).\n\n### `aagrep` Searching for PVs\n\nRunning `aagrep` without arguments will attempt to print a full\nlist of PV names being archived.\nOtherwise query patterns (wildcard or regexp) will be applied.\nIf multiple patterns are provided, the output will be all\nPV names which matched any pattern.\n\n```\n$ aagrep RH\nCO2:RH-I\n```\n\n### `aaget` Printing data\n\nQuery data from a set of PV names for a certain time range\nand print the results.\n\n```\n$ aaget --start='-1 h' --end=now CO2:RH-I\n01-30 07:50:11.958813 CO2:RH-I 45.10040283203125\n01-30 08:13:04.816086 CO2:RH-I 44.56939697265625\n01-30 08:40:41.527406 CO2:RH-I 44.06585693359375\n```\n\n### `aah5` Extract to HDF5 file\n\nQueries like `aaget`, with results written to a HDF5 file\ninstead of being printed to screen.\n\n```\n$ aah5 --start='-1 h' --end=now out.h5 CO2:RH-I\nINFO:__main__:'CO2:RH-I' : (3, 1)\n$ h5ls -r out.h5 \n/ Group\n/CO2:RH-I Group\n/CO2:RH-I/meta Dataset {3/Inf}\n/CO2:RH-I/value Dataset {3/Inf, 1/Inf}\n```\n\n### Alternate entry points.\n\n* `aaget` -> `python -m aaclient.cmd.get`\n* `aagrep` -> `python -m aaclient.cmd.grep`\n* `aah5` -> `python -m aaclient.cmd.h5`\n\n\n## API\n\nThe API behind the CLI executables is (primarily) asyncio based.\n\n```py\nimport asyncio\nfrom aaclient import getArchive\n\nasync def demo():\n A= await getArchive()\n with A:\n V,M = await A.raw('CO2:CO2-I', T0='-12 h')\n print(V.shape, M.shape)\n\nasyncio.run(demo())\n```\n\nThe entry point for API usage is `aaclient.getArchive()`,\nwhich returns an object inheriting from `aaclient.IArchive`.\n\n### Streaming\n\nThe `aaclient.IArchive.raw_iter()` method allows for incremental\nretrieval of arbitrarily large data for long time range.\nAsync. iteration will yield samples in batches.\n\n### Blocking API\n\nA blocking (threaded) API is also provided as a convenience\nfor interactive usage.\n\n```py\nfrom matplotlib.pyplot import *\nfrom aaclient.threading import getArchive\nA=getArchive()\n\n# Request ~1000 points of \"caplotbinning\" data\n# suitable for quick/efficient visualization of a\n# long time range\nV,M = A.plot('CO2:CO2-I', T0='-7 d', count=1000)\n\nfigure()\nplot_date(M.time_mpl, V[:,0], '-')\ngrid(True)\n\n# Request complete (raw) data for a (shorter)\n# time range\nfigure()\nV,M = A.raw('CO2:CO2-I', T0='-12 h')\nplot_date(M.time_mpl, V[:,0], '-')\ngrid(True)\n\nshow()\n```\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "Tools to query Archiver Appliance and export data",
"version": "0.0.3",
"project_urls": {
"Homepage": "https://github.com/mdavidsaver/aaclient"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b83ff12d262fb9ce69738f59ec0262493cf74791a92aab35c76864737efbe5c0",
"md5": "332e389af2d1c70e88bf476dbb1a5d86",
"sha256": "07641f62ecf0c5bf52e173194b3beac7f9604876240bf69ada7c12e82c050a30"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "332e389af2d1c70e88bf476dbb1a5d86",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.7",
"size": 270778,
"upload_time": "2025-02-05T03:57:39",
"upload_time_iso_8601": "2025-02-05T03:57:39.314899Z",
"url": "https://files.pythonhosted.org/packages/b8/3f/f12d262fb9ce69738f59ec0262493cf74791a92aab35c76864737efbe5c0/aaclient-0.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "13772e61dad0b45d002a419da77afaff1efdf108513d88d604eb0b9f69b49643",
"md5": "b2ccc46ef3eb7ba4b61eeb4190b0dbd9",
"sha256": "55d81beffd4ad9c555e82debe094c2154fd9a0a0e673b107066f1cba56189707"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b2ccc46ef3eb7ba4b61eeb4190b0dbd9",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.7",
"size": 270645,
"upload_time": "2025-02-05T03:57:41",
"upload_time_iso_8601": "2025-02-05T03:57:41.453489Z",
"url": "https://files.pythonhosted.org/packages/13/77/2e61dad0b45d002a419da77afaff1efdf108513d88d604eb0b9f69b49643/aaclient-0.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "9c4f16de1abe443fee888f9a19c45376f3a309ef5d39d43830e82106a2d79be3",
"md5": "f28805ce64d6b358a361b6dfe00bc88b",
"sha256": "81e1e2f48d8d4d26112b6ae0e969458af777f390500a861e1edb534762d76a67"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "f28805ce64d6b358a361b6dfe00bc88b",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.7",
"size": 269869,
"upload_time": "2025-02-05T03:57:42",
"upload_time_iso_8601": "2025-02-05T03:57:42.649863Z",
"url": "https://files.pythonhosted.org/packages/9c/4f/16de1abe443fee888f9a19c45376f3a309ef5d39d43830e82106a2d79be3/aaclient-0.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8fe46329b3dd694c6e23f3ec07b33247fd496ef323b0e5326b37bee41ec7be51",
"md5": "79e72b309c1bb9685220f3998a6b7530",
"sha256": "b4bc68e0d957f544b55e67ad367b8b877185c1ec5bf440ecff0c3ca3fbc600f3"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "79e72b309c1bb9685220f3998a6b7530",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.7",
"size": 269618,
"upload_time": "2025-02-05T03:57:44",
"upload_time_iso_8601": "2025-02-05T03:57:44.441271Z",
"url": "https://files.pythonhosted.org/packages/8f/e4/6329b3dd694c6e23f3ec07b33247fd496ef323b0e5326b37bee41ec7be51/aaclient-0.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7e1dbab217834d7c98ef6053babd94f73f95098a5d7e061490a3d1b04d64932d",
"md5": "a8443cf0e12e0076ef9055687a3d1ef9",
"sha256": "d05729940a6ffb3a1bffbeba3db6e3031d7395f2af8d5d4a5f422d9e706884fe"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "a8443cf0e12e0076ef9055687a3d1ef9",
"packagetype": "bdist_wheel",
"python_version": "cp37",
"requires_python": ">=3.7",
"size": 270683,
"upload_time": "2025-02-05T03:57:45",
"upload_time_iso_8601": "2025-02-05T03:57:45.754407Z",
"url": "https://files.pythonhosted.org/packages/7e/1d/bab217834d7c98ef6053babd94f73f95098a5d7e061490a3d1b04d64932d/aaclient-0.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d096381d1ea2eb895b469202f9cd968177d7db20f310134ea7549f326ede3411",
"md5": "21839ef1c89c93c3824ee97d5caed246",
"sha256": "6a1cdb2280327b8d234479caec4e0681b8170cbe4bb7e216b8d635706af608b6"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "21839ef1c89c93c3824ee97d5caed246",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.7",
"size": 271554,
"upload_time": "2025-02-05T03:57:47",
"upload_time_iso_8601": "2025-02-05T03:57:47.447756Z",
"url": "https://files.pythonhosted.org/packages/d0/96/381d1ea2eb895b469202f9cd968177d7db20f310134ea7549f326ede3411/aaclient-0.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d756fc9b8a70909eaf4d1f7f3c823519b60eb69076236383254b129cf2131ba6",
"md5": "4697175b3cd3857d094bab8a88719cfc",
"sha256": "2c0a23f26c6eb27320a7cae712a26fa375ef56a3d1f8c42f4cbfeb69f1f66edb"
},
"downloads": -1,
"filename": "aaclient-0.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "4697175b3cd3857d094bab8a88719cfc",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.7",
"size": 271474,
"upload_time": "2025-02-05T03:57:49",
"upload_time_iso_8601": "2025-02-05T03:57:49.454993Z",
"url": "https://files.pythonhosted.org/packages/d7/56/fc9b8a70909eaf4d1f7f3c823519b60eb69076236383254b129cf2131ba6/aaclient-0.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "96793b4f948bd01be11c6748ac0f021573db318597c6c2f9fe41115f76f5e129",
"md5": "2c25935b2d8386ef9785add753669a9d",
"sha256": "a5538d420169c2962e6cdf71e1cefc6b2bfb969d4c59ae4abf348b002e66d425"
},
"downloads": -1,
"filename": "aaclient-0.0.3.tar.gz",
"has_sig": false,
"md5_digest": "2c25935b2d8386ef9785add753669a9d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 135915,
"upload_time": "2025-02-05T03:57:51",
"upload_time_iso_8601": "2025-02-05T03:57:51.355393Z",
"url": "https://files.pythonhosted.org/packages/96/79/3b4f948bd01be11c6748ac0f021573db318597c6c2f9fe41115f76f5e129/aaclient-0.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-05 03:57:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mdavidsaver",
"github_project": "aaclient",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "numpy",
"specs": [
[
">=",
"1.7.0"
]
]
},
{
"name": "Cython",
"specs": [
[
">=",
"0.20"
]
]
},
{
"name": "aiohttp",
"specs": [
[
">=",
"3.7.0"
]
]
}
],
"lcname": "aaclient"
}