We’re happy to announce the release of GroupDocs.Assembly for Python v26.11, available as of November 2026. This release delivers major platform support improvements—including the first wheels for Linux and macOS—along with native Python data source support, enhanced error handling, and upgraded dependencies. It also introduces several new features and breaking changes to align with modern Python practices and .NET 10.

What’s new in this release

  • [Feature] Add wheels for Linux x64 and macOS (Intel and Apple Silicon) (ASSEMBLYPYTHON-26)
  • [Feature] Add support for a Python dict or list as a data source (ASSEMBLYPYTHON-27)
  • [Feature] Add support for a Python handler of document table loading (IDocumentTableLoadHandler) (ASSEMBLYPYTHON-28)
  • [Feature] Add support for Python types where the API takes a .NET Type (DocumentTableColumn.type, known_types) (ASSEMBLYPYTHON-29)
  • [Feature] Add support for applying the license from the GROUPDOCS_LIC_PATH environment variable (ASSEMBLYPYTHON-30)
  • [Enhancement] Update GroupDocs.Assembly to 26.7 and the embedded runtime to .NET 10.0.14 (ASSEMBLYPYTHON-31)
  • [Enhancement] Ship a pure-Python package for Python 3.5 – 3.14 in place of the compiled extension (ASSEMBLYPYTHON-32)
  • [Enhancement] Accept one DataSourceInfo in assemble_document() as well as a list (ASSEMBLYPYTHON-33)
  • [Enhancement] Raise FileNotFoundError for a missing file, LicenseError for a license that cannot be applied, and GroupDocsAssemblyException for other engine errors (ASSEMBLYPYTHON-34)
  • [Enhancement] Rename BarcodeSettings.x_resolution/y_resolution to xresolution/yresolution, and make use_reflection_optimization a class attribute (ASSEMBLYPYTHON-35)
  • [Enhancement] Remove the 32-bit Windows wheel (ASSEMBLYPYTHON-36)
  • [Fix] Fix CVE findings in 25.5.1: zlib 1.2.11 → 1.2.12 (+4 more) (ASSEMBLYPYTHON-11)

Public API changes

Upgraders need to rename x_resolution/y_resolution and set_use_reflection_optimization(), and catch GroupDocsAssemblyException and LicenseError where they caught RuntimeError. Everything else is additive.

New classes and members

  • groupdocs.assembly: FontSettings, FolderFontSource, IFontSource, SearchOption, OoxmlCompliance, GroupDocsAssemblyException, LicenseError, LicenseWarning.
  • LoadSaveOptions: ooxml_compliance.
  • KnownTypeSet: append().
  • DocumentTableCollection, DocumentTableColumnCollection: get().
  • DocumentTableRelationCollection: append(), get().

Renamed

  • BarcodeSettings.x_resolution → BarcodeSettings.xresolution
  • BarcodeSettings.y_resolution → BarcodeSettings.yresolution

The old names raise AttributeError with a “Did you mean” hint, on reading and on assignment.

Removed

  • DocumentAssembler.set_use_reflection_optimization(): assign the class attribute instead, DocumentAssembler.use_reflection_optimization = False.

Changed

  • DataSourceInfo takes a dict or a list.
  • assemble_document() takes one DataSourceInfo as well as a list.
  • DocumentTableSet(path, load_handler) takes a Python function or an object with handle(args).
  • DocumentTableColumn.type and KnownTypeSet.add() take a Python type.
  • Engine errors raise FileNotFoundError, RuntimeError, LicenseError or GroupDocsAssemblyException. except Exception catches the errors of both releases.

New features

Linux and macOS

26.11 has wheels for Linux x64 (manylinux_2_27_x86_64, glibc 2.27 or newer) and for macOS 12 or newer on Intel (macosx_12_0_x86_64) and Apple Silicon (macosx_12_0_arm64), beside Windows x64. 25.5 had Windows wheels only. pip 20.3 or newer picks the wheel for the platform. On Linux the .NET runtime needs ICU, and presentation templates need libgdiplus (see Requirements).

pip install groupdocs-assembly-net==26.11.0

Python data as a data source

DataSourceInfo takes a dict, a list of dicts or a list of values as it is; 25.5 raised TypeError for a dict. The wrapper turns the data into .NET objects typed from its shape, so numbers, strings, bool, datetime, date and Decimal values reach the template typed: <<[o.OrderDate.Month]>> and <<if [c.Vip]>> work as they do on .NET objects. Dicts in one list share one type with the union of their keys.

from groupdocs.assembly import DataSourceInfo, DocumentAssembler

orders = [
    {"Number": 10001, "Product": "Harbor Blend whole bean coffee", "Quantity": 30, "Price": 552.0},
    {"Number": 10004, "Product": "Aged harbour cheddar", "Quantity": 8, "Price": 132.0},
]

# order-table.docx: a table whose row <<foreach [o in orders]>><<[o.Number]>> ... <</foreach>> repeats per order
DocumentAssembler().assemble_document("order-table.docx", "order-table-report.docx", [
    DataSourceInfo("Quayside Bistro", "customer"),
    DataSourceInfo(orders, "orders"),
])

One data source without a list

assemble_document() takes one DataSourceInfo or a list of them, as .NET’s params DataSourceInfo[] does. 25.5 required a list and raised TypeError: can't build Array value from 'groupdocs.assembly.DataSourceInfo' for one.

from groupdocs.assembly import DataSourceInfo, DocumentAssembler

customer = {"Name": "Quayside Bistro", "Product": "Harbor Blend whole bean coffee"}
DocumentAssembler().assemble_document("hello-world.docx", "hello-world-report.docx", DataSourceInfo(customer, "customer"))

Table-load handlers

DocumentTableSet(path, load_handler) takes a Python function (args), or an object with a handle(args) method, and calls it for each table of the document before it loads. The handler sets that table’s args.options, or skips the table with args.is_loaded = False; args.table_index says which table it is. 25.5 raised TypeError for a Python function.

from groupdocs.assembly.data import DocumentTableOptions, DocumentTableSet


def on_table(args):
    options = DocumentTableOptions()
    options.first_row_contains_column_names = True
    args.options = options


tables = DocumentTableSet("contracts.xlsx", on_table)
for table in tables.tables:
    print(table.name, [column.name for column in table.columns])

Python types where the API takes a .NET type

A Python type stands for the .NET type a member takes: float for System.Double, int, str, bool, datetime. A column of a document table can be made numeric so a chart sums it, and known_types lets a template call a type’s static members; it also takes a .NET type name. 25.5 raised TypeError: can't build Type value from 'type'.

from groupdocs.assembly import DataSourceInfo, DocumentAssembler
from groupdocs.assembly.data import DocumentTable, DocumentTableOptions

options = DocumentTableOptions()
options.first_row_contains_column_names = True
contracts = DocumentTable("contracts.xlsx", 0, options)
contracts.columns["Price"].type = float

assembler = DocumentAssembler()
assembler.known_types.add("System.Math")  # templates can call <<[Math.Round(x, 1)]>>
assembler.assemble_document("table-row.docx", "table-row-report.docx", DataSourceInfo(contracts, "contracts"))

License from the environment

Set GROUPDOCS_LIC_PATH to the path of a license file, or to a URL that serves one, and the license is applied at the first engine call, with no license code; 25.5 did not read the variable. If that license cannot be applied (a missing file, an expired subscription, a license for another product), every engine call raises LicenseError, naming the variable and the engine’s reason, until License().set_license() applies a license. Set GROUPDOCS_LIC_STRICT=0 to get one LicenseWarning and evaluation mode instead.

from groupdocs.assembly import DataSourceInfo, DocumentAssembler, LicenseError

customer = {"Name": "Quayside Bistro", "Product": "Harbor Blend whole bean coffee"}
try:
    DocumentAssembler().assemble_document("hello-world.docx", "hello-world-report.docx", DataSourceInfo(customer, "customer"))
except LicenseError as e:
    print(e)  # GROUPDOCS_LIC_PATH=... could not be applied: <reason>

Errors by kind

25.5 raised a bare RuntimeError("Proxy error(<.NET exception>): ...") for every engine error. 26.11 raises FileNotFoundError for a missing template or data file, which still derives from RuntimeError; RuntimeError with the engine’s message alone for a template error or a member the data lacks; LicenseError for a license that cannot be applied; and GroupDocsAssemblyException for the other engine errors. LicenseError and GroupDocsAssemblyException are importable from groupdocs.assembly and do not derive from RuntimeError.

from groupdocs.assembly import DataSourceInfo, DocumentAssembler, GroupDocsAssemblyException

try:
    DocumentAssembler().assemble_document("no-such-template.docx", "report.docx", DataSourceInfo({"Name": "A"}, "customer"))
except FileNotFoundError as e:
    print("missing:", e)
except (RuntimeError, GroupDocsAssemblyException) as e:
    print("engine:", e)

Code example

from groupdocs.assembly import DataSourceInfo, DocumentAssembler, FileFormat, LoadSaveOptions, OoxmlCompliance

options = LoadSaveOptions(FileFormat.DOCX)
options.ooxml_compliance = OoxmlCompliance.STRICT
customer = {"Name": "Quayside Bistro", "Product": "Harbor Blend whole bean coffee"}
DocumentAssembler().assemble_document("hello-world.docx", "hello-world-strict.docx", options, DataSourceInfo(customer, "customer"))

How to get the update

PyPI

Upgrade to the latest package via PyPI:

groupdocs-assembly-net 26.11.0

pip install groupdocs-assembly-net==26.11.0

Direct download

Download wheels for your platform from the GroupDocs.Assembly for Python v26.11 page.

Resources