async-httpd-data-collector 0.1__tar.gz → 0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- async_httpd_data_collector-0.2/.github/workflows/publish.yml +116 -0
- async_httpd_data_collector-0.2/LICENSE +21 -0
- async_httpd_data_collector-0.2/PKG-INFO +152 -0
- async_httpd_data_collector-0.2/README.md +69 -0
- async_httpd_data_collector-0.2/ahttpdc/__init__.py +1 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/fetch/async_fetch.py +25 -15
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/interface.py +22 -13
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/query/async_query.py +10 -9
- async_httpd_data_collector-0.2/examples/dev_dashboard.py +110 -0
- async_httpd_data_collector-0.2/examples/minimal-example.py +34 -0
- async_httpd_data_collector-0.2/influx +0 -0
- async_httpd_data_collector-0.2/influxdb2-client-2.7.5-linux-amd64.tar.gz +0 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/pyproject.toml +13 -1
- async_httpd_data_collector-0.2/tests/dev_server.py +37 -0
- async_httpd_data_collector-0.2/tests/reads/fetch/test_fetcher.py +78 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/tests/reads/query/test_query.py +56 -29
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/tests/reads/test_interface.py +42 -22
- async_httpd_data_collector-0.1/LICENSE +0 -674
- async_httpd_data_collector-0.1/PKG-INFO +0 -743
- async_httpd_data_collector-0.1/README.md +0 -7
- async_httpd_data_collector-0.1/ahttpdc/__init__.py +0 -1
- async_httpd_data_collector-0.1/examples/dev_dashboard.py +0 -113
- async_httpd_data_collector-0.1/tests/dev_server.py +0 -59
- async_httpd_data_collector-0.1/tests/reads/fetch/test_fetcher.py +0 -55
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/.gitignore +0 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/__init__.py +0 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/fetch/__init__.py +0 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/query/__init__.py +0 -0
- {async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/requirements.txt +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
name: Python CI
|
|
2
|
+
|
|
3
|
+
# publish on push to master
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
deploy:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
services:
|
|
14
|
+
influxdb:
|
|
15
|
+
image: influxdb:2
|
|
16
|
+
ports:
|
|
17
|
+
- 8086:8086
|
|
18
|
+
|
|
19
|
+
flask:
|
|
20
|
+
image: python:3.9
|
|
21
|
+
ports:
|
|
22
|
+
- 5000:5000
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Check out repository
|
|
26
|
+
uses: actions/checkout@v2
|
|
27
|
+
|
|
28
|
+
- name: Install InfluxDB CLI
|
|
29
|
+
run: |
|
|
30
|
+
wget https://download.influxdata.com/influxdb/releases/influxdb2-client-2.7.5-linux-amd64.tar.gz
|
|
31
|
+
tar xvzf ./influxdb2-client-2.7.5-linux-amd64.tar.gz
|
|
32
|
+
sudo cp ./influx /usr/local/bin/
|
|
33
|
+
|
|
34
|
+
- name: Set up InfluxDB
|
|
35
|
+
id: setup-influx
|
|
36
|
+
run: |
|
|
37
|
+
|
|
38
|
+
# passes to test database with no data
|
|
39
|
+
INFLUX_USERNAME="test-user"
|
|
40
|
+
INFLUX_PASSWORD="test-password"
|
|
41
|
+
INFLUX_ORG="test-org"
|
|
42
|
+
INFLUX_BUCKET="test-bucket"
|
|
43
|
+
|
|
44
|
+
# setting up the database
|
|
45
|
+
influx setup \
|
|
46
|
+
--username "$INFLUX_USERNAME" \
|
|
47
|
+
--password "$INFLUX_PASSWORD" \
|
|
48
|
+
--org "$INFLUX_ORG" \
|
|
49
|
+
--bucket "$INFLUX_BUCKET" \
|
|
50
|
+
--force
|
|
51
|
+
|
|
52
|
+
# saving information required for connection later
|
|
53
|
+
echo "::set-output name=org::${INFLUX_ORG}"
|
|
54
|
+
echo "::set-output name=bucket::${INFLUX_BUCKET}"
|
|
55
|
+
|
|
56
|
+
- name: Authorization for InfluxDB
|
|
57
|
+
id: auth
|
|
58
|
+
run: |
|
|
59
|
+
|
|
60
|
+
# authenticating the connection
|
|
61
|
+
INFLUX_TOKEN=$(influx auth create \
|
|
62
|
+
--user "$INFLUX_USERNAME" \
|
|
63
|
+
--org "$INFLUX_ORG" \
|
|
64
|
+
--all-access \
|
|
65
|
+
--description "testing token" \
|
|
66
|
+
--skip-verify \
|
|
67
|
+
--json | jq '.token')
|
|
68
|
+
|
|
69
|
+
# saving the token for the connection
|
|
70
|
+
echo "::set-output name=token::${INFLUX_TOKEN}"
|
|
71
|
+
|
|
72
|
+
- name: Set up Python
|
|
73
|
+
uses: actions/setup-python@v2
|
|
74
|
+
with:
|
|
75
|
+
python-version: '3.11'
|
|
76
|
+
|
|
77
|
+
- name: Install dependencies
|
|
78
|
+
run: |
|
|
79
|
+
python -m pip install --upgrade pip
|
|
80
|
+
pip install build
|
|
81
|
+
pip install ruff
|
|
82
|
+
pip install twine
|
|
83
|
+
pip install -r requirements.txt
|
|
84
|
+
|
|
85
|
+
- name: Lint with ruff
|
|
86
|
+
run: |
|
|
87
|
+
ruff format
|
|
88
|
+
ruff check
|
|
89
|
+
|
|
90
|
+
- name: Test with pytest
|
|
91
|
+
run: |
|
|
92
|
+
|
|
93
|
+
# starting the flask server, supplying some sample data
|
|
94
|
+
export FLASK_APP="tests/dev_server"
|
|
95
|
+
flask run --host=0.0.0.0 --port=9000 &
|
|
96
|
+
sleep 5
|
|
97
|
+
|
|
98
|
+
# setting the connection variables as for the pytest to use
|
|
99
|
+
export PYTHONPATH="$PYTHONPATH:$(pwd)"
|
|
100
|
+
export INFLUXDB_HOST="localhost"
|
|
101
|
+
export INFLUXDB_PORT=8086
|
|
102
|
+
export INFLUXDB_TOKEN=${{steps.auth.outputs.token}}
|
|
103
|
+
export INFLUXDB_ORG=${{steps.setup-influx.outputs.org}}
|
|
104
|
+
export INFLUXDB_BUCKET=${{steps.setup-influx.outputs.bucket}}
|
|
105
|
+
pytest
|
|
106
|
+
|
|
107
|
+
- name: Build the application
|
|
108
|
+
run: |
|
|
109
|
+
python3 -m build
|
|
110
|
+
|
|
111
|
+
- name: Publish to the PyPi
|
|
112
|
+
env:
|
|
113
|
+
TWINE_USERNAME: __token__
|
|
114
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
|
115
|
+
run: |
|
|
116
|
+
python3 -m twine upload dist/*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 InfluxData
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: async-httpd-data-collector
|
|
3
|
+
Version: 0.2
|
|
4
|
+
Summary: Gateway facilitating asyncronous communication between sensory data-emitting devices, InfluxDB and the user.
|
|
5
|
+
Project-URL: Repository, https://github.com/straightchlorine/async-httpd-data-collector
|
|
6
|
+
Project-URL: Issues, https://github.com/straightchlorine/async-httpd-data-collector/issues
|
|
7
|
+
Author-email: Piotr Krzysztof Lis <piotrlis555@gmail.com>
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2021 InfluxData
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Keywords: arduino,async,collector,data,http,influxdb,json,nodemcu,sensors
|
|
31
|
+
Classifier: Development Status :: 3 - Alpha
|
|
32
|
+
Classifier: Intended Audience :: Developers
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Topic :: Database
|
|
35
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
36
|
+
Requires-Python: >=3.8
|
|
37
|
+
Requires-Dist: aiocsv
|
|
38
|
+
Requires-Dist: aiohttp
|
|
39
|
+
Requires-Dist: aiosignal
|
|
40
|
+
Requires-Dist: attrs
|
|
41
|
+
Requires-Dist: certifi
|
|
42
|
+
Requires-Dist: frozenlist
|
|
43
|
+
Requires-Dist: idna
|
|
44
|
+
Requires-Dist: influxdb-client[async]
|
|
45
|
+
Requires-Dist: multidict
|
|
46
|
+
Requires-Dist: numpy
|
|
47
|
+
Requires-Dist: pandas
|
|
48
|
+
Requires-Dist: python-dateutil
|
|
49
|
+
Requires-Dist: pytz
|
|
50
|
+
Requires-Dist: reactivex
|
|
51
|
+
Requires-Dist: setuptools
|
|
52
|
+
Requires-Dist: six
|
|
53
|
+
Requires-Dist: typing-extensions
|
|
54
|
+
Requires-Dist: tzdata
|
|
55
|
+
Requires-Dist: urllib3
|
|
56
|
+
Requires-Dist: yarl
|
|
57
|
+
Provides-Extra: test
|
|
58
|
+
Requires-Dist: blinker; extra == 'test'
|
|
59
|
+
Requires-Dist: charset-normalizer; extra == 'test'
|
|
60
|
+
Requires-Dist: click; extra == 'test'
|
|
61
|
+
Requires-Dist: dash; extra == 'test'
|
|
62
|
+
Requires-Dist: dash-core-components; extra == 'test'
|
|
63
|
+
Requires-Dist: dash-html-components; extra == 'test'
|
|
64
|
+
Requires-Dist: dash-table; extra == 'test'
|
|
65
|
+
Requires-Dist: flask; extra == 'test'
|
|
66
|
+
Requires-Dist: importlib-metadata; extra == 'test'
|
|
67
|
+
Requires-Dist: iniconfig; extra == 'test'
|
|
68
|
+
Requires-Dist: itsdangerous; extra == 'test'
|
|
69
|
+
Requires-Dist: jinja2; extra == 'test'
|
|
70
|
+
Requires-Dist: markupsafe; extra == 'test'
|
|
71
|
+
Requires-Dist: nest-asyncio; extra == 'test'
|
|
72
|
+
Requires-Dist: packaging; extra == 'test'
|
|
73
|
+
Requires-Dist: plotly; extra == 'test'
|
|
74
|
+
Requires-Dist: pluggy; extra == 'test'
|
|
75
|
+
Requires-Dist: pytest; extra == 'test'
|
|
76
|
+
Requires-Dist: pytest-asyncio; extra == 'test'
|
|
77
|
+
Requires-Dist: requests; extra == 'test'
|
|
78
|
+
Requires-Dist: retrying; extra == 'test'
|
|
79
|
+
Requires-Dist: tenacity; extra == 'test'
|
|
80
|
+
Requires-Dist: werkzeug; extra == 'test'
|
|
81
|
+
Requires-Dist: zipp; extra == 'test'
|
|
82
|
+
Description-Content-Type: text/markdown
|
|
83
|
+
|
|
84
|
+
# influx-cli
|
|
85
|
+
|
|
86
|
+
CLI for managing resources in InfluxDB v2
|
|
87
|
+
|
|
88
|
+
## Motivation
|
|
89
|
+
|
|
90
|
+
This repository decouples the `influx` CLI from the OSS `influxdb` codebase. Our goals are to:
|
|
91
|
+
1. Make it easier to keep the CLI up-to-date with InfluxDB Cloud API changes
|
|
92
|
+
2. Enable faster turn-around on fixes/features that only affect the CLI
|
|
93
|
+
3. Allow the CLI to be built & released for a wider range of platforms than the server can support
|
|
94
|
+
|
|
95
|
+
## Building the CLI
|
|
96
|
+
|
|
97
|
+
Follow these steps to build the CLI. If you're updating your CLI build, see *Updating openapi* below.
|
|
98
|
+
1. Clone this repo (influx-cli) and change to your _influx-cli_ directory.
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
git clone git@github.com:influxdata/influx-cli.git
|
|
102
|
+
cd influx-cli
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
2. Build the CLI. The `make` and `make influx` commands write the new binary to `bin/$(GOOS)/influx`.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
make
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Updating openapi
|
|
112
|
+
|
|
113
|
+
If you change or update your branch, you may also need to update `influx-cli/openapi` and regenerate the client code.
|
|
114
|
+
`influx-cli/openapi` is a Git submodule that contains the underlying API contracts and client used by the CLI.
|
|
115
|
+
We use [`OpenAPITools/openapi-generator`](https://github.com/OpenAPITools/openapi-generator) to generate
|
|
116
|
+
the HTTP client.
|
|
117
|
+
|
|
118
|
+
To update, run the following commands in your `influx-cli` repo:
|
|
119
|
+
|
|
120
|
+
1. Update the _openapi_ Git submodule. The following command pulls the latest commits for the branch and all submodules.
|
|
121
|
+
|
|
122
|
+
`git pull --recurse-submodules`
|
|
123
|
+
|
|
124
|
+
2. With [Docker](https://docs.docker.com/get-docker/) running locally, regenerate _openapi_.
|
|
125
|
+
|
|
126
|
+
`make openapi`
|
|
127
|
+
|
|
128
|
+
3. Rebuild the CLI
|
|
129
|
+
|
|
130
|
+
`make`
|
|
131
|
+
|
|
132
|
+
## Running the CLI
|
|
133
|
+
|
|
134
|
+
After building, use `influx -h` to see the list of available commands.
|
|
135
|
+
|
|
136
|
+
### Enabling Completions
|
|
137
|
+
|
|
138
|
+
The CLI supports generating completions for `bash`, `zsh`, and `powershell`. To enable completions for a
|
|
139
|
+
single shell session, run one of these commands:
|
|
140
|
+
```
|
|
141
|
+
# For bash:
|
|
142
|
+
source <(influx completion bash)
|
|
143
|
+
# For zsh:
|
|
144
|
+
source <(influx completion zsh)
|
|
145
|
+
# For pwsh:
|
|
146
|
+
Invoke-Expression ((influx completion powershell) -join "`n`")
|
|
147
|
+
```
|
|
148
|
+
To enable completions across sessions, add the appropriate line to your shell's login profile (i.e. `~/.bash_profile`).
|
|
149
|
+
|
|
150
|
+
## Testing
|
|
151
|
+
|
|
152
|
+
Run `make test` to run unit tests.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# influx-cli
|
|
2
|
+
|
|
3
|
+
CLI for managing resources in InfluxDB v2
|
|
4
|
+
|
|
5
|
+
## Motivation
|
|
6
|
+
|
|
7
|
+
This repository decouples the `influx` CLI from the OSS `influxdb` codebase. Our goals are to:
|
|
8
|
+
1. Make it easier to keep the CLI up-to-date with InfluxDB Cloud API changes
|
|
9
|
+
2. Enable faster turn-around on fixes/features that only affect the CLI
|
|
10
|
+
3. Allow the CLI to be built & released for a wider range of platforms than the server can support
|
|
11
|
+
|
|
12
|
+
## Building the CLI
|
|
13
|
+
|
|
14
|
+
Follow these steps to build the CLI. If you're updating your CLI build, see *Updating openapi* below.
|
|
15
|
+
1. Clone this repo (influx-cli) and change to your _influx-cli_ directory.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
git clone git@github.com:influxdata/influx-cli.git
|
|
19
|
+
cd influx-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. Build the CLI. The `make` and `make influx` commands write the new binary to `bin/$(GOOS)/influx`.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
make
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Updating openapi
|
|
29
|
+
|
|
30
|
+
If you change or update your branch, you may also need to update `influx-cli/openapi` and regenerate the client code.
|
|
31
|
+
`influx-cli/openapi` is a Git submodule that contains the underlying API contracts and client used by the CLI.
|
|
32
|
+
We use [`OpenAPITools/openapi-generator`](https://github.com/OpenAPITools/openapi-generator) to generate
|
|
33
|
+
the HTTP client.
|
|
34
|
+
|
|
35
|
+
To update, run the following commands in your `influx-cli` repo:
|
|
36
|
+
|
|
37
|
+
1. Update the _openapi_ Git submodule. The following command pulls the latest commits for the branch and all submodules.
|
|
38
|
+
|
|
39
|
+
`git pull --recurse-submodules`
|
|
40
|
+
|
|
41
|
+
2. With [Docker](https://docs.docker.com/get-docker/) running locally, regenerate _openapi_.
|
|
42
|
+
|
|
43
|
+
`make openapi`
|
|
44
|
+
|
|
45
|
+
3. Rebuild the CLI
|
|
46
|
+
|
|
47
|
+
`make`
|
|
48
|
+
|
|
49
|
+
## Running the CLI
|
|
50
|
+
|
|
51
|
+
After building, use `influx -h` to see the list of available commands.
|
|
52
|
+
|
|
53
|
+
### Enabling Completions
|
|
54
|
+
|
|
55
|
+
The CLI supports generating completions for `bash`, `zsh`, and `powershell`. To enable completions for a
|
|
56
|
+
single shell session, run one of these commands:
|
|
57
|
+
```
|
|
58
|
+
# For bash:
|
|
59
|
+
source <(influx completion bash)
|
|
60
|
+
# For zsh:
|
|
61
|
+
source <(influx completion zsh)
|
|
62
|
+
# For pwsh:
|
|
63
|
+
Invoke-Expression ((influx completion powershell) -join "`n`")
|
|
64
|
+
```
|
|
65
|
+
To enable completions across sessions, add the appropriate line to your shell's login profile (i.e. `~/.bash_profile`).
|
|
66
|
+
|
|
67
|
+
## Testing
|
|
68
|
+
|
|
69
|
+
Run `make test` to run unit tests.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2'
|
{async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/fetch/async_fetch.py
RENAMED
|
@@ -12,7 +12,7 @@ import aiohttp
|
|
|
12
12
|
from influxdb_client.client.influxdb_client_async import InfluxDBClientAsync
|
|
13
13
|
from influxdb_client.client.write.point import Point
|
|
14
14
|
|
|
15
|
-
__all__ = [
|
|
15
|
+
__all__ = ['AsyncReadFetcher']
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class AsyncReadFetcher:
|
|
@@ -25,7 +25,7 @@ class AsyncReadFetcher:
|
|
|
25
25
|
_influxdb_port (int): The port of the InfluxDB instance.
|
|
26
26
|
_influxdb_token (str): The token to authenticate with InfluxDB.
|
|
27
27
|
_influxdb_organization (str): The organization to use within InfluxDB.
|
|
28
|
-
_influxdb_bucket (str):
|
|
28
|
+
_influxdb_bucket (str): InfluxDB bucket where the data will be stored.
|
|
29
29
|
_device_ip (str): The IP address of device providing sensor readings.
|
|
30
30
|
_device_port (str): The port of the device providing the readings.
|
|
31
31
|
_http_handle (str): The http handle to access the data.
|
|
@@ -48,7 +48,7 @@ class AsyncReadFetcher:
|
|
|
48
48
|
_db_url: str # address of the influxdb instance
|
|
49
49
|
|
|
50
50
|
def __init__(
|
|
51
|
-
self, host, port, token, org, bucket, sensors, dev_ip, dev_port, handle=
|
|
51
|
+
self, host, port, token, org, bucket, sensors, dev_ip, dev_port, handle=''
|
|
52
52
|
):
|
|
53
53
|
"""
|
|
54
54
|
Initialize the fetcher with the required information.
|
|
@@ -78,12 +78,12 @@ class AsyncReadFetcher:
|
|
|
78
78
|
self._dev_handle = handle
|
|
79
79
|
|
|
80
80
|
# device and database URLs
|
|
81
|
-
self._dev_url = f
|
|
82
|
-
self._db_url = f
|
|
81
|
+
self._dev_url = f'http://{self._dev_ip}:{self._dev_port}/{self._dev_handle}'
|
|
82
|
+
self._db_url = f'http://{self._influxdb_host}:{self._influxdb_port}'
|
|
83
83
|
|
|
84
84
|
self._sensors = sensors
|
|
85
85
|
|
|
86
|
-
def _get_reads(self, data) -> dict[str, float]:
|
|
86
|
+
def _get_reads(self, data, device) -> dict[str, float]:
|
|
87
87
|
"""
|
|
88
88
|
Based on sensors specified in sensors attribute fill the fields
|
|
89
89
|
with appropriate key-value pairs for InfluxDB storage.
|
|
@@ -95,10 +95,19 @@ class AsyncReadFetcher:
|
|
|
95
95
|
fields = {}
|
|
96
96
|
for sensor in self._sensors:
|
|
97
97
|
for param in self._sensors[sensor]:
|
|
98
|
-
|
|
98
|
+
if param not in fields:
|
|
99
|
+
fields[param] = float(data[device][sensor][param])
|
|
100
|
+
else:
|
|
101
|
+
# if the measurement already has been recorded, calculate
|
|
102
|
+
# the average of the measurements
|
|
103
|
+
previous = fields[param]
|
|
104
|
+
current = float(data[device][sensor][param])
|
|
105
|
+
average = (previous + current) / 2
|
|
106
|
+
fields[param] = average
|
|
107
|
+
|
|
99
108
|
return fields
|
|
100
109
|
|
|
101
|
-
def _parse_into_records(self, data
|
|
110
|
+
def _parse_into_records(self, data):
|
|
102
111
|
"""
|
|
103
112
|
Parse raw json file into records for InfluxDB.
|
|
104
113
|
|
|
@@ -107,13 +116,14 @@ class AsyncReadFetcher:
|
|
|
107
116
|
device_name (str): The name of the device (default is 'nodemcu').
|
|
108
117
|
"""
|
|
109
118
|
|
|
119
|
+
device = list(data.keys())[0]
|
|
110
120
|
records = {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
'measurement': 'sensor_data',
|
|
122
|
+
'tags': {'device': device},
|
|
123
|
+
'timestamp': str(datetime.datetime.now()),
|
|
114
124
|
}
|
|
115
125
|
|
|
116
|
-
records[
|
|
126
|
+
records['fields'] = self._get_reads(data, device)
|
|
117
127
|
return records
|
|
118
128
|
|
|
119
129
|
async def _write_to_db(self, client, record):
|
|
@@ -125,9 +135,9 @@ class AsyncReadFetcher:
|
|
|
125
135
|
records (dict): The sensor readings as records for InfluxDB.
|
|
126
136
|
"""
|
|
127
137
|
|
|
128
|
-
print(
|
|
138
|
+
print('<.> writing new read into database...')
|
|
129
139
|
write_api = client.write_api()
|
|
130
|
-
point = Point.from_dict(record, write_precision=
|
|
140
|
+
point = Point.from_dict(record, write_precision='ns')
|
|
131
141
|
await write_api.write(
|
|
132
142
|
bucket=self._influxdb_bucket, org=self._influxdb_organization, record=point
|
|
133
143
|
)
|
|
@@ -157,7 +167,7 @@ class AsyncReadFetcher:
|
|
|
157
167
|
|
|
158
168
|
async with session.get(self._dev_url) as response:
|
|
159
169
|
if response.status != 200:
|
|
160
|
-
print(f
|
|
170
|
+
print(f'Error fetching data: {response.status}')
|
|
161
171
|
else:
|
|
162
172
|
read = await response.json()
|
|
163
173
|
return read
|
{async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/interface.py
RENAMED
|
@@ -12,7 +12,7 @@ import pandas as pd
|
|
|
12
12
|
from ahttpdc.reads.fetch.async_fetch import AsyncReadFetcher
|
|
13
13
|
from ahttpdc.reads.query.async_query import AsyncQuery
|
|
14
14
|
|
|
15
|
-
__all__ = [
|
|
15
|
+
__all__ = ['DatabaseInterface']
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class DatabaseInterface:
|
|
@@ -47,7 +47,7 @@ class DatabaseInterface:
|
|
|
47
47
|
_db_url: str # address of the influxdb instance
|
|
48
48
|
|
|
49
49
|
def __init__(
|
|
50
|
-
self, host, port, token, org, bucket, sensors, dev_ip, dev_port, handle=
|
|
50
|
+
self, host, port, token, org, bucket, sensors, dev_ip, dev_port, handle=''
|
|
51
51
|
):
|
|
52
52
|
"""
|
|
53
53
|
Initialize the fetcher with the required information.
|
|
@@ -74,8 +74,8 @@ class DatabaseInterface:
|
|
|
74
74
|
self._dev_port = dev_port
|
|
75
75
|
self._dev_handle = handle
|
|
76
76
|
|
|
77
|
-
self._dev_url = f
|
|
78
|
-
self._db_url = f
|
|
77
|
+
self._dev_url = f'http://{self._dev_ip}:{self._dev_port}/{self._dev_handle}'
|
|
78
|
+
self._db_url = f'http://{self._influxdb_host}:{self._influxdb_port}'
|
|
79
79
|
|
|
80
80
|
self.sensors = sensors
|
|
81
81
|
|
|
@@ -100,6 +100,13 @@ class DatabaseInterface:
|
|
|
100
100
|
self.sensors,
|
|
101
101
|
)
|
|
102
102
|
|
|
103
|
+
def _start_fetching():
|
|
104
|
+
asyncio.run(self._fetcher.schedule_fetcher())
|
|
105
|
+
|
|
106
|
+
self.fetching_process = multiprocessing.Process(
|
|
107
|
+
target=_start_fetching, name='asyncfetcher'
|
|
108
|
+
)
|
|
109
|
+
|
|
103
110
|
def enable_fetching(self):
|
|
104
111
|
"""
|
|
105
112
|
Enable fetching from the device specified by dev_ip, dev_port and handle.
|
|
@@ -108,13 +115,15 @@ class DatabaseInterface:
|
|
|
108
115
|
in order to avoid blocking the main thread.
|
|
109
116
|
"""
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
asyncio.run(self._fetcher.schedule_fetcher())
|
|
118
|
+
self.fetching_process.start()
|
|
113
119
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
def disable_fetching(self):
|
|
121
|
+
"""
|
|
122
|
+
Terminate fetching process.
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
self.fetching_process.terminate()
|
|
126
|
+
self.fetching_process.join()
|
|
118
127
|
|
|
119
128
|
async def query_latest(self) -> pd.DataFrame:
|
|
120
129
|
"""
|
|
@@ -124,7 +133,7 @@ class DatabaseInterface:
|
|
|
124
133
|
pd.DataFrame: The latest measurement.
|
|
125
134
|
"""
|
|
126
135
|
|
|
127
|
-
print(
|
|
136
|
+
print('<.> querying latest measurement...')
|
|
128
137
|
query_task = asyncio.create_task(self.query_interface.latest())
|
|
129
138
|
await query_task
|
|
130
139
|
result = query_task.result()
|
|
@@ -142,7 +151,7 @@ class DatabaseInterface:
|
|
|
142
151
|
pd.DataFrame: Historical data within the specified time range.
|
|
143
152
|
"""
|
|
144
153
|
|
|
145
|
-
print(
|
|
154
|
+
print('<.> querying historical data...')
|
|
146
155
|
query_task = asyncio.create_task(
|
|
147
156
|
self.query_interface.historical_data(start, end)
|
|
148
157
|
)
|
|
@@ -161,7 +170,7 @@ class DatabaseInterface:
|
|
|
161
170
|
pd.DataFrame: The result of the custom query.
|
|
162
171
|
"""
|
|
163
172
|
|
|
164
|
-
print(
|
|
173
|
+
print('<.> custom query...')
|
|
165
174
|
query_task = asyncio.create_task(self.query_interface.query(query))
|
|
166
175
|
await query_task
|
|
167
176
|
result = query_task.result()
|
{async_httpd_data_collector-0.1 → async_httpd_data_collector-0.2}/ahttpdc/reads/query/async_query.py
RENAMED
|
@@ -10,7 +10,7 @@ from influxdb_client.client.exceptions import InfluxDBError
|
|
|
10
10
|
from influxdb_client.client.influxdb_client_async import InfluxDBClientAsync
|
|
11
11
|
import pandas as pd
|
|
12
12
|
|
|
13
|
-
__all__ = [
|
|
13
|
+
__all__ = ['AsyncQuery']
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class AsyncQuery:
|
|
@@ -56,12 +56,13 @@ class AsyncQuery:
|
|
|
56
56
|
self._influxdb_organization = org
|
|
57
57
|
self._influxdb_bucket = bucket
|
|
58
58
|
|
|
59
|
-
self._db_url = f
|
|
59
|
+
self._db_url = f'http://{self._influxdb_host}:{self._influxdb_port}'
|
|
60
60
|
|
|
61
61
|
self.sensors = sensors
|
|
62
62
|
|
|
63
63
|
async def _get_InfluxDB_client(self) -> InfluxDBClientAsync:
|
|
64
64
|
"""Returns an InfluxDB client."""
|
|
65
|
+
|
|
65
66
|
return InfluxDBClientAsync(
|
|
66
67
|
url=self._db_url,
|
|
67
68
|
token=self._influxdb_token,
|
|
@@ -101,7 +102,7 @@ class AsyncQuery:
|
|
|
101
102
|
Returns:
|
|
102
103
|
pd.DataFrame: procured measurements as a DataFrame.
|
|
103
104
|
"""
|
|
104
|
-
|
|
105
|
+
print('into dataframe')
|
|
105
106
|
read: dict = {}
|
|
106
107
|
timestamps = set()
|
|
107
108
|
|
|
@@ -122,12 +123,12 @@ class AsyncQuery:
|
|
|
122
123
|
local_timestamps = self._convert_to_local_time(timestamps)
|
|
123
124
|
|
|
124
125
|
# if there is no time key, create one
|
|
125
|
-
if
|
|
126
|
-
read[
|
|
126
|
+
if 'time' not in read:
|
|
127
|
+
read['time'] = []
|
|
127
128
|
|
|
128
129
|
# add the timestamps to the data dict
|
|
129
130
|
for timestamp in local_timestamps:
|
|
130
|
-
read[
|
|
131
|
+
read['time'].append(pd.to_datetime(timestamp))
|
|
131
132
|
|
|
132
133
|
# return the data as a DataFrame
|
|
133
134
|
return pd.DataFrame(read)
|
|
@@ -151,7 +152,7 @@ class AsyncQuery:
|
|
|
151
152
|
try:
|
|
152
153
|
tables = await query_api.query(query)
|
|
153
154
|
except InfluxDBError as e:
|
|
154
|
-
print(f
|
|
155
|
+
print(f'Exception caught while querying the database:\n\n {e.message}')
|
|
155
156
|
|
|
156
157
|
# close the connection
|
|
157
158
|
await client.close()
|
|
@@ -185,7 +186,7 @@ class AsyncQuery:
|
|
|
185
186
|
try:
|
|
186
187
|
tables = await query_api.query(query)
|
|
187
188
|
except InfluxDBError as e:
|
|
188
|
-
print(f
|
|
189
|
+
print(f'Exception caught while querying the database:\n\n {e.message}')
|
|
189
190
|
|
|
190
191
|
await client.close()
|
|
191
192
|
|
|
@@ -212,7 +213,7 @@ class AsyncQuery:
|
|
|
212
213
|
try:
|
|
213
214
|
tables = await query_api.query(query)
|
|
214
215
|
except InfluxDBError as e:
|
|
215
|
-
print(f
|
|
216
|
+
print(f'Exception caught while querying the database:\n\n {e.message}')
|
|
216
217
|
|
|
217
218
|
await client.close()
|
|
218
219
|
|