elapi 1.0.7.dev8__tar.gz → 2.0.1__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.
Files changed (72) hide show
  1. {elapi-1.0.7.dev8 → elapi-2.0.1}/PKG-INFO +99 -33
  2. {elapi-1.0.7.dev8 → elapi-2.0.1}/README.md +96 -32
  3. {elapi-1.0.7.dev8 → elapi-2.0.1}/pyproject.toml +5 -1
  4. elapi-2.0.1/src/elapi/VERSION +1 -0
  5. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/_names.py +4 -1
  6. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/api/api.py +21 -7
  7. elapi-2.0.1/src/elapi/cli/_plugin_handler.py +413 -0
  8. elapi-2.0.1/src/elapi/cli/_venv_state_manager.py +39 -0
  9. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/cli/doc.py +15 -12
  10. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/cli/elapi.py +330 -166
  11. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/__init__.py +20 -2
  12. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/_config_history.py +1 -0
  13. elapi-2.0.1/src/elapi/configuration/_overload_history.py +145 -0
  14. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/config.py +52 -2
  15. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/overridable_vars.py +7 -0
  16. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/validators.py +17 -83
  17. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/loggers/__init__.py +2 -1
  18. elapi-2.0.1/src/elapi/loggers/base.py +97 -0
  19. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/path.py +1 -1
  20. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/commons/__init__.py +2 -1
  21. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/commons/cli_helpers.py +7 -14
  22. elapi-2.0.1/src/elapi/plugins/commons/get_data_from_input_or_path.py +173 -0
  23. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/experiments/_doc.py +2 -1
  24. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/show_config.py +30 -7
  25. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/__init__.py +1 -0
  26. elapi-2.0.1/src/elapi/styles/rich_utils.py +17 -0
  27. elapi-2.0.1/src/elapi/utils/__init__.py +2 -0
  28. elapi-2.0.1/src/elapi/utils/messages.py +84 -0
  29. elapi-2.0.1/src/elapi/utils/utils.py +22 -0
  30. elapi-1.0.7.dev8/src/elapi/VERSION +0 -1
  31. elapi-1.0.7.dev8/src/elapi/_exceptions.py +0 -1
  32. elapi-1.0.7.dev8/src/elapi/cli/_plugin_handler.py +0 -47
  33. elapi-1.0.7.dev8/src/elapi/loggers/base.py +0 -39
  34. {elapi-1.0.7.dev8 → elapi-2.0.1}/LICENSE +0 -0
  35. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/__init__.py +0 -0
  36. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/api/__init__.py +0 -0
  37. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/api/endpoint.py +0 -0
  38. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/api/validators.py +0 -0
  39. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/cli/__init__.py +0 -0
  40. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/cli/__main__.py +0 -0
  41. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/configuration/log_file.py +0 -0
  42. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/core_validators/__init__.py +0 -0
  43. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/core_validators/base.py +0 -0
  44. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/core_validators/path.py +0 -0
  45. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/loggers/handlers/__init__.py +0 -0
  46. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/loggers/handlers/file.py +0 -0
  47. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/loggers/handlers/stderr.py +0 -0
  48. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/__init__.py +0 -0
  49. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/__init__.py +0 -0
  50. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/_doc.py +0 -0
  51. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/bill_teams.py +0 -0
  52. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/cli.py +0 -0
  53. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/format.py +0 -0
  54. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/generate_table.py +0 -0
  55. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/invoice.py +0 -0
  56. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/specification.py +0 -0
  57. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/bill_teams/validators.py +0 -0
  58. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/commons/export.py +0 -0
  59. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/commons/get_information.py +0 -0
  60. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/commons/get_location_from_headers.py +0 -0
  61. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/experiments/__init__.py +0 -0
  62. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/experiments/cli.py +0 -0
  63. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/experiments/experiments.py +0 -0
  64. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/experiments/formats.py +0 -0
  65. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/plugins/version.py +0 -0
  66. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/_markdown_doc.py +0 -0
  67. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/_missing.py +0 -0
  68. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/base.py +0 -0
  69. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/colors.py +0 -0
  70. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/format.py +0 -0
  71. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/styles/highlight.py +0 -0
  72. {elapi-1.0.7.dev8 → elapi-2.0.1}/src/elapi/validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: elapi
3
- Version: 1.0.7.dev8
3
+ Version: 2.0.1
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
@@ -36,16 +36,21 @@ Requires-Dist: python-dateutil (>=2.8.2,<3.0.0) ; extra == "uhd-urz"
36
36
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
37
37
  Requires-Dist: tenacity (>=8.2.3,<9.0.0) ; extra == "uhd-urz"
38
38
  Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
39
+ Project-URL: Repository, https://github.com/uhd-urz/elAPI/
39
40
  Description-Content-Type: text/markdown
40
41
 
41
42
  # elAPI
42
43
 
43
- elAPI is a powerful, extensible API client for eLabFTW built for
44
- the [University Computing Centre](https://www.urz.uni-heidelberg.de/en) (
45
- URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division) at
46
- Universität Heidelberg. It supports serving almost all kinds of requests documented on
47
- [eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease. elAPI treats eLabFTW API endpoints as its
48
- arguments.
44
+ [![Package version](https://badge.fury.io/py/elapi.svg/?branch=main)](https://pypi.org/project/elapi)
45
+
46
+ elAPI is a powerful, extensible API client for eLabFTW developed at
47
+ the [University Computing Centre](https://www.urz.uni-heidelberg.de/en)
48
+ (URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division) of
49
+ [University of Heidelberg](https://www.uni-heidelberg.de/en). It supports serving all kinds of requests documented on
50
+ [eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease. elAPI provides a simple interface via its CLI
51
+ executable, and numerous advanced APIs when it is used directly as a Python package.
52
+
53
+ ![elAPI features in a nutshell](./.assets/elapi_features.svg)
49
54
 
50
55
  **Example:**
51
56
 
@@ -55,9 +60,14 @@ From [the documentation](https://doc.elabftw.net/api/v2/#/Users/read-user):
55
60
  With elAPI you can do the following:
56
61
 
57
62
  ```sh
58
- $ elapi get users --id <id>
63
+ $ elapi get experiments -f csv --export ~/Downloads/
59
64
  ```
60
65
 
66
+ Once the command is run, in the background, elAPI will read host (eLab server) address, API key and various other
67
+ settings (see [configuration](#configuration)) from the configuration file `elapi.yml`, perform validation (e.g.,
68
+ whether the server address is valid), fetch all _experiments_ list, convert them to `CSV`, and export them to your
69
+ local `~/Downloads/` folder.
70
+
61
71
  ## Installation
62
72
 
63
73
  elAPI can be used both as a CLI tool and as a Python library. If you are interested in simply using elAPI's
@@ -123,10 +133,12 @@ host: <host API url>
123
133
  # Example: https://demo.elabftw.net/api/v2/
124
134
  # Note the host URL ends with the API endpoint
125
135
  api_token: <token with at least read-access>
126
- # You can generate an API token from eLabFTW user panel -> API keys tab.
136
+ # "A.k.a API key". You can generate an API token from eLabFTW user panel -> API keys tab.
127
137
  export_dir: ~/Downloads/elAPI
128
- unsafe_api_token_warning: yes
129
- enable_http2: no
138
+ unsafe_api_token_warning: true
139
+ enable_http2: false
140
+ verify_ssl: true
141
+ timeout: 90
130
142
  ```
131
143
 
132
144
  `export_dir` is where elAPI will export response content to if no path is provided to `--export/-E`.
@@ -134,7 +146,11 @@ When `unsafe_api_token_warning` is `True`, elAPI will show a warning if you're s
134
146
  working directory, as it typically happens that developers accidentally commit and push configuration files with
135
147
  secrets. `enable_http2` enables HTTP/2 protocol support which by default is turned off. Be aware
136
148
  of [known issues](https://github.com/encode/httpx/discussions/2112) with
137
- HTTP/2 if you are making async requests with heavy load.
149
+ HTTP/2 if you are making async requests with heavy load. `verify_ssl` can be turned off with `False` if you are trying
150
+ out a development server that doesn't provide a valid SSL certificate. `timeout` can be modified to your needs. E.g., a
151
+ poor internet connection might benefit from a higher timeout number. THe default timeout is `90` seconds.
152
+
153
+ ### `show-config`
138
154
 
139
155
  You can get an overview of detected configuration with `elapi show-config`. `show-config` makes it easier to verify
140
156
  which configuration values are actually used by elAPI, if you are working with multiple configuration files.
@@ -142,30 +158,40 @@ which configuration values are actually used by elAPI, if you are working with m
142
158
  ```shell
143
159
  $ elapi show-config
144
160
 
145
-
146
- elapi configuration information
161
+ elapi configuration information
147
162
 
148
163
  The following debug information includes configuration values and their sources as detected by elapi.
149
164
 
150
165
  ▌ Name [Key]: Value ← Source
151
166
 
152
- • Log file path: /Users/<username>/.local/share/elapi/elapi.log
153
- • Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
154
- • API Token [api_token]: 00-55******55555 ← USER LEVEL
155
- • Export directory [export_dir]: /Users/<username>/Downloads/elapi ← USER LEVEL
156
- • App data directory: /Users/<username>/.local/share/elapi
157
- • Caching directory: /private/var/tmp/elapi
158
- • Unsafe API token use warning [unsafe_api_token_warning]: Yes ← USER LEVEL
159
- • Enable HTTP/2 [enable_http2]: Yes ← USER LEVEL
167
+ • Log file path: /Users/ <username >/.local/share/elapi/elapi.log
168
+ • Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
169
+ • API Token [api_token]: 00-55******55555 ← USER LEVEL
170
+ • Export directory [export_dir]: /Users/ ← USER LEVEL <username >/Downloads/elapi
171
+ • App data directory: /Users/ <username >/.local/share/elapi
172
+ • Third-party plugins directory: /Users/ <username >/.local/share/elapi/plugins
173
+ • Caching directory: /private/var/tmp/elapi
174
+ • Unsafe API token use warning [unsafe_api_token_warning]: True ← USER LEVEL
175
+ • Enable HTTP/2 [enable_http2]: False ← USER LEVEL
176
+ • Verify SSL certificate [verify_ssl]: True ← USER LEVEL
177
+ • Timeout duration [timeout]: 90.0 seconds ← USER LEVEL
178
+ • Development mode [development_mode]: False ← USER LEVEL
160
179
 
161
180
  Detected configuration sources that are in use:
162
181
 
163
- • USER LEVEL: /Users/<username>/.config/elapi.yml
182
+ • USER LEVEL: /Users/ <username >/.config/elapi.yml
164
183
 
165
184
  ```
166
185
 
167
186
  If both `host` and `api_token` are detected, you are good to go!
168
187
 
188
+ ### Override configuration
189
+
190
+ elAPI now supports `--override/--OC` as a global option that can be used to override the configuration parameters
191
+ as detected by `elapi show-cofig`. All plugins will also automatically listen to the overridden configuration. This can
192
+ be useful to set certain configurations temporarily. E.g., `elapi --OC '{"timeout": 300"}' get info` will override
193
+ the `timeout` from the configuration files.
194
+
169
195
  ## Usage
170
196
 
171
197
  elAPI can be invoked from the command-line.
@@ -253,19 +279,59 @@ You can also upload an attachment to an experiment.
253
279
  $ elapi experiments upload-attachment --id <experiment ID> --path <path to attachment file> --comment <comment for your attachment>
254
280
  ```
255
281
 
256
- ### Bill teams
282
+ ### Plugins
257
283
 
258
- You can get a list of all teams and its users for billing purposes and export it to home directory.
284
+ elAPI has seamless support with tight-integration for third-party plugins. A simple third-party plugin can be created in
285
+ a few easy steps:
259
286
 
260
- ```shell
261
- $ elapi bill-teams teams-info --export ~
287
+ 1. Create a new subfolder under `~/.local/share/elapi/plugins` with the name for your new plugin (e.g, a folder named
288
+ "test")
289
+ 2. Create a `cli.py` in the subfolder with the following snippet:
290
+
291
+ ```python
292
+ from elapi.plugins.commons import Typer
293
+
294
+ app = Typer(name="test", help="Test plugin.")
295
+
296
+ ```
297
+
298
+ 3. Run `elapi` again to see your plugin name under `Third-party plugins` list
299
+
300
+ Plugins are integrated in a way such that a plugin will **not** fail elAPI. So, even if one erroneous plugin is loaded,
301
+ all
302
+ other plugins and elAPI itself will remain unaffected. elAPI will show the error message on the "Message" panel.
303
+
304
+ If you try to import a package that is not a dependency of elAPI inside `cli.py`, your plugin will fail. In that case,
305
+ you want to create a plugin metadata file `elapi_plugin_metadata.yml` (notice only `.yml` extension is allowed), and
306
+ define the virtual environment that your plugin specifically requires.
307
+
308
+ ```python
309
+ import requests
310
+
311
+ from elapi.api import GETRequest
312
+ from elapi.plugins.commons import Typer
313
+
314
+ # Plugin metadata
315
+ app = Typer(name="awesome", help="An awesome elAPI plugin.")
316
+
317
+
318
+ @app.command(name="get-request", short_help=f"Make a GET request")
319
+ def get_request(endpoint_name):
320
+ r = GETRequest()
321
+ print(r(endpoint_name).json())
322
+
323
+
324
+ @app.command(name="get-wiki-status", short_help=f"Show status of Wikipedia")
325
+ def wiki_status():
326
+ r = requests.get("https://wikipedia.org")
327
+ print(r)
262
328
  ```
263
329
 
264
- Most sub-commands available under `elapi bill-teams` plugin are for Universität Heidelberg specific use-cases.
330
+ And the path to virtual environment will be defined in the metadata file:
265
331
 
266
- ## Open-source
332
+ ```yaml
333
+ plugin_name: test
334
+ cli_script: ./cli.py # Path to the cli.py script
335
+ venv_dir: ./.venv # Path to the virtual environment
336
+ ```
267
337
 
268
- elAPI is open-source and published under AGPLv3 license. The repository is however hosted internally within
269
- Universität Heidelberg's network. The codebase can still be accessed from [PyPI](https://pypi.org/project/elapi/#files).
270
- If you express interest in having the repository made completely public, or if you have any question, feel free
271
- to [contact us](mailto:elabftw@uni-heidelberg.de).
@@ -1,11 +1,15 @@
1
1
  # elAPI
2
2
 
3
- elAPI is a powerful, extensible API client for eLabFTW built for
4
- 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) at
6
- Universität Heidelberg. It supports serving almost all kinds of requests documented on
7
- [eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease. elAPI treats eLabFTW API endpoints as its
8
- arguments.
3
+ [![Package version](https://badge.fury.io/py/elapi.svg/?branch=main)](https://pypi.org/project/elapi)
4
+
5
+ elAPI is a powerful, extensible API client for eLabFTW developed at
6
+ the [University Computing Centre](https://www.urz.uni-heidelberg.de/en)
7
+ (URZ, [FIRE](https://www.urz.uni-heidelberg.de/en/node/64/organisation/future-it-research-education) division) of
8
+ [University of Heidelberg](https://www.uni-heidelberg.de/en). It supports serving all kinds of requests documented on
9
+ [eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease. elAPI provides a simple interface via its CLI
10
+ executable, and numerous advanced APIs when it is used directly as a Python package.
11
+
12
+ ![elAPI features in a nutshell](./.assets/elapi_features.svg)
9
13
 
10
14
  **Example:**
11
15
 
@@ -15,9 +19,14 @@ From [the documentation](https://doc.elabftw.net/api/v2/#/Users/read-user):
15
19
  With elAPI you can do the following:
16
20
 
17
21
  ```sh
18
- $ elapi get users --id <id>
22
+ $ elapi get experiments -f csv --export ~/Downloads/
19
23
  ```
20
24
 
25
+ Once the command is run, in the background, elAPI will read host (eLab server) address, API key and various other
26
+ settings (see [configuration](#configuration)) from the configuration file `elapi.yml`, perform validation (e.g.,
27
+ whether the server address is valid), fetch all _experiments_ list, convert them to `CSV`, and export them to your
28
+ local `~/Downloads/` folder.
29
+
21
30
  ## Installation
22
31
 
23
32
  elAPI can be used both as a CLI tool and as a Python library. If you are interested in simply using elAPI's
@@ -83,10 +92,12 @@ host: <host API url>
83
92
  # Example: https://demo.elabftw.net/api/v2/
84
93
  # Note the host URL ends with the API endpoint
85
94
  api_token: <token with at least read-access>
86
- # You can generate an API token from eLabFTW user panel -> API keys tab.
95
+ # "A.k.a API key". You can generate an API token from eLabFTW user panel -> API keys tab.
87
96
  export_dir: ~/Downloads/elAPI
88
- unsafe_api_token_warning: yes
89
- enable_http2: no
97
+ unsafe_api_token_warning: true
98
+ enable_http2: false
99
+ verify_ssl: true
100
+ timeout: 90
90
101
  ```
91
102
 
92
103
  `export_dir` is where elAPI will export response content to if no path is provided to `--export/-E`.
@@ -94,7 +105,11 @@ When `unsafe_api_token_warning` is `True`, elAPI will show a warning if you're s
94
105
  working directory, as it typically happens that developers accidentally commit and push configuration files with
95
106
  secrets. `enable_http2` enables HTTP/2 protocol support which by default is turned off. Be aware
96
107
  of [known issues](https://github.com/encode/httpx/discussions/2112) with
97
- HTTP/2 if you are making async requests with heavy load.
108
+ HTTP/2 if you are making async requests with heavy load. `verify_ssl` can be turned off with `False` if you are trying
109
+ out a development server that doesn't provide a valid SSL certificate. `timeout` can be modified to your needs. E.g., a
110
+ poor internet connection might benefit from a higher timeout number. THe default timeout is `90` seconds.
111
+
112
+ ### `show-config`
98
113
 
99
114
  You can get an overview of detected configuration with `elapi show-config`. `show-config` makes it easier to verify
100
115
  which configuration values are actually used by elAPI, if you are working with multiple configuration files.
@@ -102,30 +117,40 @@ which configuration values are actually used by elAPI, if you are working with m
102
117
  ```shell
103
118
  $ elapi show-config
104
119
 
105
-
106
- elapi configuration information
120
+ elapi configuration information
107
121
 
108
122
  The following debug information includes configuration values and their sources as detected by elapi.
109
123
 
110
124
  ▌ Name [Key]: Value ← Source
111
125
 
112
- • Log file path: /Users/<username>/.local/share/elapi/elapi.log
113
- • Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
114
- • API Token [api_token]: 00-55******55555 ← USER LEVEL
115
- • Export directory [export_dir]: /Users/<username>/Downloads/elapi ← USER LEVEL
116
- • App data directory: /Users/<username>/.local/share/elapi
117
- • Caching directory: /private/var/tmp/elapi
118
- • Unsafe API token use warning [unsafe_api_token_warning]: Yes ← USER LEVEL
119
- • Enable HTTP/2 [enable_http2]: Yes ← USER LEVEL
126
+ • Log file path: /Users/ <username >/.local/share/elapi/elapi.log
127
+ • Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
128
+ • API Token [api_token]: 00-55******55555 ← USER LEVEL
129
+ • Export directory [export_dir]: /Users/ ← USER LEVEL <username >/Downloads/elapi
130
+ • App data directory: /Users/ <username >/.local/share/elapi
131
+ • Third-party plugins directory: /Users/ <username >/.local/share/elapi/plugins
132
+ • Caching directory: /private/var/tmp/elapi
133
+ • Unsafe API token use warning [unsafe_api_token_warning]: True ← USER LEVEL
134
+ • Enable HTTP/2 [enable_http2]: False ← USER LEVEL
135
+ • Verify SSL certificate [verify_ssl]: True ← USER LEVEL
136
+ • Timeout duration [timeout]: 90.0 seconds ← USER LEVEL
137
+ • Development mode [development_mode]: False ← USER LEVEL
120
138
 
121
139
  Detected configuration sources that are in use:
122
140
 
123
- • USER LEVEL: /Users/<username>/.config/elapi.yml
141
+ • USER LEVEL: /Users/ <username >/.config/elapi.yml
124
142
 
125
143
  ```
126
144
 
127
145
  If both `host` and `api_token` are detected, you are good to go!
128
146
 
147
+ ### Override configuration
148
+
149
+ elAPI now supports `--override/--OC` as a global option that can be used to override the configuration parameters
150
+ as detected by `elapi show-cofig`. All plugins will also automatically listen to the overridden configuration. This can
151
+ be useful to set certain configurations temporarily. E.g., `elapi --OC '{"timeout": 300"}' get info` will override
152
+ the `timeout` from the configuration files.
153
+
129
154
  ## Usage
130
155
 
131
156
  elAPI can be invoked from the command-line.
@@ -213,19 +238,58 @@ You can also upload an attachment to an experiment.
213
238
  $ elapi experiments upload-attachment --id <experiment ID> --path <path to attachment file> --comment <comment for your attachment>
214
239
  ```
215
240
 
216
- ### Bill teams
241
+ ### Plugins
217
242
 
218
- You can get a list of all teams and its users for billing purposes and export it to home directory.
243
+ elAPI has seamless support with tight-integration for third-party plugins. A simple third-party plugin can be created in
244
+ a few easy steps:
245
+
246
+ 1. Create a new subfolder under `~/.local/share/elapi/plugins` with the name for your new plugin (e.g, a folder named
247
+ "test")
248
+ 2. Create a `cli.py` in the subfolder with the following snippet:
249
+
250
+ ```python
251
+ from elapi.plugins.commons import Typer
252
+
253
+ app = Typer(name="test", help="Test plugin.")
219
254
 
220
- ```shell
221
- $ elapi bill-teams teams-info --export ~
222
255
  ```
223
256
 
224
- Most sub-commands available under `elapi bill-teams` plugin are for Universität Heidelberg specific use-cases.
257
+ 3. Run `elapi` again to see your plugin name under `Third-party plugins` list
258
+
259
+ Plugins are integrated in a way such that a plugin will **not** fail elAPI. So, even if one erroneous plugin is loaded,
260
+ all
261
+ other plugins and elAPI itself will remain unaffected. elAPI will show the error message on the "Message" panel.
225
262
 
226
- ## Open-source
263
+ If you try to import a package that is not a dependency of elAPI inside `cli.py`, your plugin will fail. In that case,
264
+ you want to create a plugin metadata file `elapi_plugin_metadata.yml` (notice only `.yml` extension is allowed), and
265
+ define the virtual environment that your plugin specifically requires.
227
266
 
228
- elAPI is open-source and published under AGPLv3 license. The repository is however hosted internally within
229
- Universität Heidelberg's network. The codebase can still be accessed from [PyPI](https://pypi.org/project/elapi/#files).
230
- If you express interest in having the repository made completely public, or if you have any question, feel free
231
- to [contact us](mailto:elabftw@uni-heidelberg.de).
267
+ ```python
268
+ import requests
269
+
270
+ from elapi.api import GETRequest
271
+ from elapi.plugins.commons import Typer
272
+
273
+ # Plugin metadata
274
+ app = Typer(name="awesome", help="An awesome elAPI plugin.")
275
+
276
+
277
+ @app.command(name="get-request", short_help=f"Make a GET request")
278
+ def get_request(endpoint_name):
279
+ r = GETRequest()
280
+ print(r(endpoint_name).json())
281
+
282
+
283
+ @app.command(name="get-wiki-status", short_help=f"Show status of Wikipedia")
284
+ def wiki_status():
285
+ r = requests.get("https://wikipedia.org")
286
+ print(r)
287
+ ```
288
+
289
+ And the path to virtual environment will be defined in the metadata file:
290
+
291
+ ```yaml
292
+ plugin_name: test
293
+ cli_script: ./cli.py # Path to the cli.py script
294
+ venv_dir: ./.venv # Path to the virtual environment
295
+ ```
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "elapi"
3
- version = "1.0.7.dev8"
3
+ version = "2.0.1"
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
 
@@ -0,0 +1 @@
1
+ 2.0.1
@@ -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
- CONFIG_FILE_NAME: str = f"{APP_NAME}.yml"
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
- self._client: Union[Client, AsyncClient] = _client(
31
- auth=HeaderApiKey(api_key=self.api_token, header_name=self.header_name),
32
- http2=enable_http2,
33
- verify=verify_ssl,
34
- timeout=timeout,
35
- **kwargs,
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):