Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
373cc17
refactor: promote the EasyVista timestamp parser into a shared leaf
baraline Aug 17, 2026
ff0c793
feat: add interval and wildcard search filter builders
baraline Aug 17, 2026
4122dad
fix(review): validate interval bound calendar validity, not just shape
baraline Aug 17, 2026
80996be
fix: RECENT_TICKETS_SORT was silently ignored, so recent_tickets was …
baraline Aug 17, 2026
c9e7d55
fix(review): stop overclaiming RECENT_TICKETS_SORT's live verification
baraline Aug 17, 2026
c867856
feat!: parse read-path timestamps into aware datetimes
baraline Aug 17, 2026
82c3964
fix(review): render datetimes in the two shared by-alias extractors
baraline Aug 17, 2026
8a752ee
feat: declare the action timestamp, author and workflow fields
baraline Aug 17, 2026
b49c92e
fix(review): correct the action docstring's self-contradictory list c…
baraline Aug 17, 2026
7ce7730
feat: accept a fields= projection on list_actions
baraline Aug 17, 2026
23fe3ef
docs: surface the fields=* footgun on the public list_actions docstring
baraline Aug 17, 2026
f4ba30c
feat: add update_action and delete_document
baraline Aug 17, 2026
9552dbb
feat: widen RequestUpdate with impact_id, owner_id, external_reference
baraline Aug 17, 2026
3f1514b
test: guard the interval, sort and wildcard grammars live
baraline Aug 17, 2026
47bff08
fix(review): close task-9's interval, sort and control gaps
baraline Aug 17, 2026
83d110d
docs: correct the tilde-operator claim and document the interval grammar
baraline Aug 17, 2026
caea6fa
docs(fix): close five stale-claim gaps the file list missed in round 1
baraline Aug 17, 2026
d2cc0ac
test(skills): validate ActionUpdate snippets and guard the write-mode…
baraline Aug 17, 2026
83c2be8
fix: refuse an interval bound whose time carries no UTC offset
baraline Aug 18, 2026
8ac38fa
feat: stream an attachment's bytes instead of buffering the whole file
baraline Aug 18, 2026
1c15a64
fix: correct five false streaming claims and pin the three untested ones
baraline Aug 18, 2026
cf9ab81
docs: make six shared comments true on both generated surfaces
baraline Aug 18, 2026
e9121df
release: 0.2.0
baraline Aug 18, 2026
8d71cab
fix(filters): normalise interval bounds, refuse `_`/`[`, raise on jun…
baraline Aug 18, 2026
659a6ea
fix(client): cap list_actions explicitly and guard a non-positive chu…
baraline Aug 18, 2026
fe0e304
test(live): pin the rendering matrix, the ascending sort and RequestU…
baraline Aug 18, 2026
5de6fda
docs: resolve the changelog's self-contradictions and six false relea…
baraline Aug 18, 2026
eafe60e
fix: an explicit None is an absence, not a malformed timestamp
baraline Aug 18, 2026
49ef8d8
docs(sweep): correct the change-window sort ruling to descending
baraline Aug 18, 2026
8660f45
docs(search): document the `~` metacharacters wherever the builders a…
baraline Aug 18, 2026
d05aae2
fix(filters): diagnose a sub-minute offset, and record the truncation…
baraline Aug 18, 2026
0bee73b
docs(filters): document the DESC watermark's page-1 finality trap
baraline Aug 18, 2026
4d6dd79
fix(test): treat a silent write-drop as a refusal in the ticket-ident…
baraline Aug 18, 2026
53c31dd
test(integration): close a P2 leak and two shared-instance races in c…
baraline Aug 18, 2026
ec487af
docs(test): correct the advertised write footprint of the live suite
baraline Aug 18, 2026
a1e297d
fix(requests)!: send the documented create body, set status by GUID
baraline Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ jobs:
# easyvista_python_client.__version__ -- and the git tag is a third. PyPI
# takes whatever pyproject says, so a tag that disagrees publishes a
# release nobody can find by version, and a __version__ that disagrees
# misreports at runtime. Both are unfixable after upload. Tags in this
# repo are v-prefixed (see the CHANGELOG compare links), so the leading v
# is stripped before comparing.
# misreports at runtime. Both are unfixable after upload. The repo's only
# existing tag, 0.1.0, is UNPREFIXED; v-prefixing starts at v0.2.0. The
# leading v is therefore stripped before comparing, so both forms
# validate.
- name: Validate release tag matches package version
if: github.event_name == 'release'
shell: bash
Expand Down
364 changes: 313 additions & 51 deletions CHANGELOG.md

Large diffs are not rendered by default.

19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

[![CI](https://github.com/baraline/easyvista_python_client/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/baraline/easyvista_python_client/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/baraline/easyvista_python_client/branch/main/graph/badge.svg)](https://codecov.io/gh/baraline/easyvista_python_client)
[![License](https://img.shields.io/github/license/baraline/easyvista_python_client)](LICENSE)
[![License](https://img.shields.io/github/license/baraline/easyvista_python_client)](https://github.com/baraline/easyvista_python_client/blob/main/LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://github.com/baraline/easyvista_python_client)
[![Docs](https://readthedocs.org/projects/easyvista-python-client/badge/?version=latest)](https://easyvista-python-client.readthedocs.io/en/latest/)


Typed Python client for the EasyVista Service Manager REST API. Sync + async,
Pydantic models, Bearer or Basic auth.

While the package is preparing for 1.0, alot of potential breaking change might happen between versions. A deprecation policy will be put in place once 1.0 is out and the package have been stabilized.
While the package is preparing for 1.0, breaking changes may land between
minor versions; a deprecation policy will follow the 1.0 release.

## Documentation

Expand Down Expand Up @@ -78,6 +79,7 @@ from easyvista_python_client import (
EasyvistaClient,
EasyvistaConfig,
PostAsset,
ev_contains_filter,
ev_equals_filter,
)

Expand All @@ -86,6 +88,13 @@ with EasyvistaClient(EasyvistaConfig.from_env()) as client:
tag_filter = ev_equals_filter("ASSET_TAG", "LAPTOP-001")
found = client.search_assets(search=tag_filter, max_rows=50)

# `~` needs an explicit wildcard to mean "contains" -- a bare value is exact
# match, identical to `:`. ev_contains_filter adds the wildcard for you, and
# raises ValueError if the value itself carries one of * % _ [ (all four are
# metacharacters to `~`, with no escape). For an exact match on a tag like
# "LAPTOP_01", use ev_equals_filter: `:` does not expand a wildcard.
partial = client.search_assets(search=ev_contains_filter("ASSET_TAG", "LAPTOP"))

# attach a file to a ticket (uploaded as base64 inside the JSON body)
pdf = Path("report.pdf")
client.add_document("I240101_0001", filename=pdf.name, content=pdf.read_bytes())
Expand All @@ -112,19 +121,19 @@ then call `EasyvistaConfig.from_env()`.
`skills/` holds Agent Skills for driving this client from an AI agent — one per
domain (client setup, search syntax, tickets, actions, documents, assets,
directory, reporting and context). Each is a directory with a `SKILL.md`
following the Agent Skills specification; see [skills/README.md](skills/README.md)
following the Agent Skills specification; see [skills/README.md](https://github.com/baraline/easyvista_python_client/blob/main/skills/README.md)
for the index.

They are source-tree material: present in the git repository and the source
distribution, absent from the installed wheel.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and quality checks.
See [CONTRIBUTING.md](https://github.com/baraline/easyvista_python_client/blob/main/CONTRIBUTING.md) for development setup and quality checks.

## License

MIT — see [LICENSE](LICENSE).
MIT — see [LICENSE](https://github.com/baraline/easyvista_python_client/blob/main/LICENSE).

## Sponsoring

Expand Down
24 changes: 22 additions & 2 deletions docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Models

.. autoclass:: easyvista_python_client.models.action.PostAction

.. autoclass:: easyvista_python_client.models.action.ActionUpdate

.. autoclass:: easyvista_python_client.models.asset.Asset

.. autoclass:: easyvista_python_client.models.asset.PostAsset
Expand Down Expand Up @@ -61,17 +63,35 @@ Filters
-------

Build ``search`` expressions with these rather than f-strings: EasyVista ignores a filter it cannot
parse and returns every record, and ``,`` combines conditions — so an unescaped value fails silently
or widens the result rather than raising.
parse and returns every record, ``,`` combines conditions so an unescaped value can silently widen
the result, and there is no comparison operator — a range must be expressed as an interval.

.. autofunction:: easyvista_python_client.filters.ev_equals_filter

.. autofunction:: easyvista_python_client.filters.ev_in_filter

.. autofunction:: easyvista_python_client.filters.ev_contains_filter

.. autofunction:: easyvista_python_client.filters.ev_starts_with_filter

.. autofunction:: easyvista_python_client.filters.ev_since_filter

.. autofunction:: easyvista_python_client.filters.ev_between_filter

.. autofunction:: easyvista_python_client.filters.escape_ev_value

.. autofunction:: easyvista_python_client.filters.is_safe_ev_value

Timestamps
----------

EasyVista's timestamp format, parsed and rendered in one place — see
:ref:`timestamps` for how the read models use these.

.. autofunction:: easyvista_python_client.timestamps.parse_ev_datetime

.. autofunction:: easyvista_python_client.timestamps.format_ev_datetime

References
----------

Expand Down
19 changes: 15 additions & 4 deletions docs/publishing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,26 @@ the workflow's OIDC identity.
Cutting a release
-----------------

#. Bump the version in **both** places -- ``pyproject.toml`` (``project.version``) and
``easyvista_python_client.__version__``. The release workflow refuses to build if they
disagree, or if they disagree with the tag.
#. Bump the version in **all four** places, or CI goes red on an otherwise correct
bump:

* ``pyproject.toml`` (``project.version``);
* ``easyvista_python_client.__version__``;
* the hardcoded literal in ``easyvista_python_client/testing/test_public_api.py``
(asserted by the unit suite);
* every ``skills/*/SKILL.md`` ``metadata.version`` (asserted by
``scripts/tests/test_skills_contract.py``).

The release workflow additionally refuses to build if the first two disagree with
each other or with the tag.
#. Move the ``CHANGELOG.md`` ``[Unreleased]`` entries under the new version and update the
compare links at the bottom of the file.
#. Merge to ``main`` and let CI go green.
#. Publish a GitHub release whose tag is the version, ``v``-prefixed --
``v0.2.0`` for version ``0.2.0``. (The workflow strips a leading ``v`` before comparing,
so an unprefixed tag also passes; the repository's existing tags are prefixed.)
so an unprefixed tag also passes. The only tag that exists today, ``0.1.0``, is
**unprefixed** -- ``v``-prefixing starts at ``v0.2.0``, which is why the
``CHANGELOG.md`` link for ``0.1.0`` points at the bare tag.)

The workflow then runs the test matrix (3.10--3.14) and the quality gates -- Ruff, mypy,
the generated-``_sync``-tree check, the hand-written-twin lint and a warnings-as-errors
Expand Down
Loading
Loading