easyvista-python-client 0.4.1__tar.gz → 0.4.3__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.
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/CHANGELOG.md +48 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/PKG-INFO +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/content.rst +59 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_version.py +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/content/__init__.py +6 -2
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/content/conversion.py +250 -22
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/pyproject.toml +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-asset-workflow/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-client-setup/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-directory/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-document-workflow/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-instance-discovery/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-reporting-and-context/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-search-syntax/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-ticket-actions/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-ticket-workflow/SKILL.md +1 -1
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/.gitignore +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/.pre-commit-config.yaml +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/.readthedocs.yaml +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/CONTRIBUTING.md +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/LICENSE +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/README.md +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/_static/.gitkeep +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/_templates/.gitkeep +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/api_reference.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/conf.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/development.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/index.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/installation.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/publishing.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/sponsoring.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/user_guide.rst +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/vendor-api-reference.md +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/__init__.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_async/__init__.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_async/_concurrency.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_async/_transport.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_async/client.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_fields.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_html.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_sync/__init__.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_sync/_concurrency.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_sync/_transport.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_sync/client.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_transport.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/config.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/context.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/directory.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/discovery.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/exceptions.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/field_model.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/filters.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/__init__.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/action.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/asset.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/common.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/department.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/document.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/employee.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/generic.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/models/request.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/pagination.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/py.typed +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/references.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/reporting.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/__init__.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/actions.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/assets.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/departments.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/descriptor.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/discovery.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/documents.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/employees.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/resources/requests.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/timestamps.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/workflow.py +0 -0
- {easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/README.md +0 -0
|
@@ -15,6 +15,51 @@ is the error. Tags carry no `v` prefix.
|
|
|
15
15
|
|
|
16
16
|
## [Unreleased]
|
|
17
17
|
|
|
18
|
+
## [0.4.3] - 2026-10-08
|
|
19
|
+
|
|
20
|
+
A patch release of the content reader: a caller can recognise the images a
|
|
21
|
+
memo embeds and decide, link by link, what a read writes. Without the new
|
|
22
|
+
argument a read is unchanged, byte for byte; writing is unchanged, and so is
|
|
23
|
+
everything outside `easyvista_python_client.content`.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **`from_transport(..., rewrite_link=callback)`.** The callback is called with
|
|
28
|
+
a `Link` for each link and image the read meets outside code -- an image
|
|
29
|
+
before the link around it, with that link's `enclosing_href` -- and its
|
|
30
|
+
answer is written: `None` keeps the reader's output, a `str` is written as
|
|
31
|
+
literal text, a `Link` replaces the target (an empty `href` drops a link and
|
|
32
|
+
keeps its content, or writes an image as its text). The callback is held in
|
|
33
|
+
a context variable, so concurrent reads each use their own. What it raises
|
|
34
|
+
reaches the caller unchanged; a `ValueError` is not taken for markdownify's
|
|
35
|
+
and answered with the text fallback.
|
|
36
|
+
- **`Link` and `RewriteLink`**, exported from `easyvista_python_client.content`.
|
|
37
|
+
- **`EasyvistaContentConverter.document_id_of(src)`** returns the
|
|
38
|
+
`DOCUMENT_ID` of an embedded image's `src`
|
|
39
|
+
(`@@EMBEDDED_IMAGE_PATH@@<DOCUMENT_ID>`, how EasyVista's editor embeds a
|
|
40
|
+
pasted image), and **`document_image(document_id, alt=...)`** the Markdown
|
|
41
|
+
of one, spelled as the reader spells it. A `Link` for such an image carries
|
|
42
|
+
its `document_id`. Measured on one instance on 2026-10-07: an image written
|
|
43
|
+
that way through the API displays, for an attachment pasted in the editor
|
|
44
|
+
and for one uploaded with `add_document`.
|
|
45
|
+
- `EasyvistaContentConverter.EMBEDDED_IMAGE_PREFIX`.
|
|
46
|
+
|
|
47
|
+
## [0.4.2] - 2026-10-07
|
|
48
|
+
|
|
49
|
+
A patch release of the content writer: a link written into a memo opens in a
|
|
50
|
+
new window. Reading is unchanged, and so is everything outside
|
|
51
|
+
`easyvista_python_client.content`.
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- **Every link `to_transport` writes carries `target="_blank"
|
|
56
|
+
rel="noopener noreferrer"`**, as a link written in EasyVista's own editor
|
|
57
|
+
does. Without it, EasyVista's memo view opens the link in place, inside its
|
|
58
|
+
own window, so a link to another application seemed to do nothing (measured
|
|
59
|
+
on a live memo, 2026-10-07: links with and without the attributes, side by
|
|
60
|
+
side). Reading ignores both attributes, so `from_transport(to_transport(m))`
|
|
61
|
+
is unchanged for every link.
|
|
62
|
+
|
|
18
63
|
## [0.4.1] - 2026-10-02
|
|
19
64
|
|
|
20
65
|
A patch release of the content reader. A `<u>`, `<mark>` or `<ins>` round a
|
|
@@ -1645,7 +1690,9 @@ Initial public release.
|
|
|
1645
1690
|
status/error code, with non-retryable validation errors (HTTP 590, code 2013).
|
|
1646
1691
|
- `py.typed` marker — the package ships inline type information.
|
|
1647
1692
|
|
|
1648
|
-
[Unreleased]: https://github.com/baraline/easyvista_python_client/compare/0.4.
|
|
1693
|
+
[Unreleased]: https://github.com/baraline/easyvista_python_client/compare/0.4.3...HEAD
|
|
1694
|
+
[0.4.3]: https://github.com/baraline/easyvista_python_client/compare/0.4.2...0.4.3
|
|
1695
|
+
[0.4.2]: https://github.com/baraline/easyvista_python_client/compare/0.4.1...0.4.2
|
|
1649
1696
|
[0.4.1]: https://github.com/baraline/easyvista_python_client/compare/0.4.0...0.4.1
|
|
1650
1697
|
[0.4.0]: https://github.com/baraline/easyvista_python_client/compare/0.3.0...0.4.0
|
|
1651
1698
|
[0.3.0]: https://github.com/baraline/easyvista_python_client/compare/0.2.0...0.3.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: easyvista-python-client
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Typed Python client for the EasyVista Service Manager REST API
|
|
5
5
|
Project-URL: Homepage, https://github.com/baraline/easyvista_python_client
|
|
6
6
|
Project-URL: Documentation, https://easyvista-python-client.readthedocs.io/en/latest/
|
|
@@ -214,6 +214,11 @@ options, ``HARDBREAKS`` and ``UNSAFE``:
|
|
|
214
214
|
* a fence becomes ``<pre><code>``, with the info string as a
|
|
215
215
|
``class="language-..."``;
|
|
216
216
|
* a table becomes a ``<table>`` with a ``<thead>``;
|
|
217
|
+
* a link opens in a new window: each ``<a href>`` the renderer writes carries
|
|
218
|
+
``target="_blank" rel="noopener noreferrer"``, as a link written in
|
|
219
|
+
EasyVista's editor does. Without it the memo view opens the link in place,
|
|
220
|
+
inside EasyVista's window (measured 2026-10-07). Reading ignores both
|
|
221
|
+
attributes, so a round trip is unchanged;
|
|
217
222
|
* raw HTML, inline or as a block, is passed through as written;
|
|
218
223
|
* ``""``, or only whitespace, stays ``""`` rather than becoming ``<p></p>``.
|
|
219
224
|
|
|
@@ -229,6 +234,60 @@ reported as
|
|
|
229
234
|
:class:`~easyvista_python_client.exceptions.EasyvistaContentError`. A block
|
|
230
235
|
quote nested 100,000 levels deep rendered without one (measured 2026-10-02).
|
|
231
236
|
|
|
237
|
+
Embedded images, and rewriting links as they are read
|
|
238
|
+
-----------------------------------------------------
|
|
239
|
+
|
|
240
|
+
EasyVista's editor keeps an image pasted into a memo as an attachment of the
|
|
241
|
+
request, named like ``image_emb_001.png``, and embeds it as
|
|
242
|
+
``<img src="@@EMBEDDED_IMAGE_PATH@@<DOCUMENT_ID>" />``. Without a callback the
|
|
243
|
+
reader writes that as any other image, ````,
|
|
244
|
+
which displays nowhere but in EasyVista. Three helpers let a caller do better.
|
|
245
|
+
|
|
246
|
+
``EasyvistaContentConverter.document_id_of(src)`` returns the ``DOCUMENT_ID``
|
|
247
|
+
an image's ``src`` embeds, or ``None``. ``document_image(document_id, alt=...)``
|
|
248
|
+
returns the Markdown of such an image, spelled exactly as the reader spells
|
|
249
|
+
it, so ``to_transport`` writes the editor's form and ``from_transport`` reads
|
|
250
|
+
it back unchanged. **Tier 4** -- measured on one instance on 2026-10-07: an
|
|
251
|
+
image written that way through the API displays, both for an attachment
|
|
252
|
+
pasted in the editor and for one uploaded with ``add_document``. The memo
|
|
253
|
+
displays it only while the attachment is on the same request.
|
|
254
|
+
|
|
255
|
+
``from_transport(..., rewrite_link=callback)`` calls ``callback`` with a
|
|
256
|
+
:class:`~easyvista_python_client.content.Link` for each link and each image it
|
|
257
|
+
meets outside code, an image before the link around it. A ``Link`` carries the
|
|
258
|
+
``href`` (an image's ``src``), the ``text`` (an image's ``alt``), the
|
|
259
|
+
``title``, whether it is an ``image``, an embedded image's ``document_id``, and
|
|
260
|
+
for an image inside a link that link's ``enclosing_href``. What the callback
|
|
261
|
+
answers is written:
|
|
262
|
+
|
|
263
|
+
* ``None``: what the reader writes without a callback;
|
|
264
|
+
* a ``str``: that text, literally -- escaped as any text the memo displays, so
|
|
265
|
+
it cannot become markup;
|
|
266
|
+
* a ``Link``: a link's ``href`` and ``title`` around the link's content as
|
|
267
|
+
read, or an image's ``href`` as its ``src``, ``text`` as its ``alt`` and
|
|
268
|
+
``title``;
|
|
269
|
+
* a ``Link`` with an empty ``href``: a link is dropped and its content kept, an
|
|
270
|
+
image is written as its ``text``.
|
|
271
|
+
|
|
272
|
+
.. code-block:: python
|
|
273
|
+
|
|
274
|
+
from easyvista_python_client.content import EasyvistaContentConverter, Link
|
|
275
|
+
|
|
276
|
+
def name_attachments(link: Link) -> Link | str | None:
|
|
277
|
+
if link.document_id is not None:
|
|
278
|
+
return f"[attachment {link.document_id}]"
|
|
279
|
+
return None
|
|
280
|
+
|
|
281
|
+
EasyvistaContentConverter.from_transport(memo, rewrite_link=name_attachments)
|
|
282
|
+
|
|
283
|
+
The callback is held for the duration of one read, per thread and per task,
|
|
284
|
+
so concurrent reads each use their own, and a read inside a callback has its
|
|
285
|
+
own too. What the callback raises reaches the caller unchanged -- a
|
|
286
|
+
``ValueError`` included, which the reader would otherwise take for one of
|
|
287
|
+
markdownify's and answer by reading the body as its text. An answer of any
|
|
288
|
+
other type raises ``TypeError``. It is not called for a value passed through
|
|
289
|
+
as Markdown (``plain_text_is_markdown=True``), nor for a body read as its text.
|
|
290
|
+
|
|
232
291
|
It is not a sanitiser
|
|
233
292
|
---------------------
|
|
234
293
|
|
|
@@ -13,6 +13,10 @@ stack left to report it otherwise (see ``docs/content.rst``).
|
|
|
13
13
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
|
-
from easyvista_python_client.content.conversion import
|
|
16
|
+
from easyvista_python_client.content.conversion import (
|
|
17
|
+
EasyvistaContentConverter,
|
|
18
|
+
Link,
|
|
19
|
+
RewriteLink,
|
|
20
|
+
)
|
|
17
21
|
|
|
18
|
-
__all__ = ["EasyvistaContentConverter"]
|
|
22
|
+
__all__ = ["EasyvistaContentConverter", "Link", "RewriteLink"]
|
|
@@ -59,9 +59,11 @@ import re
|
|
|
59
59
|
import string
|
|
60
60
|
import unicodedata
|
|
61
61
|
from collections.abc import Callable, Iterator, Mapping, MutableMapping, Sequence
|
|
62
|
+
from contextvars import ContextVar
|
|
63
|
+
from dataclasses import dataclass
|
|
62
64
|
from functools import cached_property
|
|
63
65
|
from html import escape, unescape
|
|
64
|
-
from typing import Any, cast
|
|
66
|
+
from typing import Any, ClassVar, cast
|
|
65
67
|
|
|
66
68
|
from easyvista_python_client.exceptions import EasyvistaContentError
|
|
67
69
|
|
|
@@ -396,6 +398,97 @@ def _title(title: str) -> str:
|
|
|
396
398
|
return ' "' + re.sub(r'[\\"]', r"\\\g<0>", title) + '"' if title else ""
|
|
397
399
|
|
|
398
400
|
|
|
401
|
+
#: How a memo embeds an image: EasyVista's editor stores a pasted image as an
|
|
402
|
+
#: attachment of the request and writes ``<img src="@@EMBEDDED_IMAGE_PATH@@...">``
|
|
403
|
+
#: with that attachment's ``DOCUMENT_ID``. Measured 2026-10-07 on one instance
|
|
404
|
+
#: (tier 4): an image written that way through the API displays too, for an
|
|
405
|
+
#: attachment pasted in the editor and for one uploaded with ``add_document``.
|
|
406
|
+
EMBEDDED_IMAGE_PREFIX = "@@EMBEDDED_IMAGE_PATH@@"
|
|
407
|
+
|
|
408
|
+
#: A ``DOCUMENT_ID``, as an embedded image's ``src`` carries one. Measured: 40 hex
|
|
409
|
+
#: digits for an image pasted in the editor, an account number, ``_`` and 64 hex
|
|
410
|
+
#: digits for a file uploaded through the API. The class is wider than both.
|
|
411
|
+
_DOCUMENT_ID = re.compile(r"[A-Za-z0-9_.-]{1,128}")
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@dataclass(frozen=True, slots=True)
|
|
415
|
+
class Link:
|
|
416
|
+
"""A link or an image the reader meets, as a ``rewrite_link`` callback sees it.
|
|
417
|
+
|
|
418
|
+
Attributes
|
|
419
|
+
----------
|
|
420
|
+
href : str
|
|
421
|
+
An ``<a>``'s ``href`` or an ``<img>``'s ``src``, character references
|
|
422
|
+
decoded.
|
|
423
|
+
text : str
|
|
424
|
+
An ``<a>``'s displayed text or an ``<img>``'s ``alt``, whitespace
|
|
425
|
+
collapsed.
|
|
426
|
+
title : str
|
|
427
|
+
The ``title``, or ``""``.
|
|
428
|
+
image : bool
|
|
429
|
+
``True`` for an ``<img>``.
|
|
430
|
+
document_id : str or None
|
|
431
|
+
For an ``<img>`` embedding an attachment of the request
|
|
432
|
+
(:data:`EMBEDDED_IMAGE_PREFIX` and a ``DOCUMENT_ID``), that
|
|
433
|
+
``DOCUMENT_ID``; ``None`` otherwise, and always for an ``<a>``.
|
|
434
|
+
enclosing_href : str or None
|
|
435
|
+
For an ``<img>`` inside a link, that link's ``href``; ``None``
|
|
436
|
+
otherwise. The image is read before the link around it.
|
|
437
|
+
"""
|
|
438
|
+
|
|
439
|
+
href: str
|
|
440
|
+
text: str = ""
|
|
441
|
+
title: str = ""
|
|
442
|
+
image: bool = False
|
|
443
|
+
document_id: str | None = None
|
|
444
|
+
enclosing_href: str | None = None
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
#: A ``rewrite_link`` callback: called with each link and image a read meets,
|
|
448
|
+
#: outside code. ``None`` keeps what the reader writes without one. A ``str`` is
|
|
449
|
+
#: written instead, as literal text. A :class:`Link` is written in the reader's
|
|
450
|
+
#: own spelling: a link's ``href`` and ``title``, around the link's content as
|
|
451
|
+
#: read; an image's ``href`` as its ``src``, ``text`` as its ``alt`` and
|
|
452
|
+
#: ``title``. An empty ``href`` drops a link and keeps its content, and writes an
|
|
453
|
+
#: image as its ``text``.
|
|
454
|
+
RewriteLink = Callable[[Link], "Link | str | None"]
|
|
455
|
+
|
|
456
|
+
_REWRITE: ContextVar[RewriteLink | None] = ContextVar("rewrite_link", default=None)
|
|
457
|
+
"""The callback of the read in progress. A context variable rather than state
|
|
458
|
+
on the shared converter: each thread and each task reads with its own."""
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
class _CallbackRaised(Exception):
|
|
462
|
+
"""What a ``rewrite_link`` callback raised, carried past the reader's fallbacks.
|
|
463
|
+
|
|
464
|
+
The reader answers a ``ValueError`` by reading the body as its text; a
|
|
465
|
+
callback's own ``ValueError`` must not pass for markdownify's and quietly
|
|
466
|
+
cost the body its formatting.
|
|
467
|
+
"""
|
|
468
|
+
|
|
469
|
+
def __init__(self, error: Exception) -> None:
|
|
470
|
+
super().__init__(error)
|
|
471
|
+
self.error = error
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def _rewritten(link: Link) -> Link | str | None:
|
|
475
|
+
"""Ask the read's callback about ``link``; ``None`` when there is none."""
|
|
476
|
+
|
|
477
|
+
rewrite = _REWRITE.get()
|
|
478
|
+
if rewrite is None:
|
|
479
|
+
return None
|
|
480
|
+
try:
|
|
481
|
+
answer: object = rewrite(link) # typed as what it is, not what it should be
|
|
482
|
+
except Exception as exc:
|
|
483
|
+
raise _CallbackRaised(exc) from exc
|
|
484
|
+
if answer is None or isinstance(answer, (Link, str)):
|
|
485
|
+
return answer
|
|
486
|
+
error = TypeError(
|
|
487
|
+
f"rewrite_link returned {type(answer).__name__}; expected Link, str or None"
|
|
488
|
+
)
|
|
489
|
+
raise _CallbackRaised(error)
|
|
490
|
+
|
|
491
|
+
|
|
399
492
|
class _Converter(MarkdownConverter):
|
|
400
493
|
"""``markdownify``, with what CommonMark and the reader's glue need on top.
|
|
401
494
|
|
|
@@ -553,15 +646,27 @@ class _Converter(MarkdownConverter):
|
|
|
553
646
|
body, _, tail = rest.rpartition("```")
|
|
554
647
|
return f"{head}{fence}{body}{fence}{tail}"
|
|
555
648
|
|
|
649
|
+
def _literal(self, text: str, parent_tags: set[str]) -> str:
|
|
650
|
+
"""``text`` escaped as the reader escapes a text node: displayed as it is."""
|
|
651
|
+
|
|
652
|
+
return self.escape(" ".join(text.split()), parent_tags)
|
|
653
|
+
|
|
556
654
|
def convert_a(self, el: Tag, text: str, parent_tags: set[str]) -> str:
|
|
557
655
|
"""A link; ``<url>`` when its text is its URL and reads back unchanged."""
|
|
558
656
|
|
|
657
|
+
if "_noformat" in parent_tags:
|
|
658
|
+
return text
|
|
559
659
|
href = str(el.get("href") or "")
|
|
660
|
+
title = str(el.get("title") or "")
|
|
661
|
+
answer = _rewritten(Link(href, " ".join(el.get_text().split()), title))
|
|
662
|
+
if isinstance(answer, str):
|
|
663
|
+
return self._literal(answer, parent_tags)
|
|
664
|
+
if answer is not None:
|
|
665
|
+
href, title = answer.href, answer.title
|
|
560
666
|
edges = _EDGES.fullmatch(text)
|
|
561
|
-
if
|
|
667
|
+
if not href or edges is None or not edges[2]:
|
|
562
668
|
return text
|
|
563
669
|
before, inner, after = edges.groups()
|
|
564
|
-
title = str(el.get("title") or "")
|
|
565
670
|
if not title and el.get_text() == href and _AUTOLINK.fullmatch(href):
|
|
566
671
|
return f"{before}<{href}>{after}"
|
|
567
672
|
return f"{before}[{inner}]({_destination(href)}{_title(title)}){after}"
|
|
@@ -569,12 +674,38 @@ class _Converter(MarkdownConverter):
|
|
|
569
674
|
def convert_img(self, el: Tag, text: str, parent_tags: set[str]) -> str:
|
|
570
675
|
"""An image, wherever it is: a cell or a heading holds one too."""
|
|
571
676
|
|
|
677
|
+
src = str(el.get("src") or "")
|
|
572
678
|
alt = " ".join(str(el.get("alt") or "").split())
|
|
679
|
+
title = str(el.get("title") or "")
|
|
680
|
+
if "_noformat" not in parent_tags:
|
|
681
|
+
embedded = EasyvistaContentConverter.document_id_of(src)
|
|
682
|
+
around = el.find_parent("a")
|
|
683
|
+
answer = _rewritten(
|
|
684
|
+
Link(
|
|
685
|
+
src,
|
|
686
|
+
alt,
|
|
687
|
+
title,
|
|
688
|
+
image=True,
|
|
689
|
+
document_id=embedded,
|
|
690
|
+
enclosing_href=(
|
|
691
|
+
None if around is None else str(around.get("href") or "")
|
|
692
|
+
),
|
|
693
|
+
)
|
|
694
|
+
)
|
|
695
|
+
if isinstance(answer, str):
|
|
696
|
+
return self._literal(answer, parent_tags)
|
|
697
|
+
if answer is not None and not answer.href:
|
|
698
|
+
return self._literal(answer.text, parent_tags)
|
|
699
|
+
if answer is not None:
|
|
700
|
+
src, alt, title = (
|
|
701
|
+
answer.href,
|
|
702
|
+
" ".join(answer.text.split()),
|
|
703
|
+
answer.title,
|
|
704
|
+
)
|
|
573
705
|
alt = str(self._inherited("escape")(alt, parent_tags))
|
|
574
706
|
if alt.startswith("^") and "_noformat" not in parent_tags:
|
|
575
707
|
alt = "\\" + alt # cmark-gfm reads " or ''))})"
|
|
708
|
+
return f"}{_title(title)})"
|
|
578
709
|
|
|
579
710
|
|
|
580
711
|
class _Node(RenderTreeNode):
|
|
@@ -748,12 +879,26 @@ def html_to_markdown(html: str) -> str:
|
|
|
748
879
|
return str(_FORMATTER.render(_CONVERTER.convert_soup(soup))).strip()
|
|
749
880
|
|
|
750
881
|
|
|
882
|
+
#: A link as cmark-gfm writes one: an ``href``, an optional ``title``, nothing else.
|
|
883
|
+
_RENDERED_LINK = re.compile(r'<a href="[^"]*"(?: title="[^"]*")?>')
|
|
884
|
+
|
|
885
|
+
#: What EasyVista's own editor writes on a link: without it the memo view opens the
|
|
886
|
+
#: link in place, inside EasyVista's window, rather than in a new one.
|
|
887
|
+
_NEW_WINDOW = ' target="_blank" rel="noopener noreferrer"'
|
|
888
|
+
|
|
889
|
+
|
|
751
890
|
def markdown_to_html(markdown: str) -> str:
|
|
752
|
-
"""Render Markdown as HTML: CommonMark with GFM tables, through cmark-gfm.
|
|
891
|
+
"""Render Markdown as HTML: CommonMark with GFM tables, through cmark-gfm.
|
|
892
|
+
|
|
893
|
+
Every link opens in a new window, the way a link written in EasyVista's
|
|
894
|
+
editor does: ``target="_blank" rel="noopener noreferrer"`` is added to each
|
|
895
|
+
link cmark-gfm writes. Reading ignores both attributes.
|
|
896
|
+
"""
|
|
753
897
|
|
|
754
898
|
html: str = cmarkgfm.markdown_to_html_with_extensions(
|
|
755
899
|
markdown, options=_RENDER_OPTIONS, extensions=["table"]
|
|
756
900
|
)
|
|
901
|
+
html = _RENDERED_LINK.sub(lambda link: link.group(0)[:-1] + _NEW_WINDOW + ">", html)
|
|
757
902
|
return html.strip()
|
|
758
903
|
|
|
759
904
|
|
|
@@ -770,11 +915,41 @@ def _text_of(html: str) -> str:
|
|
|
770
915
|
return "\n".join(line for line in lines if line)
|
|
771
916
|
|
|
772
917
|
|
|
918
|
+
def _converted(content: str) -> str:
|
|
919
|
+
"""Read memo HTML, falling back to its text where the conversion cannot."""
|
|
920
|
+
|
|
921
|
+
try:
|
|
922
|
+
try:
|
|
923
|
+
return html_to_markdown(content)
|
|
924
|
+
except (RecursionError, ValueError): # ValueError: markdownify's
|
|
925
|
+
# int() of a colspan or start such as "²" or 5,000 digits
|
|
926
|
+
return html_to_markdown(_plain_text_html(_text_of(content)))
|
|
927
|
+
except ParserRejectedMarkup:
|
|
928
|
+
# html.parser gives up on a few malformed declarations; the
|
|
929
|
+
# body's words are still worth more than an exception.
|
|
930
|
+
text = unescape(_ANY_TAG.sub(" ", content))
|
|
931
|
+
return html_to_markdown(_plain_text_html(" ".join(text.split())))
|
|
932
|
+
except _CallbackRaised:
|
|
933
|
+
raise
|
|
934
|
+
except Exception as exc:
|
|
935
|
+
raise EasyvistaContentError(
|
|
936
|
+
"Could not convert EasyVista memo HTML to Markdown "
|
|
937
|
+
f"({type(exc).__name__}: {exc})."
|
|
938
|
+
) from exc
|
|
939
|
+
|
|
940
|
+
|
|
773
941
|
class EasyvistaContentConverter:
|
|
774
942
|
"""Convert content between EasyVista memo HTML and canonical Markdown."""
|
|
775
943
|
|
|
944
|
+
EMBEDDED_IMAGE_PREFIX: ClassVar[str] = EMBEDDED_IMAGE_PREFIX
|
|
945
|
+
|
|
776
946
|
@staticmethod
|
|
777
|
-
def from_transport(
|
|
947
|
+
def from_transport(
|
|
948
|
+
value: object,
|
|
949
|
+
*,
|
|
950
|
+
plain_text_is_markdown: bool = False,
|
|
951
|
+
rewrite_link: RewriteLink | None = None,
|
|
952
|
+
) -> str:
|
|
778
953
|
"""Convert one EasyVista memo value into Markdown.
|
|
779
954
|
|
|
780
955
|
Parameters
|
|
@@ -792,6 +967,12 @@ class EasyvistaContentConverter:
|
|
|
792
967
|
``<kbd>`` is still Markdown, but Markdown that opens with an
|
|
793
968
|
autolink or other angle-bracketed text and carries inline HTML
|
|
794
969
|
further on is read as HTML, and loses that autolink.
|
|
970
|
+
rewrite_link : callable, optional
|
|
971
|
+
Called with a :class:`Link` for each link and image the read
|
|
972
|
+
meets outside code, an image before the link around it; its
|
|
973
|
+
answer decides what is written (:data:`RewriteLink`). Not called
|
|
974
|
+
for a value passed through as Markdown, nor for a body read as
|
|
975
|
+
its text. Without one, the read is what it always was.
|
|
795
976
|
|
|
796
977
|
Returns
|
|
797
978
|
-------
|
|
@@ -811,6 +992,10 @@ class EasyvistaContentConverter:
|
|
|
811
992
|
limit, where no stack is left even to report the failure as
|
|
812
993
|
``EasyvistaContentError`` (``docs/content.rst`` gives the
|
|
813
994
|
measured depths).
|
|
995
|
+
Exception
|
|
996
|
+
Whatever ``rewrite_link`` raised, unchanged; ``TypeError`` when it
|
|
997
|
+
answered something other than a :class:`Link`, a ``str`` or
|
|
998
|
+
``None``.
|
|
814
999
|
"""
|
|
815
1000
|
|
|
816
1001
|
content = str(value or "").strip()
|
|
@@ -826,22 +1011,65 @@ class EasyvistaContentConverter:
|
|
|
826
1011
|
# 3.11.14/3.12.12/3.13.6 rescans to the end for each (quadratic).
|
|
827
1012
|
head, end, tail = content.rpartition(">")
|
|
828
1013
|
content = head + end + tail.replace("<", "<")
|
|
1014
|
+
token = _REWRITE.set(rewrite_link)
|
|
829
1015
|
try:
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1016
|
+
return _converted(content)
|
|
1017
|
+
except _CallbackRaised as raised:
|
|
1018
|
+
callback_error = raised.error
|
|
1019
|
+
finally:
|
|
1020
|
+
_REWRITE.reset(token)
|
|
1021
|
+
raise callback_error # outside the handler: the callback's, as it raised it
|
|
1022
|
+
|
|
1023
|
+
@staticmethod
|
|
1024
|
+
def document_id_of(src: str) -> str | None:
|
|
1025
|
+
"""Return the ``DOCUMENT_ID`` an embedded image's ``src`` names.
|
|
1026
|
+
|
|
1027
|
+
``None`` unless ``src`` is exactly :data:`EMBEDDED_IMAGE_PREFIX`
|
|
1028
|
+
followed by a ``DOCUMENT_ID`` -- how EasyVista's editor refers to an
|
|
1029
|
+
image pasted into a memo, which it keeps as an attachment of the
|
|
1030
|
+
request.
|
|
1031
|
+
"""
|
|
1032
|
+
|
|
1033
|
+
if not src.startswith(EMBEDDED_IMAGE_PREFIX):
|
|
1034
|
+
return None
|
|
1035
|
+
document_id = src[len(EMBEDDED_IMAGE_PREFIX) :]
|
|
1036
|
+
return document_id if _DOCUMENT_ID.fullmatch(document_id) else None
|
|
1037
|
+
|
|
1038
|
+
@staticmethod
|
|
1039
|
+
def document_image(document_id: str, *, alt: str = "") -> str:
|
|
1040
|
+
"""Return the Markdown of an image embedding one of the request's attachments.
|
|
1041
|
+
|
|
1042
|
+
:meth:`to_transport` renders it as EasyVista's editor writes a pasted
|
|
1043
|
+
image, ``<img src="@@EMBEDDED_IMAGE_PATH@@<document_id>" alt="..." />``,
|
|
1044
|
+
and :meth:`from_transport` reads that back as this same Markdown: it
|
|
1045
|
+
is spelled by the reader itself. The memo displays the image once the
|
|
1046
|
+
attachment is on the same request.
|
|
1047
|
+
|
|
1048
|
+
Parameters
|
|
1049
|
+
----------
|
|
1050
|
+
document_id : str
|
|
1051
|
+
The attachment's ``DOCUMENT_ID``, as ``list_documents`` gives it.
|
|
1052
|
+
alt : str, optional
|
|
1053
|
+
The image's alternative text.
|
|
1054
|
+
|
|
1055
|
+
Raises
|
|
1056
|
+
------
|
|
1057
|
+
ValueError
|
|
1058
|
+
``document_id`` is not one: empty, or holding a character no
|
|
1059
|
+
``DOCUMENT_ID`` has.
|
|
1060
|
+
"""
|
|
1061
|
+
|
|
1062
|
+
if not _DOCUMENT_ID.fullmatch(document_id):
|
|
1063
|
+
raise ValueError(f"not an EasyVista DOCUMENT_ID: {document_id!r}")
|
|
1064
|
+
native = (
|
|
1065
|
+
f'<p><img src="{EMBEDDED_IMAGE_PREFIX}{document_id}" '
|
|
1066
|
+
f'alt="{escape(" ".join(alt.split()))}" /></p>'
|
|
1067
|
+
)
|
|
1068
|
+
token = _REWRITE.set(None) # a callback in force for an enclosing read
|
|
1069
|
+
try:
|
|
1070
|
+
return html_to_markdown(native)
|
|
1071
|
+
finally:
|
|
1072
|
+
_REWRITE.reset(token)
|
|
845
1073
|
|
|
846
1074
|
@staticmethod
|
|
847
1075
|
def to_transport(value: object) -> str:
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and a profile authorized for the assets resource."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and valid EasyVista credentials."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
`easyvista_python_client` ships both clients over one surface:
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/skills/easyvista-directory/SKILL.md
RENAMED
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and a profile authorized for the departments and employees resources (writes are additionally profile-gated)."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and a profile authorized for the documents sub-resource."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, and network access to an EasyVista Service Manager REST API. Every call here is a GET; nothing is created, updated or deleted."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, and network access to an EasyVista Service Manager REST API."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, and network access to an EasyVista Service Manager REST API."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and a profile authorized for the actions sub-resource."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: "Requires Python 3.11+, easyvista-python-client, network access to an EasyVista Service Manager REST API, and a profile authorized for the requests resource."
|
|
6
6
|
metadata:
|
|
7
7
|
package: easyvista-python-client
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
> **Sync and async.** Examples use `EasyvistaClient`. For `AsyncEasyvistaClient`,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/docs/vendor-api-reference.md
RENAMED
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_fields.py
RENAMED
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/_html.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/config.py
RENAMED
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/context.py
RENAMED
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/directory.py
RENAMED
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/discovery.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/filters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/reporting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{easyvista_python_client-0.4.1 → easyvista_python_client-0.4.3}/easyvista_python_client/workflow.py
RENAMED
|
File without changes
|
|
File without changes
|