EagleWrapper 1.2.0__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.
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/MANIFEST.in +0 -4
- {eaglewrapper-1.2.0/src/EagleWrapper.egg-info → eaglewrapper-2.0.0}/PKG-INFO +120 -4
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/README.md +117 -2
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/setup.py +24 -15
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0/src/EagleWrapper.egg-info}/PKG-INFO +120 -4
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/EagleWrapper.egg-info/SOURCES.txt +3 -2
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/__init__.py +5 -2
- eaglewrapper-2.0.0/src/eaglewrapper/_apis.py +62 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/client.py +13 -4
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/eagle.py +57 -65
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/v2.py +30 -29
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/fakes.py +5 -2
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_api_requests.py +11 -18
- eaglewrapper-2.0.0/tests/test_apis.py +67 -0
- eaglewrapper-2.0.0/tests/test_readme.py +36 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_v2.py +14 -0
- eaglewrapper-1.2.0/reinstall.bat +0 -1
- eaglewrapper-1.2.0/reinstall.sh +0 -2
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/LICENSE +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/doc/add-from-url.png +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/doc/api-overview.png +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/doc/repo-logo.png +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/pyproject.toml +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/setup.cfg +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/EagleWrapper.egg-info/dependency_links.txt +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/EagleWrapper.egg-info/requires.txt +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/EagleWrapper.egg-info/top_level.txt +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/_library.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/errors.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/src/eaglewrapper/py.typed +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/__init__.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_compat.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_connection_options.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_eagle.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_errors.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_library_folder.py +0 -0
- {eaglewrapper-1.2.0 → eaglewrapper-2.0.0}/tests/test_v1_additions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: EagleWrapper
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A wrapper for the local HTTP API (V1 and Web API V2) of Eagle, an image management app.
|
|
5
5
|
Home-page: https://github.com/NatLee/eagle-wrapper
|
|
6
6
|
Author: Nat Lee
|
|
@@ -13,7 +13,8 @@ Project-URL: Eagle Web API V2, https://developer.eagle.cool/web-api
|
|
|
13
13
|
Keywords: eagle,eagle api,eagle web api,image management,asset management,wrapper
|
|
14
14
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
-
Classifier: Topic ::
|
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
18
|
Classifier: Programming Language :: Python :: 3
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.6
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.7
|
|
@@ -94,6 +95,7 @@ pip install EagleWrapper
|
|
|
94
95
|
|
|
95
96
|
Python 3.6 or later. Eagle must be running for everything except the library-folder reader.
|
|
96
97
|
Web API V2, the connection options and the new exceptions arrived in 1.2.0.
|
|
98
|
+
Which release speaks which Eagle API, and what to pin: see [Versioning](#versioning).
|
|
97
99
|
|
|
98
100
|
## Quick start
|
|
99
101
|
|
|
@@ -243,8 +245,25 @@ These are the methods of 1.1.1, unchanged, plus `star`, `get_library_icon` and `
|
|
|
243
245
|
| **No API** | `get_img_info_from_lib_path(library_path, name_start_filters, max_workers, match)` | reads the library folder | list |
|
|
244
246
|
| **Helpers** | `supports_v2()` · `check_success(response_or_dict)` | | bool |
|
|
245
247
|
|
|
246
|
-
`add_from_path` returns Eagle's whole reply
|
|
247
|
-
|
|
248
|
+
`add_from_path` returns Eagle's whole reply (a dict such as `{'status': 'success'}`), not a bool, because
|
|
249
|
+
1.1.1 did and scripts may read it. A dict is always truthy, so `if eagle.add_from_path(...)` passes even when Eagle
|
|
250
|
+
refused the file. Check the reply, or let failures raise:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
from eaglewrapper import Eagle, EagleAPIError
|
|
254
|
+
|
|
255
|
+
eagle = Eagle()
|
|
256
|
+
reply = eagle.add_from_path('/path/to/cat.jpg', 'Cat')
|
|
257
|
+
if eagle.check_success(reply): # True only for {'status': 'success', ...}
|
|
258
|
+
print('added')
|
|
259
|
+
else:
|
|
260
|
+
print('Eagle said no:', reply)
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
Eagle(raise_errors=True).add_from_path('/path/to/cat.jpg', 'Cat')
|
|
264
|
+
except EagleAPIError as e:
|
|
265
|
+
print('Eagle said no:', e.message)
|
|
266
|
+
```
|
|
248
267
|
|
|
249
268
|
## Reading a library folder without Eagle
|
|
250
269
|
|
|
@@ -299,6 +318,87 @@ Moving a V1 script to V2 when your Eagle is 4.0 Build 21 or later:
|
|
|
299
318
|
| `get_application_info()` | `v2.app.info()` | |
|
|
300
319
|
| `get_thumbnail_path(id)` | none | keep using V1 |
|
|
301
320
|
|
|
321
|
+
## Versioning
|
|
322
|
+
|
|
323
|
+
The version number follows Eagle's API. The major number is the newest Eagle API generation a release
|
|
324
|
+
speaks: 1 for V1, Eagle's original `/api/` API, and 2 for Web API V2 (`/api/v2/`). A test keeps the two in
|
|
325
|
+
step. Minor releases wrap more
|
|
326
|
+
of that API (often what a new Eagle build added) or add options to the package, and patch releases fix bugs.
|
|
327
|
+
Code that works with one release keeps working with later releases that have the same major number.
|
|
328
|
+
One slip from the early days: 1.1.0 renamed two arguments of 1.0.0 and changed what `add_from_url` and
|
|
329
|
+
`set_tag_with_id` return.
|
|
330
|
+
|
|
331
|
+
Eagle numbers its API only as V1 and V2. Whatever it adds inside a generation is tied to the Eagle build
|
|
332
|
+
that brought it (see the [V1 changelog](https://api.eagle.cool/changelog) and the
|
|
333
|
+
[V2 changelog](https://developer.eagle.cool/web-api/changelog)), so each release says which builds it covers:
|
|
334
|
+
|
|
335
|
+
| EagleWrapper | Eagle APIs | What it wraps |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| 1.0.0 (April 2023) | V1 | 3 endpoints (add from URL, list items, update item) and the library-folder reader |
|
|
338
|
+
| 1.1.0, 1.1.1 (April 2023) | V1 | all 21 endpoints documented at the time |
|
|
339
|
+
| 1.2.0 (November 2026) | V1 and Web API V2 | V1 up to its last change (Eagle 3.0 Build 23) plus `/api/library/icon`; V2 up to Eagle 4.0 Build 22 (smart folders, comments) |
|
|
340
|
+
| 2.0.0 (November 2026) | V1 and Web API V2 | the same as 1.2.0, plus `SUPPORTED_APIS` (below) |
|
|
341
|
+
|
|
342
|
+
1.2.0 is the odd one out. It was the first release that speaks Web API V2, but it came out as 1.2.0,
|
|
343
|
+
before this rule was written down, because nothing changed for code written against V1. 2.0.0 puts the
|
|
344
|
+
number back on the rule. It is the 1.2.0 code with this versioning written down and `SUPPORTED_APIS`
|
|
345
|
+
added, so going from 1.2.0 to 2.0.0 needs no change in your code.
|
|
346
|
+
|
|
347
|
+
The installed package knows what it covers:
|
|
348
|
+
|
|
349
|
+
```python
|
|
350
|
+
import eaglewrapper
|
|
351
|
+
|
|
352
|
+
for api in eaglewrapper.SUPPORTED_APIS:
|
|
353
|
+
print(f'{api.name}: {api.prefix}... needs Eagle {api.since}+, wrapped up to Eagle {api.covered_up_to}')
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
```text
|
|
357
|
+
V1: /api/... needs Eagle 1.11 Build 21+, wrapped up to Eagle 3.0 Build 23
|
|
358
|
+
Web API V2: /api/v2/... needs Eagle 4.0 Build 21+, wrapped up to Eagle 4.0 Build 22
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
To see what your Eagle has, `Eagle().get_application_info()` returns its `version` and `buildVersion`,
|
|
362
|
+
and `Eagle().supports_v2()` says whether Web API V2 is there. Endpoints that Eagle adds after the covered
|
|
363
|
+
build are one call away with `eagle.v2.request('GET', 'section/endpoint')`. So are `item/open`,
|
|
364
|
+
`item/select` and `folder/open`: the V2 changelog lists them, but the docs have no page for them yet, so
|
|
365
|
+
they are not wrapped.
|
|
366
|
+
|
|
367
|
+
What to pin: the major number, `EagleWrapper~=2.0` (that is `>=2.0, <3`). You get fixes and newly
|
|
368
|
+
wrapped endpoints, and you move to another API generation only when you change the pin. The 1.x line gets
|
|
369
|
+
no more releases: if you pinned `~=1.2`, change it to `~=2.0`; nothing else to do. `eagle.v2` needs
|
|
370
|
+
1.2.0 or later. Scripts that only use the V1 methods run on 1.1.0 and later, but 1.2.0 fixed several bugs
|
|
371
|
+
(see [Upgrading from 1.1.1](#upgrading-from-111)).
|
|
372
|
+
|
|
373
|
+
## Plugins and related projects
|
|
374
|
+
|
|
375
|
+
Not every job needs a script. A few things worth knowing about before you write one:
|
|
376
|
+
|
|
377
|
+
From Eagle:
|
|
378
|
+
|
|
379
|
+
- [Plugin Center](https://community-en.eagle.cool/plugins): plugins you install inside Eagle. The batch job
|
|
380
|
+
you are about to script may already exist as one.
|
|
381
|
+
- [API Playground](https://developer.eagle.cool/web-api/get-started/playground): with Eagle open, visit
|
|
382
|
+
`http://localhost:41595/api/v2/playground` to try any Web API V2 endpoint from a form and see Eagle's real
|
|
383
|
+
reply before you write the Python call. It works on your real library, so writes there are real too.
|
|
384
|
+
- [Plugin API](https://developer.eagle.cool/plugin-api) and the
|
|
385
|
+
[official plugin examples](https://github.com/eagle-app/eagle-plugin-examples): for code that should run
|
|
386
|
+
inside Eagle (a window, a background service, support for a new file format, an inspector panel) rather
|
|
387
|
+
than talk to it from outside. The examples have one small working plugin per type.
|
|
388
|
+
- [AI Search](https://eagle.cool/support/article/ai-search): Eagle's offline search by description or by
|
|
389
|
+
similar image. `eagle.v2.ai_search` only works with this plugin installed.
|
|
390
|
+
- [Eagle Skill / MCP](https://en.eagle.cool/blog/post/eagle-plugin-mcp-skill): lets an AI agent clean up
|
|
391
|
+
tags, plan folders and rewrite names and descriptions in your library. Worth a look when the hard part is
|
|
392
|
+
deciding what to change, not making the calls.
|
|
393
|
+
|
|
394
|
+
Built on EagleWrapper:
|
|
395
|
+
|
|
396
|
+
- [yande-and-konachan-to-eagle](https://github.com/NatLee/yande-and-konachan-to-eagle): fetches images and
|
|
397
|
+
their tags from yande.re and konachan.com and adds them to Eagle with `add_from_url`. A complete,
|
|
398
|
+
small downloader to copy from.
|
|
399
|
+
|
|
400
|
+
Built something with EagleWrapper? Open an issue or a pull request and it can go on this list.
|
|
401
|
+
|
|
302
402
|
## Development
|
|
303
403
|
|
|
304
404
|
The tests replace the HTTP calls with mocks, so Eagle does not need to be running.
|
|
@@ -308,6 +408,13 @@ pip install -e . pytest
|
|
|
308
408
|
pytest tests
|
|
309
409
|
```
|
|
310
410
|
|
|
411
|
+
The editable install picks up your edits right away. To reinstall a regular copy from the checkout instead
|
|
412
|
+
(what the old `reinstall.sh` and `reinstall.bat` did with the retired `setup.py install`):
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
python -m pip install --force-reinstall .
|
|
416
|
+
```
|
|
417
|
+
|
|
311
418
|
`tox -e py` runs the same tests plus a check of the source distribution. CI runs them on Linux with
|
|
312
419
|
Python 3.6 to 3.14, and on Windows and macOS with Python 3.14.
|
|
313
420
|
|
|
@@ -319,8 +426,17 @@ How the code is laid out (`src/eaglewrapper/`):
|
|
|
319
426
|
| `eagle.py` | `Eagle`: the V1 methods, kept compatible with 1.1.1 |
|
|
320
427
|
| `v2.py` | `EagleV2` and its sections (`item`, `folder`, `tag`, ...), plus pagination |
|
|
321
428
|
| `_library.py` | reads `metadata.json` files from a library folder |
|
|
429
|
+
| `_apis.py` | which Eagle APIs and builds this release covers (`SUPPORTED_APIS`); the code, `setup.py` and the README test read it |
|
|
322
430
|
| `errors.py` | the exceptions |
|
|
323
431
|
|
|
432
|
+
## Support
|
|
433
|
+
|
|
434
|
+
EagleWrapper is free and kept up in spare time. If it saved you an afternoon, you can buy me a coffee on
|
|
435
|
+
Ko-fi or chip in on Liberapay. Bug reports and pull requests help just as much.
|
|
436
|
+
|
|
437
|
+
[](https://ko-fi.com/natlee_)
|
|
438
|
+
[](https://liberapay.com/natlee)
|
|
439
|
+
|
|
324
440
|
## Contributor
|
|
325
441
|
|
|
326
442
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
@@ -44,6 +44,7 @@ pip install EagleWrapper
|
|
|
44
44
|
|
|
45
45
|
Python 3.6 or later. Eagle must be running for everything except the library-folder reader.
|
|
46
46
|
Web API V2, the connection options and the new exceptions arrived in 1.2.0.
|
|
47
|
+
Which release speaks which Eagle API, and what to pin: see [Versioning](#versioning).
|
|
47
48
|
|
|
48
49
|
## Quick start
|
|
49
50
|
|
|
@@ -193,8 +194,25 @@ These are the methods of 1.1.1, unchanged, plus `star`, `get_library_icon` and `
|
|
|
193
194
|
| **No API** | `get_img_info_from_lib_path(library_path, name_start_filters, max_workers, match)` | reads the library folder | list |
|
|
194
195
|
| **Helpers** | `supports_v2()` · `check_success(response_or_dict)` | | bool |
|
|
195
196
|
|
|
196
|
-
`add_from_path` returns Eagle's whole reply
|
|
197
|
-
|
|
197
|
+
`add_from_path` returns Eagle's whole reply (a dict such as `{'status': 'success'}`), not a bool, because
|
|
198
|
+
1.1.1 did and scripts may read it. A dict is always truthy, so `if eagle.add_from_path(...)` passes even when Eagle
|
|
199
|
+
refused the file. Check the reply, or let failures raise:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from eaglewrapper import Eagle, EagleAPIError
|
|
203
|
+
|
|
204
|
+
eagle = Eagle()
|
|
205
|
+
reply = eagle.add_from_path('/path/to/cat.jpg', 'Cat')
|
|
206
|
+
if eagle.check_success(reply): # True only for {'status': 'success', ...}
|
|
207
|
+
print('added')
|
|
208
|
+
else:
|
|
209
|
+
print('Eagle said no:', reply)
|
|
210
|
+
|
|
211
|
+
try:
|
|
212
|
+
Eagle(raise_errors=True).add_from_path('/path/to/cat.jpg', 'Cat')
|
|
213
|
+
except EagleAPIError as e:
|
|
214
|
+
print('Eagle said no:', e.message)
|
|
215
|
+
```
|
|
198
216
|
|
|
199
217
|
## Reading a library folder without Eagle
|
|
200
218
|
|
|
@@ -249,6 +267,87 @@ Moving a V1 script to V2 when your Eagle is 4.0 Build 21 or later:
|
|
|
249
267
|
| `get_application_info()` | `v2.app.info()` | |
|
|
250
268
|
| `get_thumbnail_path(id)` | none | keep using V1 |
|
|
251
269
|
|
|
270
|
+
## Versioning
|
|
271
|
+
|
|
272
|
+
The version number follows Eagle's API. The major number is the newest Eagle API generation a release
|
|
273
|
+
speaks: 1 for V1, Eagle's original `/api/` API, and 2 for Web API V2 (`/api/v2/`). A test keeps the two in
|
|
274
|
+
step. Minor releases wrap more
|
|
275
|
+
of that API (often what a new Eagle build added) or add options to the package, and patch releases fix bugs.
|
|
276
|
+
Code that works with one release keeps working with later releases that have the same major number.
|
|
277
|
+
One slip from the early days: 1.1.0 renamed two arguments of 1.0.0 and changed what `add_from_url` and
|
|
278
|
+
`set_tag_with_id` return.
|
|
279
|
+
|
|
280
|
+
Eagle numbers its API only as V1 and V2. Whatever it adds inside a generation is tied to the Eagle build
|
|
281
|
+
that brought it (see the [V1 changelog](https://api.eagle.cool/changelog) and the
|
|
282
|
+
[V2 changelog](https://developer.eagle.cool/web-api/changelog)), so each release says which builds it covers:
|
|
283
|
+
|
|
284
|
+
| EagleWrapper | Eagle APIs | What it wraps |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| 1.0.0 (April 2023) | V1 | 3 endpoints (add from URL, list items, update item) and the library-folder reader |
|
|
287
|
+
| 1.1.0, 1.1.1 (April 2023) | V1 | all 21 endpoints documented at the time |
|
|
288
|
+
| 1.2.0 (November 2026) | V1 and Web API V2 | V1 up to its last change (Eagle 3.0 Build 23) plus `/api/library/icon`; V2 up to Eagle 4.0 Build 22 (smart folders, comments) |
|
|
289
|
+
| 2.0.0 (November 2026) | V1 and Web API V2 | the same as 1.2.0, plus `SUPPORTED_APIS` (below) |
|
|
290
|
+
|
|
291
|
+
1.2.0 is the odd one out. It was the first release that speaks Web API V2, but it came out as 1.2.0,
|
|
292
|
+
before this rule was written down, because nothing changed for code written against V1. 2.0.0 puts the
|
|
293
|
+
number back on the rule. It is the 1.2.0 code with this versioning written down and `SUPPORTED_APIS`
|
|
294
|
+
added, so going from 1.2.0 to 2.0.0 needs no change in your code.
|
|
295
|
+
|
|
296
|
+
The installed package knows what it covers:
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
import eaglewrapper
|
|
300
|
+
|
|
301
|
+
for api in eaglewrapper.SUPPORTED_APIS:
|
|
302
|
+
print(f'{api.name}: {api.prefix}... needs Eagle {api.since}+, wrapped up to Eagle {api.covered_up_to}')
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
```text
|
|
306
|
+
V1: /api/... needs Eagle 1.11 Build 21+, wrapped up to Eagle 3.0 Build 23
|
|
307
|
+
Web API V2: /api/v2/... needs Eagle 4.0 Build 21+, wrapped up to Eagle 4.0 Build 22
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
To see what your Eagle has, `Eagle().get_application_info()` returns its `version` and `buildVersion`,
|
|
311
|
+
and `Eagle().supports_v2()` says whether Web API V2 is there. Endpoints that Eagle adds after the covered
|
|
312
|
+
build are one call away with `eagle.v2.request('GET', 'section/endpoint')`. So are `item/open`,
|
|
313
|
+
`item/select` and `folder/open`: the V2 changelog lists them, but the docs have no page for them yet, so
|
|
314
|
+
they are not wrapped.
|
|
315
|
+
|
|
316
|
+
What to pin: the major number, `EagleWrapper~=2.0` (that is `>=2.0, <3`). You get fixes and newly
|
|
317
|
+
wrapped endpoints, and you move to another API generation only when you change the pin. The 1.x line gets
|
|
318
|
+
no more releases: if you pinned `~=1.2`, change it to `~=2.0`; nothing else to do. `eagle.v2` needs
|
|
319
|
+
1.2.0 or later. Scripts that only use the V1 methods run on 1.1.0 and later, but 1.2.0 fixed several bugs
|
|
320
|
+
(see [Upgrading from 1.1.1](#upgrading-from-111)).
|
|
321
|
+
|
|
322
|
+
## Plugins and related projects
|
|
323
|
+
|
|
324
|
+
Not every job needs a script. A few things worth knowing about before you write one:
|
|
325
|
+
|
|
326
|
+
From Eagle:
|
|
327
|
+
|
|
328
|
+
- [Plugin Center](https://community-en.eagle.cool/plugins): plugins you install inside Eagle. The batch job
|
|
329
|
+
you are about to script may already exist as one.
|
|
330
|
+
- [API Playground](https://developer.eagle.cool/web-api/get-started/playground): with Eagle open, visit
|
|
331
|
+
`http://localhost:41595/api/v2/playground` to try any Web API V2 endpoint from a form and see Eagle's real
|
|
332
|
+
reply before you write the Python call. It works on your real library, so writes there are real too.
|
|
333
|
+
- [Plugin API](https://developer.eagle.cool/plugin-api) and the
|
|
334
|
+
[official plugin examples](https://github.com/eagle-app/eagle-plugin-examples): for code that should run
|
|
335
|
+
inside Eagle (a window, a background service, support for a new file format, an inspector panel) rather
|
|
336
|
+
than talk to it from outside. The examples have one small working plugin per type.
|
|
337
|
+
- [AI Search](https://eagle.cool/support/article/ai-search): Eagle's offline search by description or by
|
|
338
|
+
similar image. `eagle.v2.ai_search` only works with this plugin installed.
|
|
339
|
+
- [Eagle Skill / MCP](https://en.eagle.cool/blog/post/eagle-plugin-mcp-skill): lets an AI agent clean up
|
|
340
|
+
tags, plan folders and rewrite names and descriptions in your library. Worth a look when the hard part is
|
|
341
|
+
deciding what to change, not making the calls.
|
|
342
|
+
|
|
343
|
+
Built on EagleWrapper:
|
|
344
|
+
|
|
345
|
+
- [yande-and-konachan-to-eagle](https://github.com/NatLee/yande-and-konachan-to-eagle): fetches images and
|
|
346
|
+
their tags from yande.re and konachan.com and adds them to Eagle with `add_from_url`. A complete,
|
|
347
|
+
small downloader to copy from.
|
|
348
|
+
|
|
349
|
+
Built something with EagleWrapper? Open an issue or a pull request and it can go on this list.
|
|
350
|
+
|
|
252
351
|
## Development
|
|
253
352
|
|
|
254
353
|
The tests replace the HTTP calls with mocks, so Eagle does not need to be running.
|
|
@@ -258,6 +357,13 @@ pip install -e . pytest
|
|
|
258
357
|
pytest tests
|
|
259
358
|
```
|
|
260
359
|
|
|
360
|
+
The editable install picks up your edits right away. To reinstall a regular copy from the checkout instead
|
|
361
|
+
(what the old `reinstall.sh` and `reinstall.bat` did with the retired `setup.py install`):
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
python -m pip install --force-reinstall .
|
|
365
|
+
```
|
|
366
|
+
|
|
261
367
|
`tox -e py` runs the same tests plus a check of the source distribution. CI runs them on Linux with
|
|
262
368
|
Python 3.6 to 3.14, and on Windows and macOS with Python 3.14.
|
|
263
369
|
|
|
@@ -269,8 +375,17 @@ How the code is laid out (`src/eaglewrapper/`):
|
|
|
269
375
|
| `eagle.py` | `Eagle`: the V1 methods, kept compatible with 1.1.1 |
|
|
270
376
|
| `v2.py` | `EagleV2` and its sections (`item`, `folder`, `tag`, ...), plus pagination |
|
|
271
377
|
| `_library.py` | reads `metadata.json` files from a library folder |
|
|
378
|
+
| `_apis.py` | which Eagle APIs and builds this release covers (`SUPPORTED_APIS`); the code, `setup.py` and the README test read it |
|
|
272
379
|
| `errors.py` | the exceptions |
|
|
273
380
|
|
|
381
|
+
## Support
|
|
382
|
+
|
|
383
|
+
EagleWrapper is free and kept up in spare time. If it saved you an afternoon, you can buy me a coffee on
|
|
384
|
+
Ko-fi or chip in on Liberapay. Bug reports and pull requests help just as much.
|
|
385
|
+
|
|
386
|
+
[](https://ko-fi.com/natlee_)
|
|
387
|
+
[](https://liberapay.com/natlee)
|
|
388
|
+
|
|
274
389
|
## Contributor
|
|
275
390
|
|
|
276
391
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
@@ -1,23 +1,36 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import runpy
|
|
3
|
+
|
|
1
4
|
import setuptools
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
+
|
|
8
|
+
with open(os.path.join(HERE, 'README.md'), 'r', encoding='utf-8') as fh:
|
|
4
9
|
long_description = fh.read()
|
|
5
10
|
|
|
11
|
+
# The Eagle APIs this release speaks (names, docs links) come from the package itself.
|
|
12
|
+
# The file is loaded on its own because importing the package would need its dependencies.
|
|
13
|
+
APIS = runpy.run_path(os.path.join(HERE, 'src', 'eaglewrapper', '_apis.py'))
|
|
14
|
+
API_V1, API_V2 = APIS['API_V1'], APIS['API_V2']
|
|
15
|
+
|
|
16
|
+
REPO = 'https://github.com/NatLee/eagle-wrapper'
|
|
17
|
+
|
|
6
18
|
setuptools.setup(
|
|
7
19
|
name='EagleWrapper',
|
|
8
20
|
author='Nat Lee',
|
|
9
21
|
author_email='natlee.work@gmail.com',
|
|
10
|
-
description='A wrapper for the local HTTP API (
|
|
22
|
+
description='A wrapper for the local HTTP API ({}) of Eagle, an image management app.'.format(
|
|
23
|
+
' and '.join(api.name for api in APIS['SUPPORTED_APIS'])),
|
|
11
24
|
keywords='eagle, eagle api, eagle web api, image management, asset management, wrapper',
|
|
12
25
|
long_description=long_description,
|
|
13
26
|
long_description_content_type='text/markdown',
|
|
14
|
-
url=
|
|
27
|
+
url=REPO,
|
|
15
28
|
project_urls={
|
|
16
|
-
'Documentation':
|
|
17
|
-
'Bug Reports': '
|
|
18
|
-
'Source Code':
|
|
19
|
-
'Official API Documentation':
|
|
20
|
-
'Eagle Web API V2':
|
|
29
|
+
'Documentation': REPO,
|
|
30
|
+
'Bug Reports': REPO + '/issues',
|
|
31
|
+
'Source Code': REPO,
|
|
32
|
+
'Official API Documentation': API_V1.docs,
|
|
33
|
+
'Eagle Web API V2': API_V2.docs,
|
|
21
34
|
# 'Funding': '',
|
|
22
35
|
# 'Say Thanks!': '',
|
|
23
36
|
},
|
|
@@ -29,7 +42,8 @@ setuptools.setup(
|
|
|
29
42
|
'Development Status :: 5 - Production/Stable',
|
|
30
43
|
|
|
31
44
|
'Intended Audience :: Developers',
|
|
32
|
-
'Topic ::
|
|
45
|
+
'Topic :: Multimedia :: Graphics',
|
|
46
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
33
47
|
|
|
34
48
|
'Programming Language :: Python :: 3',
|
|
35
49
|
'Programming Language :: Python :: 3.6',
|
|
@@ -49,10 +63,5 @@ setuptools.setup(
|
|
|
49
63
|
install_requires=['requests', 'loguru'],
|
|
50
64
|
extras_require={
|
|
51
65
|
'dev': ['check-manifest'],
|
|
52
|
-
# 'test': ['coverage'],
|
|
53
66
|
},
|
|
54
|
-
|
|
55
|
-
'console_scripts': [
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
)
|
|
67
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: EagleWrapper
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A wrapper for the local HTTP API (V1 and Web API V2) of Eagle, an image management app.
|
|
5
5
|
Home-page: https://github.com/NatLee/eagle-wrapper
|
|
6
6
|
Author: Nat Lee
|
|
@@ -13,7 +13,8 @@ Project-URL: Eagle Web API V2, https://developer.eagle.cool/web-api
|
|
|
13
13
|
Keywords: eagle,eagle api,eagle web api,image management,asset management,wrapper
|
|
14
14
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
-
Classifier: Topic ::
|
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
18
|
Classifier: Programming Language :: Python :: 3
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.6
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.7
|
|
@@ -94,6 +95,7 @@ pip install EagleWrapper
|
|
|
94
95
|
|
|
95
96
|
Python 3.6 or later. Eagle must be running for everything except the library-folder reader.
|
|
96
97
|
Web API V2, the connection options and the new exceptions arrived in 1.2.0.
|
|
98
|
+
Which release speaks which Eagle API, and what to pin: see [Versioning](#versioning).
|
|
97
99
|
|
|
98
100
|
## Quick start
|
|
99
101
|
|
|
@@ -243,8 +245,25 @@ These are the methods of 1.1.1, unchanged, plus `star`, `get_library_icon` and `
|
|
|
243
245
|
| **No API** | `get_img_info_from_lib_path(library_path, name_start_filters, max_workers, match)` | reads the library folder | list |
|
|
244
246
|
| **Helpers** | `supports_v2()` · `check_success(response_or_dict)` | | bool |
|
|
245
247
|
|
|
246
|
-
`add_from_path` returns Eagle's whole reply
|
|
247
|
-
|
|
248
|
+
`add_from_path` returns Eagle's whole reply (a dict such as `{'status': 'success'}`), not a bool, because
|
|
249
|
+
1.1.1 did and scripts may read it. A dict is always truthy, so `if eagle.add_from_path(...)` passes even when Eagle
|
|
250
|
+
refused the file. Check the reply, or let failures raise:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
from eaglewrapper import Eagle, EagleAPIError
|
|
254
|
+
|
|
255
|
+
eagle = Eagle()
|
|
256
|
+
reply = eagle.add_from_path('/path/to/cat.jpg', 'Cat')
|
|
257
|
+
if eagle.check_success(reply): # True only for {'status': 'success', ...}
|
|
258
|
+
print('added')
|
|
259
|
+
else:
|
|
260
|
+
print('Eagle said no:', reply)
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
Eagle(raise_errors=True).add_from_path('/path/to/cat.jpg', 'Cat')
|
|
264
|
+
except EagleAPIError as e:
|
|
265
|
+
print('Eagle said no:', e.message)
|
|
266
|
+
```
|
|
248
267
|
|
|
249
268
|
## Reading a library folder without Eagle
|
|
250
269
|
|
|
@@ -299,6 +318,87 @@ Moving a V1 script to V2 when your Eagle is 4.0 Build 21 or later:
|
|
|
299
318
|
| `get_application_info()` | `v2.app.info()` | |
|
|
300
319
|
| `get_thumbnail_path(id)` | none | keep using V1 |
|
|
301
320
|
|
|
321
|
+
## Versioning
|
|
322
|
+
|
|
323
|
+
The version number follows Eagle's API. The major number is the newest Eagle API generation a release
|
|
324
|
+
speaks: 1 for V1, Eagle's original `/api/` API, and 2 for Web API V2 (`/api/v2/`). A test keeps the two in
|
|
325
|
+
step. Minor releases wrap more
|
|
326
|
+
of that API (often what a new Eagle build added) or add options to the package, and patch releases fix bugs.
|
|
327
|
+
Code that works with one release keeps working with later releases that have the same major number.
|
|
328
|
+
One slip from the early days: 1.1.0 renamed two arguments of 1.0.0 and changed what `add_from_url` and
|
|
329
|
+
`set_tag_with_id` return.
|
|
330
|
+
|
|
331
|
+
Eagle numbers its API only as V1 and V2. Whatever it adds inside a generation is tied to the Eagle build
|
|
332
|
+
that brought it (see the [V1 changelog](https://api.eagle.cool/changelog) and the
|
|
333
|
+
[V2 changelog](https://developer.eagle.cool/web-api/changelog)), so each release says which builds it covers:
|
|
334
|
+
|
|
335
|
+
| EagleWrapper | Eagle APIs | What it wraps |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| 1.0.0 (April 2023) | V1 | 3 endpoints (add from URL, list items, update item) and the library-folder reader |
|
|
338
|
+
| 1.1.0, 1.1.1 (April 2023) | V1 | all 21 endpoints documented at the time |
|
|
339
|
+
| 1.2.0 (November 2026) | V1 and Web API V2 | V1 up to its last change (Eagle 3.0 Build 23) plus `/api/library/icon`; V2 up to Eagle 4.0 Build 22 (smart folders, comments) |
|
|
340
|
+
| 2.0.0 (November 2026) | V1 and Web API V2 | the same as 1.2.0, plus `SUPPORTED_APIS` (below) |
|
|
341
|
+
|
|
342
|
+
1.2.0 is the odd one out. It was the first release that speaks Web API V2, but it came out as 1.2.0,
|
|
343
|
+
before this rule was written down, because nothing changed for code written against V1. 2.0.0 puts the
|
|
344
|
+
number back on the rule. It is the 1.2.0 code with this versioning written down and `SUPPORTED_APIS`
|
|
345
|
+
added, so going from 1.2.0 to 2.0.0 needs no change in your code.
|
|
346
|
+
|
|
347
|
+
The installed package knows what it covers:
|
|
348
|
+
|
|
349
|
+
```python
|
|
350
|
+
import eaglewrapper
|
|
351
|
+
|
|
352
|
+
for api in eaglewrapper.SUPPORTED_APIS:
|
|
353
|
+
print(f'{api.name}: {api.prefix}... needs Eagle {api.since}+, wrapped up to Eagle {api.covered_up_to}')
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
```text
|
|
357
|
+
V1: /api/... needs Eagle 1.11 Build 21+, wrapped up to Eagle 3.0 Build 23
|
|
358
|
+
Web API V2: /api/v2/... needs Eagle 4.0 Build 21+, wrapped up to Eagle 4.0 Build 22
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
To see what your Eagle has, `Eagle().get_application_info()` returns its `version` and `buildVersion`,
|
|
362
|
+
and `Eagle().supports_v2()` says whether Web API V2 is there. Endpoints that Eagle adds after the covered
|
|
363
|
+
build are one call away with `eagle.v2.request('GET', 'section/endpoint')`. So are `item/open`,
|
|
364
|
+
`item/select` and `folder/open`: the V2 changelog lists them, but the docs have no page for them yet, so
|
|
365
|
+
they are not wrapped.
|
|
366
|
+
|
|
367
|
+
What to pin: the major number, `EagleWrapper~=2.0` (that is `>=2.0, <3`). You get fixes and newly
|
|
368
|
+
wrapped endpoints, and you move to another API generation only when you change the pin. The 1.x line gets
|
|
369
|
+
no more releases: if you pinned `~=1.2`, change it to `~=2.0`; nothing else to do. `eagle.v2` needs
|
|
370
|
+
1.2.0 or later. Scripts that only use the V1 methods run on 1.1.0 and later, but 1.2.0 fixed several bugs
|
|
371
|
+
(see [Upgrading from 1.1.1](#upgrading-from-111)).
|
|
372
|
+
|
|
373
|
+
## Plugins and related projects
|
|
374
|
+
|
|
375
|
+
Not every job needs a script. A few things worth knowing about before you write one:
|
|
376
|
+
|
|
377
|
+
From Eagle:
|
|
378
|
+
|
|
379
|
+
- [Plugin Center](https://community-en.eagle.cool/plugins): plugins you install inside Eagle. The batch job
|
|
380
|
+
you are about to script may already exist as one.
|
|
381
|
+
- [API Playground](https://developer.eagle.cool/web-api/get-started/playground): with Eagle open, visit
|
|
382
|
+
`http://localhost:41595/api/v2/playground` to try any Web API V2 endpoint from a form and see Eagle's real
|
|
383
|
+
reply before you write the Python call. It works on your real library, so writes there are real too.
|
|
384
|
+
- [Plugin API](https://developer.eagle.cool/plugin-api) and the
|
|
385
|
+
[official plugin examples](https://github.com/eagle-app/eagle-plugin-examples): for code that should run
|
|
386
|
+
inside Eagle (a window, a background service, support for a new file format, an inspector panel) rather
|
|
387
|
+
than talk to it from outside. The examples have one small working plugin per type.
|
|
388
|
+
- [AI Search](https://eagle.cool/support/article/ai-search): Eagle's offline search by description or by
|
|
389
|
+
similar image. `eagle.v2.ai_search` only works with this plugin installed.
|
|
390
|
+
- [Eagle Skill / MCP](https://en.eagle.cool/blog/post/eagle-plugin-mcp-skill): lets an AI agent clean up
|
|
391
|
+
tags, plan folders and rewrite names and descriptions in your library. Worth a look when the hard part is
|
|
392
|
+
deciding what to change, not making the calls.
|
|
393
|
+
|
|
394
|
+
Built on EagleWrapper:
|
|
395
|
+
|
|
396
|
+
- [yande-and-konachan-to-eagle](https://github.com/NatLee/yande-and-konachan-to-eagle): fetches images and
|
|
397
|
+
their tags from yande.re and konachan.com and adds them to Eagle with `add_from_url`. A complete,
|
|
398
|
+
small downloader to copy from.
|
|
399
|
+
|
|
400
|
+
Built something with EagleWrapper? Open an issue or a pull request and it can go on this list.
|
|
401
|
+
|
|
302
402
|
## Development
|
|
303
403
|
|
|
304
404
|
The tests replace the HTTP calls with mocks, so Eagle does not need to be running.
|
|
@@ -308,6 +408,13 @@ pip install -e . pytest
|
|
|
308
408
|
pytest tests
|
|
309
409
|
```
|
|
310
410
|
|
|
411
|
+
The editable install picks up your edits right away. To reinstall a regular copy from the checkout instead
|
|
412
|
+
(what the old `reinstall.sh` and `reinstall.bat` did with the retired `setup.py install`):
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
python -m pip install --force-reinstall .
|
|
416
|
+
```
|
|
417
|
+
|
|
311
418
|
`tox -e py` runs the same tests plus a check of the source distribution. CI runs them on Linux with
|
|
312
419
|
Python 3.6 to 3.14, and on Windows and macOS with Python 3.14.
|
|
313
420
|
|
|
@@ -319,8 +426,17 @@ How the code is laid out (`src/eaglewrapper/`):
|
|
|
319
426
|
| `eagle.py` | `Eagle`: the V1 methods, kept compatible with 1.1.1 |
|
|
320
427
|
| `v2.py` | `EagleV2` and its sections (`item`, `folder`, `tag`, ...), plus pagination |
|
|
321
428
|
| `_library.py` | reads `metadata.json` files from a library folder |
|
|
429
|
+
| `_apis.py` | which Eagle APIs and builds this release covers (`SUPPORTED_APIS`); the code, `setup.py` and the README test read it |
|
|
322
430
|
| `errors.py` | the exceptions |
|
|
323
431
|
|
|
432
|
+
## Support
|
|
433
|
+
|
|
434
|
+
EagleWrapper is free and kept up in spare time. If it saved you an afternoon, you can buy me a coffee on
|
|
435
|
+
Ko-fi or chip in on Liberapay. Bug reports and pull requests help just as much.
|
|
436
|
+
|
|
437
|
+
[](https://ko-fi.com/natlee_)
|
|
438
|
+
[](https://liberapay.com/natlee)
|
|
439
|
+
|
|
324
440
|
## Contributor
|
|
325
441
|
|
|
326
442
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
@@ -2,8 +2,6 @@ LICENSE
|
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.md
|
|
4
4
|
pyproject.toml
|
|
5
|
-
reinstall.bat
|
|
6
|
-
reinstall.sh
|
|
7
5
|
setup.cfg
|
|
8
6
|
setup.py
|
|
9
7
|
doc/add-from-url.png
|
|
@@ -15,6 +13,7 @@ src/EagleWrapper.egg-info/dependency_links.txt
|
|
|
15
13
|
src/EagleWrapper.egg-info/requires.txt
|
|
16
14
|
src/EagleWrapper.egg-info/top_level.txt
|
|
17
15
|
src/eaglewrapper/__init__.py
|
|
16
|
+
src/eaglewrapper/_apis.py
|
|
18
17
|
src/eaglewrapper/_library.py
|
|
19
18
|
src/eaglewrapper/client.py
|
|
20
19
|
src/eaglewrapper/eagle.py
|
|
@@ -24,10 +23,12 @@ src/eaglewrapper/v2.py
|
|
|
24
23
|
tests/__init__.py
|
|
25
24
|
tests/fakes.py
|
|
26
25
|
tests/test_api_requests.py
|
|
26
|
+
tests/test_apis.py
|
|
27
27
|
tests/test_compat.py
|
|
28
28
|
tests/test_connection_options.py
|
|
29
29
|
tests/test_eagle.py
|
|
30
30
|
tests/test_errors.py
|
|
31
31
|
tests/test_library_folder.py
|
|
32
|
+
tests/test_readme.py
|
|
32
33
|
tests/test_v1_additions.py
|
|
33
34
|
tests/test_v2.py
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"""A Python wrapper for the local HTTP API of Eagle, the image and design asset manager.
|
|
2
2
|
|
|
3
3
|
* :class:`Eagle` - the V1 (legacy) API methods, the library-folder reader, and ``.v2``.
|
|
4
|
-
* :class:`EagleV2` - the Web API V2 on its own
|
|
4
|
+
* :class:`EagleV2` - the Web API V2 on its own.
|
|
5
5
|
* :mod:`eaglewrapper.errors` - the exceptions.
|
|
6
|
+
* :data:`SUPPORTED_APIS` - which Eagle APIs and Eagle builds this release covers.
|
|
6
7
|
"""
|
|
7
|
-
__version__ = '
|
|
8
|
+
__version__ = '2.0.0'
|
|
8
9
|
|
|
10
|
+
from ._apis import API_V1, API_V2, SUPPORTED_APIS, EagleAPI
|
|
9
11
|
from .client import EagleClient
|
|
10
12
|
from .eagle import Eagle, ImageData
|
|
11
13
|
from .errors import EagleAPIError, EagleConnectionError, EagleError, EagleResponseError
|
|
@@ -14,4 +16,5 @@ from .v2 import EagleV2
|
|
|
14
16
|
__all__ = [
|
|
15
17
|
'Eagle', 'EagleV2', 'EagleClient', 'ImageData',
|
|
16
18
|
'EagleError', 'EagleAPIError', 'EagleConnectionError', 'EagleResponseError',
|
|
19
|
+
'EagleAPI', 'API_V1', 'API_V2', 'SUPPORTED_APIS',
|
|
17
20
|
]
|