The latest release of viur-core brings a substantial set of improvements, cleanups, and a few noteworthy breaking changes that developers will want to be aware of before migrating their projects.
- Python compatibility has been tightened: viur-core 3.8 now requires Python 3.12 or 3.13. Old compatibility flags for legacy Admin and Vi formats are disabled by default, meaning several conf.compatibility.remove(...) lines can simply be deleted from existing projects. The conf object now runs in strict mode, so old-style dict access like conf["mainApp"] is no longer permitted.
- Internationalization gets a welcome upgrade — all bone validations now return translated error messages, and a new global flag conf.i18n.auto_translate_bones controls automatic translation of bone descriptions and categories.
- The db module is back home. After being spun off into the separate viur-datastore package in version 3.1, the Cloud Datastore abstraction layer has been reintegrated into viur-core itself. The split had led to development inconsistencies and, since Google's own Datastore API implementation has become faster again, there was no longer a good reason to keep it separate. Functions like db.put, db.get, and db.delete are now PEP-8 compliant snake_case; old-style calls generate deprecation warnings.
- Query limits are now configurable. Previously hardcoded at 30 (default) and 100 (external max), these can now be adjusted globally via conf.db.query_default_limit and conf.db.query_external_limit — removing the need to manually pass ?limit=99 on external list calls.
- The Skeleton API has been refactored significantly. viur-relations handling is now centralized in update_relations(), which also covers RelationalBones inside RecordBones and handles RelationalConsistency checks. New convenience methods include Skeleton.readonly() to mark all bones read-only, and Skeleton.dump() for easy JSON-serializable output — replacing a previously convoluted workaround involving the JSON renderer. RefSkel.read() now allows directly reading a target skeleton from a RelationalBone, including support for dynamic sub-skeletons.
- New bones: RawBone now supports searchable=True, and the new ImageBone (a typed subclass of FileBone) provides a dedicated, accessibility-friendly way to handle images, complete with translated alt text fields.
- New and updated modules: The File.write() function now accepts an optional folder path and auto-creates directories. A brand-new History module enables out-of-the-box change tracking for any skeleton, with optional BigQuery support. In the User module, a new is_admin() function replaces scattered "root" in user["access"] checks, and the login flow now uses ActionSkels — a minor breaking change for some projects. User.adminInfo has also changed from a class attribute to a method.
- Finally, the old rebuildSearchIndex task has been replaced by the more powerful SkeletonMaintenanceTask, which lets root users refresh, delete, or count records with optional filter and logic expressions — protected by a default "do nothing" condition that must be explicitly overridden.
Find a well written release note in English and German here!