elapi 1.0.7.dev7__tar.gz → 2.0.0__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.
- {elapi-1.0.7.dev7 → elapi-2.0.0}/PKG-INFO +93 -30
- {elapi-1.0.7.dev7 → elapi-2.0.0}/README.md +88 -29
- {elapi-1.0.7.dev7 → elapi-2.0.0}/pyproject.toml +7 -1
- elapi-2.0.0/src/elapi/VERSION +1 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/_names.py +4 -1
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/api.py +21 -7
- elapi-2.0.0/src/elapi/cli/_plugin_handler.py +391 -0
- elapi-2.0.0/src/elapi/cli/_venv_state_manager.py +39 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/doc.py +15 -12
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/elapi.py +338 -167
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/__init__.py +19 -2
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/_config_history.py +1 -0
- elapi-2.0.0/src/elapi/configuration/_overload_history.py +145 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/config.py +52 -2
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/overridable_vars.py +7 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/validators.py +17 -83
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/__init__.py +2 -1
- elapi-2.0.0/src/elapi/loggers/base.py +97 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/path.py +1 -1
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/__init__.py +2 -1
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/cli_helpers.py +7 -14
- elapi-2.0.0/src/elapi/plugins/commons/get_data_from_input_or_path.py +173 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/_doc.py +2 -1
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/show_config.py +30 -7
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/__init__.py +1 -0
- elapi-2.0.0/src/elapi/styles/rich_utils.py +17 -0
- elapi-2.0.0/src/elapi/utils/__init__.py +2 -0
- elapi-2.0.0/src/elapi/utils/messages.py +84 -0
- elapi-2.0.0/src/elapi/utils/utils.py +22 -0
- elapi-1.0.7.dev7/src/elapi/VERSION +0 -1
- elapi-1.0.7.dev7/src/elapi/_exceptions.py +0 -1
- elapi-1.0.7.dev7/src/elapi/cli/_plugin_handler.py +0 -47
- elapi-1.0.7.dev7/src/elapi/loggers/base.py +0 -39
- {elapi-1.0.7.dev7 → elapi-2.0.0}/LICENSE +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/endpoint.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/validators.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/__main__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/log_file.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/base.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/path.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/file.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/stderr.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/_doc.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/bill_teams.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/cli.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/format.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/generate_table.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/invoice.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/specification.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/validators.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/export.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/get_information.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/get_location_from_headers.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/__init__.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/cli.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/experiments.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/formats.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/version.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/_markdown_doc.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/_missing.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/base.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/colors.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/format.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/highlight.py +0 -0
- {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: elapi
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: elAPI is a powerful, extensible API client for eLabFTW.
|
|
5
5
|
Home-page: https://www.urz.uni-heidelberg.de/en/service-catalogue/software-and-applications/elabftw
|
|
6
6
|
License: AGPL-3.0-only
|
|
@@ -32,18 +32,25 @@ Requires-Dist: h2 (>=4.1.0,<5.0.0)
|
|
|
32
32
|
Requires-Dist: httpx (>=0.24.1,<0.25.0)
|
|
33
33
|
Requires-Dist: httpx-auth (>=0.17.0,<0.18.0)
|
|
34
34
|
Requires-Dist: mistune (>=3.0.2,<4.0.0)
|
|
35
|
+
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0) ; extra == "uhd-urz"
|
|
35
36
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
37
|
+
Requires-Dist: tenacity (>=8.2.3,<9.0.0) ; extra == "uhd-urz"
|
|
36
38
|
Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
|
|
39
|
+
Project-URL: Repository, https://github.com/uhd-urz/elAPI/
|
|
37
40
|
Description-Content-Type: text/markdown
|
|
38
41
|
|
|
39
42
|
# elAPI
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
<a href="https://pypi.org/project/elapi/">
|
|
45
|
+
<img src="https://badge.fury.io/py/elapi.svg" alt="Package version">
|
|
46
|
+
</a>
|
|
47
|
+
<br />
|
|
48
|
+
<br />
|
|
49
|
+
elAPI is a powerful, extensible API client for eLabFTW developed at
|
|
42
50
|
the [University Computing Centre](https://www.urz.uni-heidelberg.de/en) (
|
|
43
|
-
URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division)
|
|
44
|
-
|
|
45
|
-
[eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease.
|
|
46
|
-
arguments.
|
|
51
|
+
URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division) of
|
|
52
|
+
[University of Heidelberg](https://www.uni-heidelberg.de/en). It supports serving all kinds of requests documented on
|
|
53
|
+
[eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease.
|
|
47
54
|
|
|
48
55
|
**Example:**
|
|
49
56
|
|
|
@@ -123,8 +130,10 @@ host: <host API url>
|
|
|
123
130
|
api_token: <token with at least read-access>
|
|
124
131
|
# You can generate an API token from eLabFTW user panel -> API keys tab.
|
|
125
132
|
export_dir: ~/Downloads/elAPI
|
|
126
|
-
unsafe_api_token_warning:
|
|
127
|
-
enable_http2:
|
|
133
|
+
unsafe_api_token_warning: true
|
|
134
|
+
enable_http2: false
|
|
135
|
+
verify_ssl: true
|
|
136
|
+
timeout: 90
|
|
128
137
|
```
|
|
129
138
|
|
|
130
139
|
`export_dir` is where elAPI will export response content to if no path is provided to `--export/-E`.
|
|
@@ -132,7 +141,11 @@ When `unsafe_api_token_warning` is `True`, elAPI will show a warning if you're s
|
|
|
132
141
|
working directory, as it typically happens that developers accidentally commit and push configuration files with
|
|
133
142
|
secrets. `enable_http2` enables HTTP/2 protocol support which by default is turned off. Be aware
|
|
134
143
|
of [known issues](https://github.com/encode/httpx/discussions/2112) with
|
|
135
|
-
HTTP/2 if you are making async requests with heavy load.
|
|
144
|
+
HTTP/2 if you are making async requests with heavy load. `verify_ssl` can be turned off with `False` if you are trying
|
|
145
|
+
out a development server that doesn't provide a valid SSL certificate. `timeout` can be modified to your needs. E.g., a
|
|
146
|
+
poor internet connection might benefit from a higher timeout number. THe default timeout is `90` seconds.
|
|
147
|
+
|
|
148
|
+
### `show-config`
|
|
136
149
|
|
|
137
150
|
You can get an overview of detected configuration with `elapi show-config`. `show-config` makes it easier to verify
|
|
138
151
|
which configuration values are actually used by elAPI, if you are working with multiple configuration files.
|
|
@@ -140,30 +153,40 @@ which configuration values are actually used by elAPI, if you are working with m
|
|
|
140
153
|
```shell
|
|
141
154
|
$ elapi show-config
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
elapi configuration information
|
|
156
|
+
elapi configuration information
|
|
145
157
|
|
|
146
158
|
The following debug information includes configuration values and their sources as detected by elapi.
|
|
147
159
|
|
|
148
160
|
▌ Name [Key]: Value ← Source
|
|
149
161
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
162
|
+
• Log file path: /Users/ <username >/.local/share/elapi/elapi.log
|
|
163
|
+
• Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
|
|
164
|
+
• API Token [api_token]: 00-55******55555 ← USER LEVEL
|
|
165
|
+
• Export directory [export_dir]: /Users/ ← USER LEVEL <username >/Downloads/elapi
|
|
166
|
+
• App data directory: /Users/ <username >/.local/share/elapi
|
|
167
|
+
• Third-party plugins directory: /Users/ <username >/.local/share/elapi/plugins
|
|
168
|
+
• Caching directory: /private/var/tmp/elapi
|
|
169
|
+
• Unsafe API token use warning [unsafe_api_token_warning]: True ← USER LEVEL
|
|
170
|
+
• Enable HTTP/2 [enable_http2]: False ← USER LEVEL
|
|
171
|
+
• Verify SSL certificate [verify_ssl]: True ← USER LEVEL
|
|
172
|
+
• Timeout duration [timeout]: 90.0 seconds ← USER LEVEL
|
|
173
|
+
• Development mode [development_mode]: False ← USER LEVEL
|
|
158
174
|
|
|
159
175
|
Detected configuration sources that are in use:
|
|
160
176
|
|
|
161
|
-
|
|
177
|
+
• USER LEVEL: /Users/ <username >/.config/elapi.yml
|
|
162
178
|
|
|
163
179
|
```
|
|
164
180
|
|
|
165
181
|
If both `host` and `api_token` are detected, you are good to go!
|
|
166
182
|
|
|
183
|
+
### Override configuration
|
|
184
|
+
|
|
185
|
+
elAPI now supports `--override/--OC` as a global option that can be used to override the configuration parameters
|
|
186
|
+
as detected by `elapi show-cofig`. All plugins will also automatically listen to the overridden configuration. This can
|
|
187
|
+
be useful to set certain configurations temporarily. E.g., `elapi --OC '{"timeout": 300"}' get info` will override
|
|
188
|
+
the `timeout` from the configuration files.
|
|
189
|
+
|
|
167
190
|
## Usage
|
|
168
191
|
|
|
169
192
|
elAPI can be invoked from the command-line.
|
|
@@ -251,19 +274,59 @@ You can also upload an attachment to an experiment.
|
|
|
251
274
|
$ elapi experiments upload-attachment --id <experiment ID> --path <path to attachment file> --comment <comment for your attachment>
|
|
252
275
|
```
|
|
253
276
|
|
|
254
|
-
###
|
|
277
|
+
### Plugins
|
|
255
278
|
|
|
256
|
-
|
|
279
|
+
elAPI has seamless support with tight-integration for third-party plugins. A simple third-party plugin can be created in
|
|
280
|
+
a few easy steps:
|
|
281
|
+
|
|
282
|
+
1. Create a new subfolder under `~/.local/share/elapi/plugins` with the name for your new plugin (e.g, a folder named "
|
|
283
|
+
test")
|
|
284
|
+
2. Create a `cli.py` in the subfolder with the following snippet:
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
from elapi.plugins.commons import Typer
|
|
288
|
+
|
|
289
|
+
app = Typer(name="test", help="Test plugin.")
|
|
257
290
|
|
|
258
|
-
```shell
|
|
259
|
-
$ elapi bill-teams teams-info --export ~
|
|
260
291
|
```
|
|
261
292
|
|
|
262
|
-
|
|
293
|
+
3. Run `elapi` again to see your plugin name under `Third-party plugins` list
|
|
294
|
+
|
|
295
|
+
Plugins are integrated in a way such that a plugin will **not** fail elAPI. So, even if one erroneous plugin is loaded,
|
|
296
|
+
all
|
|
297
|
+
other plugins and elAPI itself will remain unaffected. elAPI will show the error message on the "Message" panel.
|
|
298
|
+
|
|
299
|
+
If you try to import a package that is not a dependency of elAPI inside `cli.py`, your plugin will fail. In that case,
|
|
300
|
+
you want to create a plugin metadata file `elapi_plugin_metadata.yml` (notice only `.yml` extension is allowed), and
|
|
301
|
+
define the virtual environment that your plugin specifically requires.
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
import requests
|
|
263
305
|
|
|
264
|
-
|
|
306
|
+
from elapi.api import GETRequest
|
|
307
|
+
from elapi.plugins.commons import Typer
|
|
308
|
+
|
|
309
|
+
# Plugin metadata
|
|
310
|
+
app = Typer(name="awesome", help="An awesome elAPI plugin.")
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@app.command(name="get-request", short_help=f"Make a GET request")
|
|
314
|
+
def get_request(endpoint_name):
|
|
315
|
+
r = GETRequest()
|
|
316
|
+
print(r(endpoint_name).json())
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
@app.command(name="get-wiki-status", short_help=f"Show status of Wikipedia")
|
|
320
|
+
def wiki_status():
|
|
321
|
+
r = requests.get("https://wikipedia.org")
|
|
322
|
+
print(r)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
And the path to virtual environment will be defined in the metadata file:
|
|
326
|
+
|
|
327
|
+
```yaml
|
|
328
|
+
plugin_name: test
|
|
329
|
+
cli_script: ./cli.py # Path to the cli.py script
|
|
330
|
+
venv_dir: ./.venv # Path to the virtual environment
|
|
331
|
+
```
|
|
265
332
|
|
|
266
|
-
elAPI is open-source and published under AGPLv3 license. The repository is however hosted internally within
|
|
267
|
-
Universität Heidelberg's network. The codebase can still be accessed from [PyPI](https://pypi.org/project/elapi/#files).
|
|
268
|
-
If you express interest in having the repository made completely public, or if you have any question, feel free
|
|
269
|
-
to [contact us](mailto:elabftw@uni-heidelberg.de).
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# elAPI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<a href="https://pypi.org/project/elapi/">
|
|
4
|
+
<img src="https://badge.fury.io/py/elapi.svg" alt="Package version">
|
|
5
|
+
</a>
|
|
6
|
+
<br />
|
|
7
|
+
<br />
|
|
8
|
+
elAPI is a powerful, extensible API client for eLabFTW developed at
|
|
4
9
|
the [University Computing Centre](https://www.urz.uni-heidelberg.de/en) (
|
|
5
|
-
URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division)
|
|
6
|
-
|
|
7
|
-
[eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease.
|
|
8
|
-
arguments.
|
|
10
|
+
URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division) of
|
|
11
|
+
[University of Heidelberg](https://www.uni-heidelberg.de/en). It supports serving all kinds of requests documented on
|
|
12
|
+
[eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease.
|
|
9
13
|
|
|
10
14
|
**Example:**
|
|
11
15
|
|
|
@@ -85,8 +89,10 @@ host: <host API url>
|
|
|
85
89
|
api_token: <token with at least read-access>
|
|
86
90
|
# You can generate an API token from eLabFTW user panel -> API keys tab.
|
|
87
91
|
export_dir: ~/Downloads/elAPI
|
|
88
|
-
unsafe_api_token_warning:
|
|
89
|
-
enable_http2:
|
|
92
|
+
unsafe_api_token_warning: true
|
|
93
|
+
enable_http2: false
|
|
94
|
+
verify_ssl: true
|
|
95
|
+
timeout: 90
|
|
90
96
|
```
|
|
91
97
|
|
|
92
98
|
`export_dir` is where elAPI will export response content to if no path is provided to `--export/-E`.
|
|
@@ -94,7 +100,11 @@ When `unsafe_api_token_warning` is `True`, elAPI will show a warning if you're s
|
|
|
94
100
|
working directory, as it typically happens that developers accidentally commit and push configuration files with
|
|
95
101
|
secrets. `enable_http2` enables HTTP/2 protocol support which by default is turned off. Be aware
|
|
96
102
|
of [known issues](https://github.com/encode/httpx/discussions/2112) with
|
|
97
|
-
HTTP/2 if you are making async requests with heavy load.
|
|
103
|
+
HTTP/2 if you are making async requests with heavy load. `verify_ssl` can be turned off with `False` if you are trying
|
|
104
|
+
out a development server that doesn't provide a valid SSL certificate. `timeout` can be modified to your needs. E.g., a
|
|
105
|
+
poor internet connection might benefit from a higher timeout number. THe default timeout is `90` seconds.
|
|
106
|
+
|
|
107
|
+
### `show-config`
|
|
98
108
|
|
|
99
109
|
You can get an overview of detected configuration with `elapi show-config`. `show-config` makes it easier to verify
|
|
100
110
|
which configuration values are actually used by elAPI, if you are working with multiple configuration files.
|
|
@@ -102,30 +112,40 @@ which configuration values are actually used by elAPI, if you are working with m
|
|
|
102
112
|
```shell
|
|
103
113
|
$ elapi show-config
|
|
104
114
|
|
|
105
|
-
|
|
106
|
-
elapi configuration information
|
|
115
|
+
elapi configuration information
|
|
107
116
|
|
|
108
117
|
The following debug information includes configuration values and their sources as detected by elapi.
|
|
109
118
|
|
|
110
119
|
▌ Name [Key]: Value ← Source
|
|
111
120
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
• Log file path: /Users/ <username >/.local/share/elapi/elapi.log
|
|
122
|
+
• Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
|
|
123
|
+
• API Token [api_token]: 00-55******55555 ← USER LEVEL
|
|
124
|
+
• Export directory [export_dir]: /Users/ ← USER LEVEL <username >/Downloads/elapi
|
|
125
|
+
• App data directory: /Users/ <username >/.local/share/elapi
|
|
126
|
+
• Third-party plugins directory: /Users/ <username >/.local/share/elapi/plugins
|
|
127
|
+
• Caching directory: /private/var/tmp/elapi
|
|
128
|
+
• Unsafe API token use warning [unsafe_api_token_warning]: True ← USER LEVEL
|
|
129
|
+
• Enable HTTP/2 [enable_http2]: False ← USER LEVEL
|
|
130
|
+
• Verify SSL certificate [verify_ssl]: True ← USER LEVEL
|
|
131
|
+
• Timeout duration [timeout]: 90.0 seconds ← USER LEVEL
|
|
132
|
+
• Development mode [development_mode]: False ← USER LEVEL
|
|
120
133
|
|
|
121
134
|
Detected configuration sources that are in use:
|
|
122
135
|
|
|
123
|
-
|
|
136
|
+
• USER LEVEL: /Users/ <username >/.config/elapi.yml
|
|
124
137
|
|
|
125
138
|
```
|
|
126
139
|
|
|
127
140
|
If both `host` and `api_token` are detected, you are good to go!
|
|
128
141
|
|
|
142
|
+
### Override configuration
|
|
143
|
+
|
|
144
|
+
elAPI now supports `--override/--OC` as a global option that can be used to override the configuration parameters
|
|
145
|
+
as detected by `elapi show-cofig`. All plugins will also automatically listen to the overridden configuration. This can
|
|
146
|
+
be useful to set certain configurations temporarily. E.g., `elapi --OC '{"timeout": 300"}' get info` will override
|
|
147
|
+
the `timeout` from the configuration files.
|
|
148
|
+
|
|
129
149
|
## Usage
|
|
130
150
|
|
|
131
151
|
elAPI can be invoked from the command-line.
|
|
@@ -213,19 +233,58 @@ You can also upload an attachment to an experiment.
|
|
|
213
233
|
$ elapi experiments upload-attachment --id <experiment ID> --path <path to attachment file> --comment <comment for your attachment>
|
|
214
234
|
```
|
|
215
235
|
|
|
216
|
-
###
|
|
236
|
+
### Plugins
|
|
217
237
|
|
|
218
|
-
|
|
238
|
+
elAPI has seamless support with tight-integration for third-party plugins. A simple third-party plugin can be created in
|
|
239
|
+
a few easy steps:
|
|
240
|
+
|
|
241
|
+
1. Create a new subfolder under `~/.local/share/elapi/plugins` with the name for your new plugin (e.g, a folder named "
|
|
242
|
+
test")
|
|
243
|
+
2. Create a `cli.py` in the subfolder with the following snippet:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from elapi.plugins.commons import Typer
|
|
247
|
+
|
|
248
|
+
app = Typer(name="test", help="Test plugin.")
|
|
219
249
|
|
|
220
|
-
```shell
|
|
221
|
-
$ elapi bill-teams teams-info --export ~
|
|
222
250
|
```
|
|
223
251
|
|
|
224
|
-
|
|
252
|
+
3. Run `elapi` again to see your plugin name under `Third-party plugins` list
|
|
253
|
+
|
|
254
|
+
Plugins are integrated in a way such that a plugin will **not** fail elAPI. So, even if one erroneous plugin is loaded,
|
|
255
|
+
all
|
|
256
|
+
other plugins and elAPI itself will remain unaffected. elAPI will show the error message on the "Message" panel.
|
|
257
|
+
|
|
258
|
+
If you try to import a package that is not a dependency of elAPI inside `cli.py`, your plugin will fail. In that case,
|
|
259
|
+
you want to create a plugin metadata file `elapi_plugin_metadata.yml` (notice only `.yml` extension is allowed), and
|
|
260
|
+
define the virtual environment that your plugin specifically requires.
|
|
225
261
|
|
|
226
|
-
|
|
262
|
+
```python
|
|
263
|
+
import requests
|
|
227
264
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
265
|
+
from elapi.api import GETRequest
|
|
266
|
+
from elapi.plugins.commons import Typer
|
|
267
|
+
|
|
268
|
+
# Plugin metadata
|
|
269
|
+
app = Typer(name="awesome", help="An awesome elAPI plugin.")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@app.command(name="get-request", short_help=f"Make a GET request")
|
|
273
|
+
def get_request(endpoint_name):
|
|
274
|
+
r = GETRequest()
|
|
275
|
+
print(r(endpoint_name).json())
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@app.command(name="get-wiki-status", short_help=f"Show status of Wikipedia")
|
|
279
|
+
def wiki_status():
|
|
280
|
+
r = requests.get("https://wikipedia.org")
|
|
281
|
+
print(r)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
And the path to virtual environment will be defined in the metadata file:
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
plugin_name: test
|
|
288
|
+
cli_script: ./cli.py # Path to the cli.py script
|
|
289
|
+
venv_dir: ./.venv # Path to the virtual environment
|
|
290
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "elapi"
|
|
3
|
-
version = "
|
|
3
|
+
version = "2.0.0"
|
|
4
4
|
description = "elAPI is a powerful, extensible API client for eLabFTW."
|
|
5
5
|
authors = [
|
|
6
6
|
"Alexander Haller, Mahadi Xion <elabftw@uni-heidelberg.de>",
|
|
@@ -10,6 +10,7 @@ maintainers = [
|
|
|
10
10
|
]
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
homepage = "https://www.urz.uni-heidelberg.de/en/service-catalogue/software-and-applications/elabftw"
|
|
13
|
+
repository = "https://github.com/uhd-urz/elAPI/"
|
|
13
14
|
license = "AGPL-3.0-only"
|
|
14
15
|
keywords = ["elabftw", "api"]
|
|
15
16
|
classifiers = [
|
|
@@ -26,6 +27,9 @@ classifiers = [
|
|
|
26
27
|
"Topic :: Utilities",
|
|
27
28
|
]
|
|
28
29
|
|
|
30
|
+
[project.urls]
|
|
31
|
+
Changelog = "https://github.com/uhd-urz/elAPI/blob/main/CHANGELOG.md"
|
|
32
|
+
|
|
29
33
|
[tool.poetry.scripts]
|
|
30
34
|
elapi = "elapi.cli.elapi:app"
|
|
31
35
|
|
|
@@ -38,6 +42,8 @@ typer = { extras = ["all"], version = "^0.9.0" }
|
|
|
38
42
|
pyyaml = "^6.0.1"
|
|
39
43
|
mistune = "^3.0.2"
|
|
40
44
|
h2 = "^4.1.0"
|
|
45
|
+
python-dateutil = { version = "^2.8.2", optional = true }
|
|
46
|
+
tenacity = { version = "^8.2.3", optional = true }
|
|
41
47
|
|
|
42
48
|
[tool.poetry.extras]
|
|
43
49
|
uhd-urz = ["python-dateutil", "tenacity"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.0
|
|
@@ -5,8 +5,10 @@ from pathlib import Path
|
|
|
5
5
|
# In which case, import their counterparts from src/config.py
|
|
6
6
|
# name definitions
|
|
7
7
|
APP_NAME: str = "elapi"
|
|
8
|
+
APP_BRAND_NAME: str = "elAPI"
|
|
8
9
|
LOG_FILE_NAME: str = f"{APP_NAME}.log"
|
|
9
|
-
|
|
10
|
+
CONFIG_FILE_EXTENSION: str = "yml"
|
|
11
|
+
CONFIG_FILE_NAME: str = f"{APP_NAME}.{CONFIG_FILE_EXTENSION}"
|
|
10
12
|
DEFAULT_EXPORT_DATA_FORMAT: str = "json"
|
|
11
13
|
user_home: Path = Path.home()
|
|
12
14
|
cur_dir: Path = Path.cwd()
|
|
@@ -41,6 +43,7 @@ KEY_UNSAFE_TOKEN_WARNING: str = "UNSAFE_API_TOKEN_WARNING"
|
|
|
41
43
|
KEY_ENABLE_HTTP2: str = "ENABLE_HTTP2"
|
|
42
44
|
KEY_VERIFY_SSL: str = "VERIFY_SSL"
|
|
43
45
|
KEY_TIMEOUT: str = "TIMEOUT"
|
|
46
|
+
KEY_DEVELOPMENT_MODE: str = "DEVELOPMENT_MODE"
|
|
44
47
|
|
|
45
48
|
# Log data directory with root permission
|
|
46
49
|
LOG_DIR_ROOT: Path = Path(f"/var/log/{APP_NAME}")
|
|
@@ -5,6 +5,7 @@ from typing import Union, Optional, Tuple
|
|
|
5
5
|
from httpx import Response, Client, AsyncClient, Limits
|
|
6
6
|
from httpx_auth import HeaderApiKey
|
|
7
7
|
|
|
8
|
+
from .. import APP_NAME
|
|
8
9
|
from ..configuration import (
|
|
9
10
|
TOKEN_BEARER,
|
|
10
11
|
get_active_host,
|
|
@@ -19,6 +20,9 @@ class APIRequest(ABC):
|
|
|
19
20
|
__slots__ = "keep_session_open", "_client", "host", "api_token", "header_name"
|
|
20
21
|
|
|
21
22
|
def __init__(self, keep_session_open: bool = False, **kwargs):
|
|
23
|
+
from ..utils import check_reserved_keyword
|
|
24
|
+
from .._names import CONFIG_FILE_NAME
|
|
25
|
+
|
|
22
26
|
self.host: str = get_active_host()
|
|
23
27
|
self.api_token: str = get_active_api_token().token
|
|
24
28
|
self.header_name: str = TOKEN_BEARER
|
|
@@ -27,13 +31,23 @@ class APIRequest(ABC):
|
|
|
27
31
|
verify_ssl = get_active_verify_ssl()
|
|
28
32
|
timeout = get_active_timeout()
|
|
29
33
|
_client = Client if not self.is_async_client else AsyncClient
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
try:
|
|
35
|
+
self._client: Union[Client, AsyncClient] = _client(
|
|
36
|
+
auth=HeaderApiKey(api_key=self.api_token, header_name=self.header_name),
|
|
37
|
+
http2=enable_http2,
|
|
38
|
+
verify=verify_ssl,
|
|
39
|
+
timeout=timeout,
|
|
40
|
+
**kwargs,
|
|
41
|
+
)
|
|
42
|
+
except TypeError as e:
|
|
43
|
+
check_reserved_keyword(
|
|
44
|
+
e,
|
|
45
|
+
what=f"{APP_NAME}",
|
|
46
|
+
against=f"abstract class {APIRequest.__name__}, "
|
|
47
|
+
f"so the parameter remains user-configurable "
|
|
48
|
+
f"through {CONFIG_FILE_NAME} configuration file",
|
|
49
|
+
)
|
|
50
|
+
raise e
|
|
37
51
|
|
|
38
52
|
# noinspection PyMethodOverriding
|
|
39
53
|
def __init_subclass__(cls, /, is_async_client: bool = False, **kwargs):
|