Tags give the ability to mark specific points in history as being important
-
1.0.0rc6
Release: Release 1.0.0rc69753ce99 · ·# 1.0.0rc6 - Release Candidate 6 Sixth release candidate of the `1.0.0` line. It adds document search-flag querying, archive/lock status properties on document instances, and three new system methods (`get_icons`, `jobs`, `check_connections`), and fixes the `build` CI job. The public API of `1.0.0rc5` is unchanged apart from the additive capabilities below. ## Added - **Query documents by `OBJECT_SEARCHFLAGS` state (#14491).** The `ObjectSearchFlags` enum existed but could not be used: the only condition entry point emitted `system="0"`, so the server ignored the bitmask. Document models now expose boolean search-flag properties on their `system` namespace (`Model.system.in_register`, `.signed_current`, `.without_pages`, `.archivable`, ...) usable directly in `where()`, e.g. `ecm.dms.select(Document).where(Document.system.in_register == True).execute()`. Multiple flag conditions collapse into one correct `<FieldCondition internal_name="OBJECT_SEARCHFLAGS" system="1">`. Paired flags (`archivable`, `in_register`) also accept `== False`. - **Archive-status and lock properties on loaded document instances (#14491).** `OBJECT_FLAGS` (1102) and `OBJECT_LOCKUSER` (1116) are now part of the document default system fields, so `ECMDocumentModel` instances expose decoded boolean properties without any extra query flag: `obj.system.archived`, `.archivable`, `.not_archivable`, `.page_error`, `.without_pages`, `.reference`, `.external_archived` (from the `OBJECT_FLAGS` status code) and `.locked` (from `OBJECT_LOCKUSER`), plus the raw `.flags`. The query-only search-flag properties (`multi_location`, `has_variants`, `signed_current`, `signed_former`) remain usable only inside `where(...)`. - **`ecm.system.get_icons()` fetches object/type icons by ID.** Wraps the `cnv.GetIcons` server job and returns the GIF images for the given icon IDs as a `dict[int, bytes]` (icon ID to raw GIF bytes). Icon IDs come from the object definition (`icon_id` per object type) or from `document.system.file_properties.iconid`. Multiple IDs are fetched in a single round-trip; unknown IDs are silently omitted; passing no IDs returns `{}` without contacting the server. Sync and async. - **`ecm.check_connections()` probes every configured pool server individually (#15467).** This root-level method opens a throwaway connection to each server in the pool configuration (TCP/TLS, login, `krn.GetServerInfoEx`), reports reachability, authentication state and server info per server, then closes it again. Probe connections never enter the pool and never affect pool statistics; one unreachable server does not abort the others, failures are recorded in the result's `error` field instead of being raised. Returns `list[ECMServerConnectionCheck]` (sync and async). - **`ecm.system.jobs()` lists all server jobs grouped by namespace.** Combines `krn.EnumNameSpaces` and one `krn.EnumJobs` call per engine into a single `dict[str, list[str]]`, keyed by namespace short label (e.g. `"krn"`) with the namespace's jobs as values, each including the namespace prefix. Dict keys and job lists are sorted; the async variant runs the per-engine calls concurrently (sync and async). ## Fixed - **The `build` CI job failed at `uv build` (#15468).** A newer `uv` refuses to build when its cache lives inside the build source tree, and the shared GitLab cache restored `.cache/uv` back into the project directory. The `build` job now points `UV_CACHE_DIR` outside the source and skips the shared cache, so the package builds again. The test job keeps its in-project cache for reuse between pipelines. **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0rc5...1.0.0rc6 -
1.0.0rc5
Release: Release 1.0.0rc5afbac8bd · ·# 1.0.0rc5 - Release Candidate 5 Fifth release candidate of the `1.0.0` line. It fixes a model-generator defect that silently dropped data-bearing fields displayed with the GROUP control. The public API of `1.0.0rc4` is unchanged. ## Fixed - **`ecm-generate-models` dropped data-bearing GROUP-control fields.** enaio uses the GROUP control (`dt='G'`) both for visual containers and for real index fields that have their own data type and database column. The generator skipped every GROUP control, so such fields (e.g. `PostDoc`'s `hash`, `group`, `user`) were silently missing from the generated model class. GROUP-control fields that carry a data type are now emitted as `ECMField` declarations; purely visual GROUP boxes (no data type, or static) stay excluded. Present since `1.0.0a1`; regenerate model files to pick up the affected fields. **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0rc4...1.0.0rc5
-
1.0.0rc4
Release: Release 1.0.0rc4e2f35b30 · ·# 1.0.0rc4 — Release Candidate 4 Fourth release candidate of the `1.0.0` line. It adds class-level queryable system fields and group-management write methods, and fixes license handling on enaio 12, field clearing on update and a SQL-whitespace edge case. The public API of `1.0.0rc3` is unchanged apart from the additive capabilities below. ## Added - **Class-level `Model.system.<field>` as queryable fields.** `system` is now access-aware: instance access (`obj.system.id`) still returns the loaded value, while class access (`Model.system.id`) returns an `ECMField` usable in `where()` / `order_by()`. This enables cross-type filtering on a parent via the same dotted path, e.g. all documents inside a known folder via `select(Doc).where(Folder.system.id == folder.system.id)`. Exposed for every system field with a single queryable backing column (`id`, `owner_guid`, `creator`, `creation_date`, `last_modifier`, `last_modified`, `creation_time`, `deleted_at`; register/document location fields; and the queryable subset of `system.base_params` and `system.file_properties`). Aggregate values without a backing column (`rights`, `name`, `is_modified`) remain instance-only. Verified against a live server. - **Group-management write methods on `ecm.security` (#15...).** `create_group()`, `update_group()`, `delete_group()` and `empty_group()` wrap `mng.CreateGroup`, `mng.SetGroupAttributes`, `mng.DeleteGroup` and `mng.EmptyGroup`. `create_group()` returns an `ECMGroup` with the server-assigned `id` and `guid`; `update_group()` takes a (modified) `ECMGroup`; `delete_group()` / `empty_group()` accept either an `ECMGroup` or a group name. A group can only be deleted once empty. Sync and async. ## Fixed - **License jobs no longer raise a hard error on enaio 12+.** `check_license()` and `module_info()` now pass `Flags=1` to the `LIC_CHECKLICENSE` and `LIC_LICGETMODULEINFO` server jobs; since enaio version 12 these return a hard error with the previous `Flags=0`. As a consequence `module_info()` for an unknown module now returns a result with a `?` license-type marker instead of failing; this is detected and reported as the documented `ECMNotFoundException` (sync and async). - **Fields could not be cleared on update (#15434).** Setting a loaded field to `None` was correctly detected as a change, but `_build_update_xml` skipped `None`-valued fields, so the reset was never sent and the server kept the old value. A field changed to `None` is now emitted with `field_function="NULL"` so the server actually clears it (sync and async). `insert()` still omits `None` fields. - **`ecm.db.select()` raised an opaque `IndexError` on leading whitespace (#15431).** A statement beginning with whitespace (e.g. a leading newline from a multi-line literal) made `ado.ExecuteSQL` return no result set while still reporting success, tripping `files[0]`. The bound command is now left-trimmed before being sent (sync and async). **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0rc3...1.0.0rc4
-
1.0.0rc3
Release: Release 1.0.0rc3c6536ad0 · ·# 1.0.0rc3 — Release Candidate 3 Third release candidate of the `1.0.0` line. It adds table-field column conditions to the query builder and fixes enum and workflow-model handling. The public API of `1.0.0rc2` is unchanged apart from the additive query capability below. ## Added - **Table-field column conditions in the query builder (#15428).** Conditions can now target columns of a sub-table / multi-field (e.g. `Invoice.Positions.ArticleNo == "A-100"`), emitting `<TableCondition>` / `<TableColumn>` instead of a flat field condition. Restrict a condition to a row via `Invoice.Positions[3].Quantity == 5` (alias `.row(3)`). Works in `select` and `select_lol` (sync and async) with all comparison and collection operators. ## Fixed - **Enum (catalog) field values were serialized as their Python repr (#15427).** Passing a generated `(str, Enum)` / `IntEnum` member to `insert` / `update` / `upsert` emitted `Class.MEMBER` instead of the catalog value, which the server rejected. Enum members are now unwrapped to their value before conversion. - **Workflow start inputs were under-detected.** Inputs were read from `INOUT` parameters across the whole model (including activities) and `IN` was ignored. They are now read from the `<WorkflowProcess>` interface only, counting both `IN` and `INOUT`; the standard ad-hoc workflow, for example, previously reported 2 of its 5 input variables. - **List-of-record workflow variables lost their type and members.** Variables typed as a list of records are now correctly typed as `list[...Record]` with their members. ## Changed - **Generated workflow-model class names derive from the stable workflow display name** (e.g. `Standard_Ad_hoc_WorkflowModel` instead of `Ad_hoc_Version_3_0_5WorkflowModel`), so they no longer change when the workflow version increases. ## Documentation - New **FastAPI integration** and **workflow-start** guides (with matching skills). German docs use "Schrank"; skill documentation links now point to the hosted Antora site. **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0rc2...1.0.0rc3
-
1.0.0rc2
Release: Release 1.0.0rc2498a70a8 · ·# 1.0.0rc2 — Release Candidate 2 Second release candidate of the `1.0.0` line. It adds steerable table-field replacement and fixes two object/XML handling defects, one of which affected a production environment. The public API of `1.0.0rc1` is unchanged apart from the additive parameters below. ## Added - **Steerable table-field replacement on `upsert` and `update` (#15422).** New `replace_table_fields(value=True)` fluent method on the upsert builder, and a keyword-only `replace_table_fields: bool | None` parameter on `ecm.dms.update()` and `ecm.dms.update_and_get()` (sync and async). `None` (default) keeps the automatic detection, `True` forces `REPLACETABLEFIELDS=1`, `False` suppresses it. ## Fixed - **Invalid upsert XML when a search section was used (#15424).** The `<Search>` element was placed after `<Fields>`, but the schema requires it first; the server rejected such requests (`Element 'Search' is unexpected …`). `<Search>` is now emitted first, so every `upsert(...).search(...)` call produces valid XML. - **Object definition dropped fields from unnamed PageControl tabs.** Tabs with a blank internal name collapsed onto one entry and lost their fields. Pages now fall back to their unique `page_id`, restoring the missing fields in `ecm.system.definition()`, `ecm.dms.model_by_name()` and `ecm-generate-models`. **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0rc1...1.0.0rc2
-
1.0.0rc1
Release: Release 1.0.0rc1f7efdaae · ·First release candidate of the `1.0.0` line. There are **no functional changes to the library API** since `1.0.0a9`; this candidate stabilises the release tooling and test suite. - **Automatic GitLab Release on tags.** Tag pipelines now create a GitLab Release whose description is taken from this tag's message. The built library (wheel + sdist) and the rendered documentation are uploaded to the project's generic Package Registry and linked as permanent release assets, alongside a link to the matching PyPI project page. The rendered Antora site is also bundled as `docs-<tag>.zip`. - **Workflow process-list integration test no longer assumes the creator is the inbox owner.** `ecm.workflow.process_list_by_user()` returns the processes in a user's inbox, and an inbox item may have been created by any user. The `test_process_has_creation_block` test (sync and async) now only asserts that the `creation` block is populated. No change to library behaviour. **Full changelog:** https://gitlab.ecmind.ch/open/ecmind_blue_client/-/compare/1.0.0a9...1.0.0rc1
-
-
-
-
1.0.0a6
52190a61 · ·### Added - **`ecm.workflow.process_list_by_user()`**: New sync and async method wrapping the server job `wfm.AdminGetProcessListByUser`. Returns a list of typed `ECMProcess` objects, each containing an `ECMProcessCreation` block and a tuple of `ECMProcessActivity` instances with parsed timestamps and a convenient `is_personalised` flag (equivalent to `Activity.State & 128`). The `user` argument expects the workflow-organisation user object — not the security user GUID. - **Full-text search on the typed model query builders**: New `.fulltext(term, **engine_options)` chain method on `ecm.dms.select()` (HOL) and `ecm.dms.select_lol()` (LOL), available in both sync and async variants. Adds a `<Fulltext>` condition to the queried object type's `<ConditionObject>` and accepts optional RetrievalWare engine attributes (`mode`, `expansion_level`, `fuzzy_spell_half_words`, `fuzzy_spell_threshold`, `max_fuzzy_spell`, `max_reg_expr`, `warn_max_reg_expr`, `word_expansion_limit`). Requires a configured RetrievalWare search engine on the enaio® server. The archive-wide `<FulltextQuery>` flavour (hits across multiple object types in one request) remains HOL-exclusive at the low-level `DmsQueryBuilder.fulltext_query()` API and is intentionally not exposed on the typed single-model builders.
-
1.0.0a5
3612af07 · ·## 1.0.0a5 ### Added - `ECMDocumentModelSystem.system_id` (`OBJECT_SYSTEMID`): ID of the external archive system holding the referenced file; now also loaded on `get()`. - Read-only enforcement for model fields via the new `ECMField(read_only=...)` parameter (`"always"` / `"init"` / `"arch"`), checked on `insert()`, `insert_variant()`, `update()` and `upsert()` (sync and async). Disable per call with `check_read_only=False`. ### Changed - `generate_ecm_models` now derives `read_only` from the ECM flags (`readonly` → `"always"`, `readonly_after_initialization` → `"init"`, `readonly_after_archiving` → `"arch"`) and emits it on the generated `ECMField(...)` line. - Clarified `foreign_id` documentation, including the *green arrow* special case. ### Fixed - **#15222** Model feature: `update()` failed for fields flagged "read-only after initialization". A `mandatory` + `read_only="always"` field is no longer generated as a required constructor argument.
-
1.0.0a4
0658eb72 · ·## Release Notes — since 1.0.0a3 ### New features - **Skills bundle for AI assistants** — collection of compact, LLM-optimised skill descriptions for every public ECM operation. Auto-loaded by Claude Code / Cline / Cursor via description-based invocation. Downloadable as `/skills.zip` from the docs site. - **`ecm.security` user lifecycle** — `create_user()`, `update_user()`, `delete_user()`, `add_user_to_group()`, `remove_user_from_group()`, plus full sync + async coverage and DE/EN documentation. - **`ecm.security.export_security_system()`** — typed `ECMSecuritySystemExport` wrapping `mng.ExportSecuritySystem`. Group-level security clauses are mapped to their object rights; `ECMObjectRight` (R/W/D/X/U) and `ECMAnnotationRight` (G/P) are decoded as `IntFlag`. - **`ecm.system.info()`** — process-local snapshot of pool connection stats and auto-fetched server info. No RPC; cheap to call from dashboards or health checks. - **Pool connection statistics** — `pool.connection_stats()` returns a `list[ConnectionStats]` (host, port, server_info, connected_at, last_call_at, call_count, stable `connection_id`). - **`RpcServerInfo`** — fetched once per pool connection from `krn.GetServerInfoEx` and exposed on `RpcConnection.server_info`. Tolerant parser: partial server responses never break the connection. - **Coverage in CI** — every `unittests` run now emits Cobertura + JUnit reports and feeds the GitLab coverage badge. ### Improvements - **Codebase-wide docstring refactor** — Google-style docstrings (Args/Returns/Raises/Example) across the public API and across the test suite. - **`pyproject.toml` cleanup** — removed dead `[tool.uv.workspace]` / `[tool.uv.sources]` declarations, dropped redundant `setuptools-scm` and unused `pytest-xdist` from dev extras, added `pyright`. The `TcpClient` extra alias is kept and now documented as a backwards-compatibility shim. - **`.gitlab-ci.yml` overhaul** — shared `default.before_script` with `uv sync --frozen` (lockfile drift now fails the pipeline); `build_docs` moved into the `build` stage and now zips `skills/ecmind-blue-client` into `public/skills.zip`; `deploy_pypi_alpha` renamed to `deploy_pypi_prerelease` (regex covers `a`/`b`/`rc`); redundant `when: always` removed from deploy rules. - **Documentation** — new "Skills for AI assistants" / "Skills für KI-Assistenten" section on the DE + EN index pages with direct download link. ### Fixed - **`uv build` regression** introduced by the dev-extra cleanup — `--no-build-isolation` dropped from the `build` job so build dependencies come from `[build-system].requires` again. - Test assertions aligned with current behaviour for XML self-closing tags and SQL-quote escaping.
-
1.0.0a3
b118f9d5 · ·## Release Notes — since 1.0.0a2 ### New features - **Document variants** (dc79def) — `ecm.dms.insert_variant(...)` and `insert_variant_and_get(...)` (sync + async) for creating new variants of an existing document. The internal XML builder gained a `variant_parent_id` parameter; the variant inherits `folder_id`/`register_id` from its parent. New docs: `insert_variant`, `insert_variant_and_get`. - **Generic model from type name** (f104f2c) — `ecm.dms.model_by_name("…")` resolves an internal object-type name via `ecm.system.definition()` and returns the matching dynamic subclass (`ECMFolderModel` / `ECMRegisterModel` / `ECMDocumentModel`). Usable directly in `select(...)`. New doc: `model_by_name`. - **Default system fields inherited** (24beaaf) — `ECMRegisterModel` and `ECMDocumentModel` now append their specific `SystemFields` to `_ECMModelBase._ecm_system_fields_` instead of overriding them. Breaking for code that relied on the base fields being absent. ### Improvements - **`tcp` extra is optional again** (68fad5f) — `Client`, `Job`, `Param`, `QueryConditionField`, `QueryConditionGroup`, `QueryResultField` are lazily re-exported in `ecmind_blue_client/__init__.py` via PEP 562 `__getattr__`. The ECM abstraction (`SyncPoolClient` / `AsyncPoolClient`) can now be used without installing `XmlElement`. - **Pyright config** (94736bc) — `build`, `dist`, `__pycache__`, `.venv` excluded from the scan. ### Cleanup - **Expanded tests** — new suites for variants (`test_ecm_dms_variant_sync/async/unit.py`) and `model_by_name` (`test_ecm_model_sync/async.py`); minor cleanups in the async DMS tests. -
1.0.0a2
1c880159 · ·## Changelog since tag `1.0.0a1` ### New Features **DMS** - `std.GetDocumentStream` – partial reading of document file ranges (1c88015) - `dms.SetUserData` / `dms.GetUserData` – user-scoped data storage (86c37c1) - `dms.CheckOut`, `dms.UndoCheckOut`, `dms.CheckIn` including document history (693133d, b7da1e0) - `dms.CheckPermission` (3cc2bad) **Workflow (wfm)** - Full Workflow API added (e2fcdad) - Workflow organisations (1bcc01f) - `wfm.SetSubstitutes` (cbd138d) - `wfm.ConfigUserAbsence` (a7809df) - `wfm.SaveOrganisation` (d067fd8) **License & Kernel** - `lic.CheckLicense` and `lic.LicGetModuleInfo` (2c80f84) - `krn.RunScript` and `krn.EmptyJob` (78552c3) ### Improvements - Eliminated unnecessary `get_object_type_by_id` calls (f929ec4) - Tests optimised, manual unit tests added (84ab824, e3f637b) ### Documentation & Infrastructure - Model API documentation added (04372aa) - Docker container for documentation added (c8405c1, 1e03990, 5589eae, 9ce084a, 340c39c) - German documentation as default landing page (9f812b8)
-
1.0.0a1
Release: 1.0.0a16347ccfd · ·## Changelog: 0.9.2 → 1.0.0 ### New Features - **Model API (ORM-style):** Declarative query builder with typed model classes, conditions, sorting, and table fields - **Upsert builder:** Fluent `ecm.dms.upsert()` with configurable search and action strategies - **Dynamic models:** Runtime model creation via `make_folder_model()` / `make_register_model()` / `make_document_model()` - **`ecm.security` namespace:** User and group management (`users()`, `groups()`, `roles()`, `user()`) - **Impersonation:** `ecm.impersonate(username)` context manager - **Definition module:** Full parsing of `asobjdef` XML into a typed object graph ### New Endpoints - `dms.XMLCopy` — copy DMS objects - `dms.XMLMove` — move DMS objects - `dms.XMLDelete` — delete DMS objects by query - `dms.GetObjectDetails` — retrieve detailed object metadata - `std.CalcDocumentDigest` / `std.FindDocumentDigest` — document integrity via hash - `ado.ExecuteSQL` — execute raw SQL via ADO - `mng.GetUserList` / `mng.GetUserAttributes` / `mng.GetUserGroups` / `mng.GetUserRoles` — user management - `mng.GetGroupList` / `mng.GetGroupAttributes` / `mng.GetGroupMembers` — group management ### Architecture - Sync/async split into `ecm/synchron/` and `ecm/asynchron/` - `SyncPoolClient` / `AsyncPoolClient` replace `TcpPoolClient` - Python 3.12+, switched to **UV** as package manager - Added `ECMNotFoundException` and `ECMWrongStateException` ### Documentation - Antora-based documentation with migration guide and quickstart
-
-
-
0.9.0
Release: 0.9.0b08896f0 · ·# Release notes - remove protlib dependency - remove deprecated SOAP and COM clients and all related dependencies - replace tcp_client_classes with new rpc implementation - Add code documentation - bugfix pooling errors
-
0.8.1
Release: 0.8.14cf8667b · ·* Linting warnings * Fix buffer of buffer in RequestFile * Rename parameter bytes into file_bytes init in RequestFile * Fix CamelCase properties in sopa_client * Fix JobCaller connection error handling
-