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.
Files changed (72) hide show
  1. {elapi-1.0.7.dev7 → elapi-2.0.0}/PKG-INFO +93 -30
  2. {elapi-1.0.7.dev7 → elapi-2.0.0}/README.md +88 -29
  3. {elapi-1.0.7.dev7 → elapi-2.0.0}/pyproject.toml +7 -1
  4. elapi-2.0.0/src/elapi/VERSION +1 -0
  5. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/_names.py +4 -1
  6. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/api.py +21 -7
  7. elapi-2.0.0/src/elapi/cli/_plugin_handler.py +391 -0
  8. elapi-2.0.0/src/elapi/cli/_venv_state_manager.py +39 -0
  9. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/doc.py +15 -12
  10. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/elapi.py +338 -167
  11. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/__init__.py +19 -2
  12. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/_config_history.py +1 -0
  13. elapi-2.0.0/src/elapi/configuration/_overload_history.py +145 -0
  14. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/config.py +52 -2
  15. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/overridable_vars.py +7 -0
  16. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/validators.py +17 -83
  17. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/__init__.py +2 -1
  18. elapi-2.0.0/src/elapi/loggers/base.py +97 -0
  19. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/path.py +1 -1
  20. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/__init__.py +2 -1
  21. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/cli_helpers.py +7 -14
  22. elapi-2.0.0/src/elapi/plugins/commons/get_data_from_input_or_path.py +173 -0
  23. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/_doc.py +2 -1
  24. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/show_config.py +30 -7
  25. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/__init__.py +1 -0
  26. elapi-2.0.0/src/elapi/styles/rich_utils.py +17 -0
  27. elapi-2.0.0/src/elapi/utils/__init__.py +2 -0
  28. elapi-2.0.0/src/elapi/utils/messages.py +84 -0
  29. elapi-2.0.0/src/elapi/utils/utils.py +22 -0
  30. elapi-1.0.7.dev7/src/elapi/VERSION +0 -1
  31. elapi-1.0.7.dev7/src/elapi/_exceptions.py +0 -1
  32. elapi-1.0.7.dev7/src/elapi/cli/_plugin_handler.py +0 -47
  33. elapi-1.0.7.dev7/src/elapi/loggers/base.py +0 -39
  34. {elapi-1.0.7.dev7 → elapi-2.0.0}/LICENSE +0 -0
  35. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/__init__.py +0 -0
  36. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/__init__.py +0 -0
  37. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/endpoint.py +0 -0
  38. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/api/validators.py +0 -0
  39. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/__init__.py +0 -0
  40. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/cli/__main__.py +0 -0
  41. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/configuration/log_file.py +0 -0
  42. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/__init__.py +0 -0
  43. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/base.py +0 -0
  44. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/core_validators/path.py +0 -0
  45. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/__init__.py +0 -0
  46. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/file.py +0 -0
  47. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/loggers/handlers/stderr.py +0 -0
  48. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/__init__.py +0 -0
  49. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/__init__.py +0 -0
  50. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/_doc.py +0 -0
  51. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/bill_teams.py +0 -0
  52. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/cli.py +0 -0
  53. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/format.py +0 -0
  54. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/generate_table.py +0 -0
  55. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/invoice.py +0 -0
  56. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/specification.py +0 -0
  57. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/bill_teams/validators.py +0 -0
  58. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/export.py +0 -0
  59. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/get_information.py +0 -0
  60. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/commons/get_location_from_headers.py +0 -0
  61. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/__init__.py +0 -0
  62. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/cli.py +0 -0
  63. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/experiments.py +0 -0
  64. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/experiments/formats.py +0 -0
  65. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/plugins/version.py +0 -0
  66. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/_markdown_doc.py +0 -0
  67. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/_missing.py +0 -0
  68. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/base.py +0 -0
  69. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/colors.py +0 -0
  70. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/format.py +0 -0
  71. {elapi-1.0.7.dev7 → elapi-2.0.0}/src/elapi/styles/highlight.py +0 -0
  72. {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: 1.0.7.dev7
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
- elAPI is a powerful, extensible API client for eLabFTW built for
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) at
44
- Universität Heidelberg. It supports serving almost all kinds of requests documented on
45
- [eLabFTW API documentation](https://doc.elabftw.net/api/v2/) with ease. elAPI treats eLabFTW API endpoints as its
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: yes
127
- enable_http2: no
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
- • Log file path: /Users/<username>/.local/share/elapi/elapi.log
151
- • Host address [host]: https://demo.elabftw.net/api/v2 ← USER LEVEL
152
- • API Token [api_token]: 00-55******55555 ← USER LEVEL
153
- • Export directory [export_dir]: /Users/<username>/Downloads/elapi ← USER LEVEL
154
- • App data directory: /Users/<username>/.local/share/elapi
155
- • Caching directory: /private/var/tmp/elapi
156
- • Unsafe API token use warning [unsafe_api_token_warning]: Yes ← USER LEVEL
157
- • Enable HTTP/2 [enable_http2]: Yes ← USER LEVEL
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
- • USER LEVEL: /Users/<username>/.config/elapi.yml
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
- ### Bill teams
277
+ ### Plugins
255
278
 
256
- You can get a list of all teams and its users for billing purposes and export it to home directory.
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
- Most sub-commands available under `elapi bill-teams` plugin are for Universität Heidelberg specific use-cases.
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
- ## Open-source
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
- elAPI is a powerful, extensible API client for eLabFTW built for
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) 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.
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: yes
89
- enable_http2: no
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
- • 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
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
- • USER LEVEL: /Users/<username>/.config/elapi.yml
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
- ### Bill teams
236
+ ### Plugins
217
237
 
218
- You can get a list of all teams and its users for billing purposes and export it to home directory.
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
- Most sub-commands available under `elapi bill-teams` plugin are for Universität Heidelberg specific use-cases.
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
- ## Open-source
262
+ ```python
263
+ import requests
227
264
 
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).
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 = "1.0.7.dev7"
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
- 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):