# GroupDocs.Metadata for Python via .NET — Complete Documentation > Develop Applications to Create, View, Access, Update, Delete, Search, Compare, Replace & Export Metadata of Popular Documents & Image Formats. --- ## Exporting metadata properties Path: /metadata/python-net/exporting-metadata-properties/ This example demonstrates how to export metadata properties to an Excel workbook. The `ExportManager` constructor takes a list of `MetadataProperty` objects, so collect the properties you want (here, the whole tree via `find_properties`) and wrap the result in `list(...)`. `ExportFormat` also supports `CSV`, `JSON` and `XML`. {{< tabs "exporting-metadata-properties">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.export import ExportManager, ExportFormat def exporting_metadata_properties(): with Metadata("input.pdf") as metadata: # Collect the whole metadata tree as a list of properties properties = list(metadata.find_properties(lambda p: True)) # Export them to an Excel workbook ExportManager(properties).export("export.xlsx", ExportFormat.XLSX) print(f"Exported {len(properties)} properties to export.xlsx") if __name__ == "__main__": exporting_metadata_properties() ``` {{< /tab >}} {{< tab "input.pdf" >}} {{< tab-text >}} `input.pdf` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties/input.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "export.xlsx" >}} ```text Binary file (XLSX, 9 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties/exporting_metadata_properties/export.xlsx) {{< /tab >}} {{< /tabs >}} ## See also - [Extracting property values]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/extracting-property-values.md" >}}) - [Working with metadata properties]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Features Overview Path: /metadata/python-net/features-overview/ ## Overview GroupDocs.Metadata for Python via .NET reads, edits, removes, and exports metadata across **documents, images, audio, video, and many other formats** — Microsoft Office, PDF, OpenDocument, images (JPEG, PNG, PSD, TIFF), audio (MP3, WAV), video, fonts, e-books, archives, and more. It exposes the major metadata standards (XMP, EXIF, IPTC, Image Resource Blocks, ID3) and format-specific properties through one unified, predicate-driven API. It runs entirely on-premise, requires no Microsoft Office installation, and ships as a pre-built wheel on Windows, Linux, and macOS. See the full list of [supported formats]({{< ref "/metadata/python-net/getting-started/supported-document-formats.md" >}}) or browse the [Developer Guide]({{< ref "/metadata/python-net/developer-guide/_index.md" >}}) for runnable examples of every API surface. ## Reading and Searching Metadata Read every property in a file, or search for specific properties using a plain Python predicate (`lambda p: ...`) — no specification objects required. You can match on a property's name, value, type, or [tags]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-interpreted-values.md" >}}). - [Find metadata properties]({{< ref "/metadata/python-net/developer-guide/basic-usage/find-metadata-properties.md" >}}) — locate properties that match a predicate, across any format. - [Extract metadata]({{< ref "/metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) — pull properties from the native, document, and standards packages. - [Get known property descriptors]({{< ref "/metadata/python-net/developer-guide/advanced-usage/getting-known-property-descriptors.md" >}}) — discover the strongly-typed properties a package exposes. - [Work with interpreted values]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-interpreted-values.md" >}}) — read human-friendly, interpreted forms of raw property values. ## Editing Metadata Add new properties or update existing ones in a unified way. Predefined **tags** let you set common properties (author, creation date, title) consistently regardless of the underlying format. - [Set metadata properties]({{< ref "/metadata/python-net/developer-guide/basic-usage/set-metadata-properties.md" >}}) — add or update every property matching a predicate. - [Add metadata]({{< ref "/metadata/python-net/developer-guide/advanced-usage/adding-metadata.md" >}}) — add missing properties (for example, a last-printed date) when the format supports them. ## Removing and Cleaning Metadata Remove particular properties that match a predicate, or strip every detected property in a single call — ideal for privacy and compliance workflows. - [Remove metadata properties]({{< ref "/metadata/python-net/developer-guide/basic-usage/remove-metadata-properties.md" >}}) — delete only the properties that match a predicate. - [Clean metadata]({{< ref "/metadata/python-net/developer-guide/basic-usage/clean-metadata.md" >}}) — `sanitize()` removes every detected property at once. - [Remove metadata (advanced)]({{< ref "/metadata/python-net/developer-guide/advanced-usage/removing-metadata.md" >}}) — remove whole metadata packages from a file. ## Working with Metadata Standards Read and write the metadata standards used by images and many other formats: - [EXIF]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata.md" >}}) — read, update, and remove EXIF tags in JPEG, TIFF, PNG, WEBP, PSD, and more. - [IPTC IIM]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata.md" >}}) — read and edit IPTC datasets in JPEG, TIFF, and PSD. - [XMP]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata.md" >}}) — read, update, and add custom XMP packages across formats. Image Resource Blocks (IRB) and format-specific native packages are exposed through the same root metadata tree. ## Audio Metadata Manage audio tags through the root package: **ID3v1**, **ID3v2**, **Lyrics3**, and **APE**, plus MPEG audio technical properties. Read or edit titles, artists, albums, and other tag fields, then [export]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties.md" >}}) or strip them as needed. ## Document Inspection and File Type Detection Read basic facts about a file without walking its full metadata tree — format, MIME type, page count, size, and encryption state — and detect a file's format by its internal structure rather than its extension. - [Get document info]({{< ref "/metadata/python-net/developer-guide/basic-usage/get-document-info.md" >}}) — format, MIME type, page count, size, and encryption flag. Office documents also expose inspection data such as user comments, form fields, hidden pages, revisions, digital signatures, and common statistics (word count, character count). ## Loading Files from Different Sources The `Metadata` constructor accepts a file path, a binary file-like object, or a URI, so you can load files from local disk, in-memory buffers, or cloud storage. - [Load from a local disk]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-local-disk.md" >}}) - [Load from a stream]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-stream.md" >}}) — `open("file.jpg", "rb")`, `io.BytesIO(data)`, or bytes fetched from S3, Azure Blob, or `requests`. - [Load a file of a specific format]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-file-of-a-specific-format.md" >}}) - [Load a password-protected document]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-password-protected-document.md" >}}) ## Saving Files After editing, save back to the original source or to a new destination — a path or a stream. - [Save to a specified location]({{< ref "/metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-specified-location.md" >}}) - [Save to a stream]({{< ref "/metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-stream.md" >}}) - [Save to the original source]({{< ref "/metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-the-original-source.md" >}}) {{< alert style="info" >}} Saving a modified file requires a license. Without a license, the library runs in evaluation mode — it reads only the first few properties of each package and `save()` raises an "Evaluation only" exception. See [Evaluation Limitations and Licensing]({{< ref "/metadata/python-net/getting-started/evaluation-limitations-and-licensing.md" >}}). {{< /alert >}} ## Exporting Metadata Export the metadata tree — or a filtered subset of properties — to a spreadsheet or a structured data file for indexing, reporting, or downstream processing. - [Export metadata properties]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties.md" >}}) — write to **Excel, CSV, JSON, or XML** via `ExportManager`. ## AI and LLM Integration GroupDocs.Metadata is a useful building block for AI document pipelines: extract metadata as structured data to enrich search indexes and LLM context. The `groupdocs-metadata-net` pip package ships an `AGENTS.md` file inside the wheel so AI coding assistants can discover the API surface automatically, and GroupDocs runs a public [MCP server](https://docs.groupdocs.com/mcp) for on-demand documentation lookups. See [Agents and LLM Integration]({{< ref "/metadata/python-net/agents-and-llm-integration.md" >}}) for the full story. ## On-Premise Deployment No cloud calls, no outbound network traffic, no third-party software dependencies beyond what the OS already provides. The wheel is self-contained on Windows and ships its own native runtime libraries on Linux and macOS. See [System Requirements]({{< ref "/metadata/python-net/getting-started/system-requirements.md" >}}) for the short list of optional native packages (`libgdiplus`, fontconfig). --- ## Get document info Path: /metadata/python-net/get-document-info/ GroupDocs.Metadata allows users to get document information which includes: * __File format__ (detected by the internal structure) * __File extension__ * __MIME type__ * __Number of pages__ * __File size__ * A __value__ indicating whether a file is encrypted The following code sample demonstrates how to extract basic format information from a file. {{< tabs "get-document-info">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def get_document_info(): # Open the file (the context manager releases it on exit) with Metadata("input.xlsx") as metadata: # Read basic information detected from the file's internal structure info = metadata.get_document_info() # Format, extension and MIME type come from the file_type descriptor print(f"File format: {info.file_type.file_format}") print(f"File extension: {info.file_type.extension}") print(f"MIME Type: {info.file_type.mime_type}") # Page/size/encryption details are exposed directly on the info object print(f"Number of pages: {info.page_count}") print(f"Document size: {info.size} bytes") print(f"Is document encrypted: {info.is_encrypted}") if __name__ == "__main__": get_document_info() ``` {{< /tab >}} {{< tab "input.xlsx" >}} {{< tab-text >}} `input.xlsx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/basic-usage/get-document-info/input.xlsx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "get-document-info.txt" >}} ```text File format: 2 File extension: .xlsx MIME Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet Number of pages: 2 Document size: 1677676 bytes Is document encrypted: False ``` [Download full output](/metadata/python-net/_output_files/developer-guide/basic-usage/get-document-info/get_document_info/get-document-info.txt) {{< /tab >}} {{< /tabs >}} ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## How to install the libgdiplus library Path: /metadata/python-net/getting-started/troubleshooting/how-to-install-libgdiplus/ ## Overview If you process images (or documents that contain images) with GroupDocs.Metadata for Python via .NET on Linux or macOS and hit errors related to `System.Drawing` or GDI+, you are likely missing the `libgdiplus` library. This library provides the GDI+-compatible API that .NET's `System.Drawing` relies on. This guide walks you through installing `libgdiplus` on various operating systems. ## Ubuntu / Debian-based systems Update the package list and install `libgdiplus`: ```bash sudo apt-get update sudo apt-get install -y libgdiplus ``` Create a symlink if required for compatibility: ```bash sudo ln -s /usr/lib/libgdiplus.so /usr/lib/libgdiplus.so.0 ``` ## Red Hat / CentOS-based systems Enable the EPEL repository and install `libgdiplus`: ```bash sudo yum install epel-release sudo yum install -y libgdiplus ``` ## macOS Install `libgdiplus` via Homebrew: ```bash brew install mono-libgdiplus ``` ## Windows On Windows you usually do not need `libgdiplus`, as GDI+ functionality is built into the operating system. ## Verifying the installation After installing, verify it is found: ```bash ldconfig -p | grep libgdiplus ``` ### Common issues * **"Cannot find libgdiplus.so"** — ensure the symbolic link exists; re-run the `ln -s` command above. * **"System.Drawing.Common is not supported" persists** — make sure your .NET runtime is up to date and that fonts are installed (`sudo apt install ttf-mscorefonts-installer fontconfig && sudo fc-cache -f`). --- ## Load from a local disk Path: /metadata/python-net/load-from-a-local-disk/ The following example demonstrates how to load a file from a local disk by passing its path to the `Metadata` constructor. {{< tabs "load-from-a-local-disk">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def load_from_local_disk(): # Absolute or relative path to your document with Metadata("input.docx") as metadata: # Extract, edit or remove metadata here info = metadata.get_document_info() print(f"Loaded {info.file_type.file_format} ({info.size} bytes)") if __name__ == "__main__": load_from_local_disk() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/loading-files/load-from-a-local-disk/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "load-from-local-disk.txt" >}} ```text Loaded 3 (17952 bytes) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/loading-files/load-from-a-local-disk/load_from_local_disk/load-from-local-disk.txt) {{< /tab >}} {{< /tabs >}} ## See also - [Load from a stream]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-stream.md" >}}) - [Loading files]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## GroupDocs.Metadata for Python via .NET Overview Path: /metadata/python-net/product-overview/ ## What is GroupDocs.Metadata? GroupDocs.Metadata for Python via .NET is a native Python library that reads, edits, removes, and exports metadata across **documents, images, audio, video, and many other formats**. It works with the most notable metadata standards — XMP, EXIF, IPTC, Image Resource Blocks, and ID3 — as well as format-specific and built-in document properties, and exposes them all through one unified, predicate-driven API regardless of file format. It runs entirely on-premise, requires no Microsoft Office installation, and ships as a pre-built wheel on Windows, Linux, and macOS. Typical uses include: - **Privacy and compliance** — strip author, GPS location, comments, and hidden data from files before they leave your organization. - **Digital asset management** — read and edit EXIF, IPTC, and XMP fields on images to drive search, tagging, and cataloguing. - **AI / content preprocessing** — extract metadata as structured data (JSON, CSV) to enrich search indexes and LLM context. See [Agents and LLM Integration]({{< ref "/metadata/python-net/agents-and-llm-integration.md" >}}). - **Auditing** — inspect documents for format, MIME type, encryption state, and statistics without modifying them. - **Batch normalization** — set or update properties (titles, dates, copyright) across many files with a single predicate. With its powerful and straightforward API, you can: * Work with the most popular metadata standards: XMP, EXIF, IPTC, Image Resource Blocks, ID3, document properties, etc. * Manage audio metadata: ID3 tags (ID3v1, ID3v2), Lyrics3 tag, APE. * Create, modify, and remove metadata with a few lines of code. * Identify built-in, custom, and hidden metadata. * Work with password-protected documents. * Detect the format and MIME type of a loaded file by its internal structure. * Use predefined tags to manipulate metadata properties in a unified way across all supported formats. * Detect and remove digital signatures associated with a loaded file. * Inspect office documents to extract user comments, form fields, hidden pages, etc. * Manage metadata in e-books, torrent files, archives, electronic business cards, saved emails, and more. GroupDocs.Metadata runs across multiple platforms and operating systems: **Windows, Linux, and macOS** (Intel and Apple Silicon). ## Key Capabilities | Capability | Description | |---|---| | **Read and search metadata** | [Find properties with a plain Python predicate]({{< ref "/metadata/python-net/developer-guide/basic-usage/find-metadata-properties.md" >}}) across any format. | | **Edit and add metadata** | [Set, add, and update properties]({{< ref "/metadata/python-net/developer-guide/basic-usage/set-metadata-properties.md" >}}) matched by a predicate. | | **Remove and sanitize** | [Remove selected properties]({{< ref "/metadata/python-net/developer-guide/basic-usage/remove-metadata-properties.md" >}}) or [strip everything in one call]({{< ref "/metadata/python-net/developer-guide/basic-usage/clean-metadata.md" >}}). | | **Metadata standards** | Read and write [EXIF]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata.md" >}}), [IPTC IIM]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata.md" >}}), and [XMP]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata.md" >}}) on images. | | **Audio tags** | ID3v1, ID3v2, Lyrics3, and APE tags in audio files. | | **Document inspection** | [Read format, MIME type, page count, size, and encryption]({{< ref "/metadata/python-net/developer-guide/basic-usage/get-document-info.md" >}}) without editing. | | **Export** | [Export the metadata tree to Excel, CSV, JSON, or XML]({{< ref "/metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties.md" >}}). | | **Load from anywhere** | [Local disk]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-local-disk.md" >}}), [a stream]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-stream.md" >}}), or [a specific format]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-file-of-a-specific-format.md" >}}); [password-protected files]({{< ref "/metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-password-protected-document.md" >}}) supported. | | **Unified tags** | Predefined tags manipulate common properties (author, creation date, title) uniformly across every format. | | **On-premise** | No cloud calls, no Microsoft Office install, no network traffic. | ## Quick Example {{< tabs "quick-example">}} {{< tab "Read metadata" >}} ```python from groupdocs.metadata import Metadata def quick_example(): """Read every metadata property from a document.""" with Metadata("./input.docx") as metadata: # `lambda p: True` matches every property in the file for prop in metadata.find_properties(lambda p: True): print(f"{prop.name} = {prop.value}") if __name__ == "__main__": quick_example() ``` {{< /tab >}} {{< tab "Remove all metadata" >}} ```python from groupdocs.metadata import License, Metadata def remove_all_metadata(): """Strip every property and save a clean copy (saving requires a license).""" License().set_license("./GroupDocs.Metadata.lic") with Metadata("./input.pdf") as metadata: removed = metadata.sanitize() print(f"Removed {removed} properties") metadata.save("./clean.pdf") if __name__ == "__main__": remove_all_metadata() ``` {{< /tab >}} {{< /tabs >}} ## Where to Next 1. **Install the package** — [Installation]({{< ref "/metadata/python-net/getting-started/installation.md" >}}) walks through PyPI and offline wheel installation for Windows, Linux, and macOS. 2. **Run your first example** — the [Quick Start Guide]({{< ref "/metadata/python-net/getting-started/quick-start-guide.md" >}}) reads and removes metadata in a few minutes. 3. **Explore the examples** — [How to Run Examples]({{< ref "/metadata/python-net/getting-started/how-to-run-examples.md" >}}) clones the runnable repository and runs every documented scenario locally or in Docker. 4. **Use it in depth** — the [Developer Guide]({{< ref "/metadata/python-net/developer-guide/_index.md" >}}) covers reading, editing, removing, standards, loading, saving, and exporting. 5. **Plug it into AI pipelines** — [Agents and LLM Integration]({{< ref "/metadata/python-net/agents-and-llm-integration.md" >}}) explains the MCP server and the `AGENTS.md` shipped inside the wheel. ## Technical Support If you encounter an issue while using GroupDocs.Metadata or have a technical question, feel free to create a post in our [Free Support Forum](https://forum.groupdocs.com/c/metadata/9). If free support is not sufficient, you can submit a ticket to our [Paid Support Helpdesk](https://helpdesk.groupdocs.com/). --- ## Save a modified file to the original source Path: /metadata/python-net/save-a-modified-file-to-the-original-source/ This example shows how to save the modified content back to the underlying source. Call `save()` with no arguments — the changes are written back to the file (or stream) the document was loaded from. {{< tabs "save-a-modified-file-to-the-original-source">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def save_file_to_original_source(): with Metadata("input.ppt") as metadata: # Edit or remove metadata here removed = metadata.sanitize() print(f"Removed {removed} properties") # Saves the document back to the underlying source (stream or file) metadata.save() if __name__ == "__main__": save_file_to_original_source() ``` {{< /tab >}} {{< tab "input.ppt" >}} ```text Binary file (PPT, 172 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-the-original-source/save_file_to_original_source/input.ppt) {{< /tab >}} {{< /tabs >}} ## See also - [Save a modified file to a specified location]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-specified-location.md" >}}) - [Saving files]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Working with EXIF metadata Path: /metadata/python-net/working-with-exif-metadata/ ## What is EXIF? According to the specification, EXIF (Exchangeable image file format) is a standard that specifies the formats for images, sound, and tags used by digital still cameras and other systems that handle the image and sound files they record. Despite the confusing name, EXIF is just a metadata standard: it defines a way to store metadata properties in a variety of well-known image and audio formats. The EXIF tag structure is borrowed from TIFF files and declares tags that store technical details such as geolocation, the camera owner's name, camera settings, and so on. {{< alert style="info" >}} Please refer to the following article for more information on the standard: https://en.wikipedia.org/wiki/Exif {{< /alert >}} ## Reading basic EXIF properties To access EXIF metadata in a file of any supported format, GroupDocs.Metadata provides the `exif_package` property on the root package. {{< tabs "exif-read-basic">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def read_basic_exif_properties(): with Metadata("exif.tiff") as metadata: root = metadata.get_root_package() # The EXIF package is exposed on the root; it may be absent exif = getattr(root, "exif_package", None) if exif is not None: # Top-level EXIF tags print(exif.artist) print(exif.copyright) print(exif.image_description) print(exif.make) print(exif.model) print(exif.software) # The EXIF IFD sub-package holds camera/exposure details print(exif.exif_ifd_package.body_serial_number) print(exif.exif_ifd_package.camera_owner_name) print(exif.exif_ifd_package.user_comment) # The GPS sub-package holds geolocation tags print(exif.gps_package.altitude) print(exif.gps_package.latitude_ref) print(exif.gps_package.longitude_ref) if __name__ == "__main__": read_basic_exif_properties() ``` {{< /tab >}} {{< tab "exif.tiff" >}} {{< tab-text >}} `exif.tiff` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/exif.tiff) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-basic-exif-properties.txt" >}} ```text None None None None None Adobe Photoshop CS6 (Windows) None None test comment 1/5 [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/read_basic_exif_properties/read-basic-exif-properties.txt) {{< /tab >}} {{< /tabs >}} ## Reading all EXIF tags In some cases it's necessary to read all EXIF tags from a file, including custom ones. The API provides direct access to the EXIF tags on different levels. {{< tabs "exif-read-tags">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def read_exif_tags(): with Metadata("exif.jpg") as metadata: root = metadata.get_root_package() exif = getattr(root, "exif_package", None) if exif is not None: # to_list() yields every raw tag (id + value) at each level for tag in exif.to_list(): print(f"{tag.tag_id} = {tag.value}") # ...including the EXIF IFD sub-package for tag in exif.exif_ifd_package.to_list(): print(f"{tag.tag_id} = {tag.value}") # ...and the GPS sub-package for tag in exif.gps_package.to_list(): print(f"{tag.tag_id} = {tag.value}") if __name__ == "__main__": read_exif_tags() ``` {{< /tab >}} {{< tab "exif.jpg" >}} {{< tab-text >}} `exif.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/exif.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-exif-tags.txt" >}} ```text 282 = System.Double[] 283 = System.Double[] 296 = System.Int32[] 531 = System.Int32[] 34665 = System.Int64[] 34853 = System.Int64[] 42032 = James B. 36864 = System.Byte[] 37121 = System.Byte[] 40961 = System.Int32[] [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/read_exif_tags/read-exif-tags.txt) {{< /tab >}} {{< /tabs >}} ## Reading a specific EXIF tag The API supports reading a specific EXIF tag through an indexer that takes a `TiffTagID`. {{< tabs "exif-read-specific">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.formats.image import TiffTagID def read_specific_exif_tag(): with Metadata("exif.tiff") as metadata: root = metadata.get_root_package() exif = getattr(root, "exif_package", None) if exif is not None: # Index the package by TiffTagID to read one specific tag software = exif[TiffTagID.SOFTWARE] if software is not None: print(f"Software: {software.value}") # The same indexer works on the EXIF IFD sub-package comment = exif.exif_ifd_package[TiffTagID.USER_COMMENT] if comment is not None: print(f"Comment: {comment.interpreted_value}") if __name__ == "__main__": read_specific_exif_tag() ``` {{< /tab >}} {{< tab "exif.tiff" >}} {{< tab-text >}} `exif.tiff` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/exif.tiff) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-specific-exif-tag.txt" >}} ```text Software: Adobe Photoshop CS6 (Windows) Comment: test comment ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/read_specific_exif_tag/read-specific-exif-tag.txt) {{< /tab >}} {{< /tabs >}} ## Updating EXIF properties Update EXIF metadata in a convenient way using the `ExifPackage` properties. If the package is missing, create a new one. {{< tabs "exif-update">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.standards.exif import ExifPackage def update_exif_properties(): with Metadata("input.jpg") as metadata: root = metadata.get_root_package() # Create an EXIF package if the image doesn't have one yet if getattr(root, "exif_package", None) is None: root.exif_package = ExifPackage() # Assign top-level EXIF properties root.exif_package.copyright = "Copyright (C) 2026 GroupDocs. All Rights Reserved." root.exif_package.image_description = "test image" root.exif_package.software = "GroupDocs.Metadata" # Assign properties on the EXIF IFD sub-package root.exif_package.exif_ifd_package.body_serial_number = "test" root.exif_package.exif_ifd_package.camera_owner_name = "GroupDocs" root.exif_package.exif_ifd_package.user_comment = "test comment" # Persist the changes metadata.save("output.jpg") if __name__ == "__main__": update_exif_properties() ``` {{< /tab >}} {{< tab "input.jpg" >}} {{< tab-text >}} `input.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/input.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 795 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/update_exif_properties/output.jpg) {{< /tab >}} {{< /tabs >}} ## Adding or updating custom EXIF tags The API allows adding or updating custom tags in an EXIF package using the typed TIFF tag classes. {{< tabs "exif-set-custom">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.formats.image import TiffAsciiTag, TiffTagID from groupdocs.metadata.standards.exif import ExifPackage def set_custom_exif_tag(): with Metadata("exif.tiff") as metadata: root = metadata.get_root_package() if getattr(root, "exif_package", None) is None: root.exif_package = ExifPackage() # Add known properties using typed TIFF tags root.exif_package.set(TiffAsciiTag(TiffTagID.ARTIST, "test artist")) root.exif_package.set(TiffAsciiTag(TiffTagID.SOFTWARE, "GroupDocs.Metadata")) metadata.save("output.tiff") if __name__ == "__main__": set_custom_exif_tag() ``` {{< /tab >}} {{< tab "exif.tiff" >}} {{< tab-text >}} `exif.tiff` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/exif.tiff) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.tiff" >}} ```text Binary file (TIFF, 135 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/set_custom_exif_tag/output.tiff) {{< /tab >}} {{< /tabs >}} The following typed tag classes are available in `groupdocs.metadata.formats.image`: `TiffAsciiTag`, `TiffByteTag`, `TiffDoubleTag`, `TiffFloatTag`, `TiffLongTag`, `TiffRationalTag`, `TiffSByteTag`, `TiffShortTag`, `TiffSLongTag`, `TiffSRationalTag`, `TiffSShortTag`, `TiffUndefinedTag`. ## Removing EXIF metadata To remove the EXIF package from a file, assign `None` to the `exif_package` property. {{< tabs "exif-remove">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def remove_exif_metadata(): with Metadata("exif.jpg") as metadata: root = metadata.get_root_package() # Assigning None drops the entire EXIF package root.exif_package = None metadata.save("output.jpg") if __name__ == "__main__": remove_exif_metadata() ``` {{< /tab >}} {{< tab "exif.jpg" >}} {{< tab-text >}} `exif.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/exif.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 795 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata/remove_exif_metadata/output.jpg) {{< /tab >}} {{< /tabs >}} ## See also - [Working with IPTC IIM metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata.md" >}}) - [Working with XMP metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata.md" >}}) - [Working with metadata standards]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Extracting metadata Path: /metadata/python-net/extracting-metadata/ Using GroupDocs.Metadata you can extract the metadata properties you need from files of different types. You don't have to worry about the exact file format or the metadata standards it uses — the same code works for all supported formats. Most commonly used metadata properties are marked with tags, and all tags are grouped into categories that make it easier to find the one you need. The code sample below demonstrates how to use tags, categories and other property attributes. 1. **Load** a file to search for metadata properties 2. Build a predicate to examine every extracted metadata property 3. Pass the predicate to the **find_properties** method 4. Iterate through the found properties {{< tabs "extracting-metadata">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.tagging import Tags def extracting_metadata(): with Metadata("input.docx") as metadata: # Find every property whose tags fall into the "content" category properties = metadata.find_properties( lambda p: any(tag.category == Tags.content for tag in p.tags) ) for prop in properties: print(f"Property name: {prop.name}, Property value: {prop.value}") if __name__ == "__main__": extracting_metadata() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/extracting-metadata/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "extracting-metadata.txt" >}} ```text Property name: FileFormat, Property value: 3 Property name: MimeType, Property value: application/vnd.openxmlformats-officedocument.wordprocessingml.document Property name: WordProcessingFileFormat, Property value: 3 Property name: Category, Property value: Property name: Comments, Property value: Property name: ContentStatus, Property value: Property name: Keywords, Property value: Property name: RevisionNumber, Property value: 9 Property name: Subject, Property value: Property name: Title [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/extracting-metadata/extracting_metadata/extracting-metadata.txt) {{< /tab >}} {{< /tabs >}} ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Extracting property values Path: /metadata/python-net/extracting-property-values/ The most common way to get a metadata property value is to inspect its type and read the underlying value accordingly. Every `MetadataProperty` exposes a `value` (a `PropertyValue`) whose `type` tells you the data type and whose `raw_value` returns the underlying Python value. {{< tabs "extracting-property-values">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.common import MetadataPropertyType def extract_using_type(): with Metadata("input.docx") as metadata: # Fetch all metadata properties from the file properties = metadata.find_properties(lambda p: True) for prop in properties: # Process string and date/time properties only (as an example) if prop.value.type == MetadataPropertyType.STRING: print(f"{prop.name} (string): {prop.value.raw_value}") elif prop.value.type == MetadataPropertyType.DATE_TIME: print(f"{prop.name} (datetime): {prop.value.raw_value}") if __name__ == "__main__": extract_using_type() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-properties/extracting-property-values/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "extract-using-type.txt" >}} ```text MimeType (string): application/vnd.openxmlformats-officedocument.wordprocessingml.document Extension (string): .docx Author (string): Prokofjev Igor Category (string): Comments (string): Company (string): Profitgroup ContentStatus (string): CreateTime (datetime): 2016-03-22 17:08:00+00:00 Keywords (string): LastPrinted (datetime): 0001-01-01 00:00:00 [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-properties/extracting-property-values/extract_using_type/extract-using-type.txt) {{< /tab >}} {{< /tabs >}} If you need to process many supported types generically, inspect `prop.value.raw_value` together with `prop.value.type` and branch accordingly. This lets you handle arrays, numbers, booleans, nested packages, and so on in a single pass. ## See also - [Exporting metadata properties]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/exporting-metadata-properties.md" >}}) - [Working with metadata properties]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-properties/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Find metadata properties Path: /metadata/python-net/find-metadata-properties/ ## Use tags to find most common metadata properties To make manipulating metadata easier, GroupDocs.Metadata attaches specific tags to the most commonly used metadata properties extracted from a file. Some metadata standards can have quite a complex structure. Moreover, in most cases one image, video or document contains more than one metadata package. Using tags you can search for the properties you want with a few lines of code without even knowing the exact format of the loaded file. In Python you search by passing a **predicate** — any `lambda` (or function) that takes a single `MetadataProperty` and returns `True`/`False` — to the `find_properties` method. The `groupdocs.metadata.tagging.Tags` catalog gives you the tags to test against. The code sample below demonstrates how to search for specific metadata properties using tags: 1. **Load** a file to examine 2. Build a predicate that checks a property carries a specific tag (or a combination of tags) 3. Pass the predicate to the **find_properties** method 4. Iterate through the found properties {{< tabs "find-metadata-properties">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.tagging import Tags def find_metadata_properties(): # Fetch all the properties satisfying the predicate: # the property carries the "last editor" tag OR the "modified date/time" tag with Metadata("input.pptx") as metadata: properties = metadata.find_properties( lambda p: Tags.person.editor in list(p.tags) or Tags.time.modified in list(p.tags) ) for prop in properties: print(f"Property name: {prop.name}, Property value: {prop.value}") if __name__ == "__main__": find_metadata_properties() ``` {{< /tab >}} {{< tab "input.pptx" >}} {{< tab-text >}} `input.pptx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/basic-usage/find-metadata-properties/input.pptx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "find-metadata-properties.txt" >}} ```text Property name: lastsavedby, Property value: tttlll@sibmail.com Property name: lastsavedtime, Property value: 10/28/2019 09:59:47 ``` [Download full output](/metadata/python-net/_output_files/developer-guide/basic-usage/find-metadata-properties/find_metadata_properties/find-metadata-properties.txt) {{< /tab >}} {{< /tabs >}} As a result, we obtain all metadata properties that hold the name of the person who last edited the document and all properties that store the date/time the document was last edited. For more information on searching metadata, please refer to the following articles: * [Extracting metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) * [Removing metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/removing-metadata.md" >}}) * [Adding metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/adding-metadata.md" >}}) ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Load from a stream Path: /metadata/python-net/load-from-a-stream/ This example demonstrates how to load a file from a binary stream. Pass any readable binary file-like object (an `open(..., "rb")` handle or an `io.BytesIO`) to the `Metadata` constructor. {{< tabs "load-from-a-stream">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def load_from_stream(): with open("input.docx", "rb") as stream: with Metadata(stream) as metadata: # Extract, edit or remove metadata here print(f"Loaded {metadata.file_format} from a stream") if __name__ == "__main__": load_from_stream() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/loading-files/load-from-a-stream/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "load-from-stream.txt" >}} ```text Loaded 3 from a stream ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/loading-files/load-from-a-stream/load_from_stream/load-from-stream.txt) {{< /tab >}} {{< /tabs >}} ## See also - [Load from a local disk]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/load-from-a-local-disk.md" >}}) - [Loading files]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Quick Start Guide Path: /metadata/python-net/getting-started/quick-start-guide/ This guide gives a quick overview of how to set up and start using GroupDocs.Metadata for Python via .NET. The library lets you read, edit, and remove metadata from documents, images, audio, and video with minimal configuration. ## Prerequisites To proceed, make sure you have: 1. A configured environment as described in the [System Requirements]({{< ref "/metadata/python-net/getting-started/system-requirements.md" >}}) topic. 2. Optionally, a [Temporary License](https://purchase.groupdocs.com/temporary-license/) to test all product features (saving files requires a license). ## Set Up Your Development Environment For best practices, use a virtual environment to manage dependencies. ### Create and Activate a Virtual Environment Create a virtual environment: {{< tabs "create-venv">}} {{< tab "Windows" >}} ```ps py -m venv .venv ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m venv .venv ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m venv .venv ``` {{< /tab >}} {{< /tabs >}} Activate it: {{< tabs "activate-venv">}} {{< tab "Windows" >}} ```ps .venv\Scripts\activate ``` {{< /tab >}} {{< tab "Linux" >}} ```bash source .venv/bin/activate ``` {{< /tab >}} {{< tab "macOS" >}} ```bash source .venv/bin/activate ``` {{< /tab >}} {{< /tabs >}} ### Install the `groupdocs-metadata-net` package {{< tabs "install-package">}} {{< tab "Windows" >}} ```ps py -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< /tabs >}} ## Example 1: Read metadata Open a file and print all detected metadata properties. {{< tabs "qs-read-metadata">}} {{< tab "Python" >}} ```python import os from groupdocs.metadata import License, Metadata def read_metadata(): # Apply a license if one is present next to the script license_path = os.path.abspath("./GroupDocs.Metadata.lic") if os.path.exists(license_path): License().set_license(license_path) with Metadata("./input.docx") as metadata: # `lambda p: True` matches every property in the file for prop in metadata.find_properties(lambda p: True): print(f"{prop.name} = {prop.value}") if __name__ == "__main__": read_metadata() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/getting-started/quick-start-guide/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-metadata.txt" >}} ```text FileType = GroupDocs.Metadata.Formats.Document.WordProcessingTypePackage DocumentProperties = GroupDocs.Metadata.Formats.Document.WordProcessingPackage DublinCore = GroupDocs.Metadata.Standards.DublinCore.DublinCorePackage InspectionPackage = GroupDocs.Metadata.Formats.Document.WordProcessingInspectionPackage DocumentStatistics = GroupDocs.Metadata.Formats.Document.DocumentStatistics FileFormat = 3 MimeType = application/vnd.openxmlformats-officedocument.wordprocessingml.document Extension = .do [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/getting-started/quick-start-guide/read_metadata/read-metadata.txt) {{< /tab >}} {{< /tabs >}} ## Example 2: Remove all metadata Strip every detected property and save a clean copy. Saving requires a license. {{< tabs "qs-remove-metadata">}} {{< tab "Python" >}} ```python import os from groupdocs.metadata import License, Metadata def remove_metadata(): license_path = os.path.abspath("./GroupDocs.Metadata.lic") if os.path.exists(license_path): License().set_license(license_path) with Metadata("./input.docx") as metadata: # sanitize() strips every detected property; save() needs a license removed = metadata.sanitize() print(f"Removed {removed} properties") metadata.save("./clean.docx") if __name__ == "__main__": remove_metadata() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/getting-started/quick-start-guide/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "clean.docx" >}} ```text Binary file (DOCX, 14 KB) ``` [Download full output](/metadata/python-net/_output_files/getting-started/quick-start-guide/remove_metadata/clean.docx) {{< /tab >}} {{< /tabs >}} ## Example 3: Inspect a document Read basic file information without parsing the whole metadata tree. {{< tabs "qs-document-info">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def document_info(): with Metadata("./input.docx") as metadata: # get_document_info() reads basic facts without walking the metadata tree info = metadata.get_document_info() print(f"Format: {info.file_type.file_format}") print(f"MIME type: {info.file_type.mime_type}") print(f"Pages: {info.page_count}") print(f"Size: {info.size} bytes") print(f"Encrypted: {info.is_encrypted}") if __name__ == "__main__": document_info() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/getting-started/quick-start-guide/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "document-info.txt" >}} ```text Format: 3 MIME type: application/vnd.openxmlformats-officedocument.wordprocessingml.document Pages: 1 Size: 17952 bytes Encrypted: False ``` [Download full output](/metadata/python-net/_output_files/getting-started/quick-start-guide/document_info/document-info.txt) {{< /tab >}} {{< /tabs >}} ## Next Steps After completing the basics, explore additional resources: - [Supported File Formats]({{< ref "/metadata/python-net/getting-started/supported-document-formats.md" >}}): review the full list of supported file types. - [Developer Guide]({{< ref "/metadata/python-net/developer-guide/_index.md" >}}): runnable examples for every API surface. - [Licensing]({{< ref "/metadata/python-net/getting-started/evaluation-limitations-and-licensing.md" >}}): details on licensing and evaluation. - [Technical Support]({{< ref "metadata/python-net/technical-support" >}}): contact support if you run into issues. --- ## Save a modified file to a specified location Path: /metadata/python-net/save-a-modified-file-to-a-specified-location/ This example shows how to save a modified file to a specified location on a local disk by passing an output path to the `save` method. {{< tabs "save-a-modified-file-to-a-specified-location">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def save_file_to_specified_location(): with Metadata("input.jpg") as metadata: # Edit or remove metadata here removed = metadata.sanitize() print(f"Removed {removed} properties") metadata.save("output.jpg") if __name__ == "__main__": save_file_to_specified_location() ``` {{< /tab >}} {{< tab "input.jpg" >}} {{< tab-text >}} `input.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-specified-location/input.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 795 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-specified-location/save_file_to_specified_location/output.jpg) {{< /tab >}} {{< /tabs >}} ## See also - [Save a modified file to a stream]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-stream.md" >}}) - [Saving files]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Supported File Formats Path: /metadata/python-net/supported-document-formats/ The following table contains a full list of file formats that are currently supported by GroupDocs.Metadata for Python via .NET | Format | Description | Load | Save | Remarks | | --- | --- | --- | --- | --- | | [ASF](https://docs.fileformat.com/video/asf/) | Advanced Systems FormatVideo | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [AVI](https://docs.fileformat.com/video/avi/) | Audio Video Interleave File | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [BMP](https://docs.fileformat.com/image/bmp/) | Bitmap Picture (BMP) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | BMP Specification v5 | | [CR2](https://docs.fileformat.com/image/crw/) | Digital photography RAW format created by Canon | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DAE](https://docs.fileformat.com/3d/dae/) | Dae File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DICOM](https://docs.fileformat.com/image/dcm/) | Digital Imaging and Communications in Medicine (DICOM) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DJVU](https://docs.fileformat.com/image/djvu/)/DJV | Deja Vu (DjVu) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Supported since version 3.0 | | [DNG](https://docs.fileformat.com/image/dng/) | Digital Negative Specification | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DOC](https://docs.fileformat.com/word-processing/doc/) | Microsoft Word 97 - 2007 Document. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | \*.doc versions starting from Microsoft Word 95 | | [DOCM](https://docs.fileformat.com/word-processing/docm/) | Office Open XML WordprocessingML Macro-Enabled Document. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DOCX](https://docs.fileformat.com/word-processing/docx/) | Office Open XML WordprocessingML Document (macro-free). | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DOT](https://docs.fileformat.com/word-processing/dot/) | Microsoft Word 97 - 2007 Template. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DOTX](https://docs.fileformat.com/word-processing/dotx/) | Office Open XML WordprocessingML Template (macro-free). | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DWG](https://docs.fileformat.com/cad/dwg/) | Autodesk Design Data Formats | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [DXF](https://docs.fileformat.com/cad/dxf/) | AutoCAD Drawing Interchange | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [EMF](https://docs.fileformat.com/image/emf/) | Windows Enhanced Metafile (EMF) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Revision 11.0 | | [EML](https://docs.fileformat.com/email/eml/) | Email Message Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [EPUB](https://docs.fileformat.com/ebook/epub/) | Saves the document in the IDPF EPUB format. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Versions 2.0, 3.0.1, 3.1 | | [FBX](https://docs.fileformat.com/3d/fbx/) | Fbx File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [FLV](https://docs.fileformat.com/video/flv/) | Flash Video File | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [GEOJSON](https://docs.fileformat.com/gis/geojson/) | GeoJson File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [GIF](https://docs.fileformat.com/image/gif/) | Graphics Interchange Format (GIF) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Supported since version 89a | | [GML](https://docs.fileformat.com/gis/gml/) | Gml File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [GPX](https://docs.fileformat.com/gis/gpx/) | Gpx File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [HEIF](https://docs.fileformat.com/image/heif/)/[HEIC](https://docs.fileformat.com/image/heic/) | High Efficiency Image File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [JP2](https://docs.fileformat.com/image/jp2/) | JPEG2000 Core Image File | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [JPG](https://docs.fileformat.com/image/jpeg) / [JPEG](https://docs.fileformat.com/image/jpeg) / JPE   | Joint Photographic Experts Group (JPEG) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Supported since version 1.02 | | [KML](https://docs.fileformat.com/gis/kml/) | Kml File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [MOV](https://docs.fileformat.com/video/mov/) / [QT](https://docs.fileformat.com/video/qt/) | Apple QuickTime Movie | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [MP3](https://docs.fileformat.com/audio/mp3/) | MPEG Audio Layer III | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [MPP](https://docs.fileformat.com/project-management/mpp/) | Microsoft Project Document | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [MSG](https://docs.fileformat.com/email/msg/) | Outlook Email Message Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [ODS](https://docs.fileformat.com/spreadsheet/ods/) | Open Document Spreadsheet | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [ODT](https://docs.fileformat.com/word-processing/odt/) | ODF Text Document. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [ONE](https://docs.fileformat.com/note-taking/one/) | Microsoft OneNote | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [OSM](https://docs.fileformat.com/gis/osm/) | Osm File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | OTC | OpenDocument Chart Template | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [OTF](https://docs.fileformat.com/font/otf/) | OpenType Font | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PDF](https://docs.fileformat.com/pdf/) | Saves the document as PDF (Adobe Portable Document) format. | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | \*.pdf versions starting from PDF version 1.2 | | [PNG](https://docs.fileformat.com/image/png/) | Portable Network Graphics (PNG) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Version 1.0 and later  | | [POTM](https://docs.fileformat.com/presentation/potm/) | OOXML Macro Enabled Presentation Template | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [POTX](https://docs.fileformat.com/presentation/potx/) | OOXML Presentation Template | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PPS](https://docs.fileformat.com/presentation/pps/) | PowerPoint SlideShow 97-2003 | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PPSM](https://docs.fileformat.com/presentation/ppsm/) | OOXML Macros Enabled Presentation | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PPSX](https://docs.fileformat.com/presentation/ppsx/) | OOXML SlideShow | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PPT](https://docs.fileformat.com/presentation/ppt/) | PowerPoint Presentation 97-2003 | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | \*.ppt versions starting from Microsoft PowerPoint 97 | | [PPTM](https://docs.fileformat.com/presentation/pptm/) | OOXML Macro Enabled Presentation | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PPTX](https://docs.fileformat.com/presentation/pptx/) | OOXML Presentation | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [PSD](https://docs.fileformat.com/image/psd/) | Adobe Photoshop Document (PSD) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Adobe Photoshop 2.0 and later | | [RAR](https://docs.fileformat.com/compression/rar/) | RAR Archive File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [SEVENZIP](https://docs.fileformat.com/compression/7z/) | 7z Archive File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [SHP](https://docs.fileformat.com/gis/shp/) | Shp File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [STL](https://docs.fileformat.com/3d/stl/) | Stl File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [TAR](https://docs.fileformat.com/compression/tar/) | TAR Archive File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [THREEDS](https://docs.fileformat.com/3d/3ds/) | 3DS File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [TIFF](https://docs.fileformat.com/image/tiff/) | Tagged Image File Format (TIFF) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Supported since version 6.0 | | TOPOJSON | TopoJson File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [TORRENT](https://docs.fileformat.com/misc/torrent/) | BitTorrent File | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [TTC](https://docs.fileformat.com/font/ttc/) | TrueType Font Collection | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [TTF](https://docs.fileformat.com/font/ttf/) | TrueType Font | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VCF](https://docs.fileformat.com/email/vcf/) | Electronic Business Card (vCard) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VCR](https://docs.fileformat.com/email/vcf/) | Electronic Business Card (vCard) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VDX](https://docs.fileformat.com/image/vdx/) | Microsoft Visio 2003-2010 XML Drawing | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VSD](https://docs.fileformat.com/image/vsd/) | Microsoft Visio 2003-2010 Drawing | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VSDX](https://docs.fileformat.com/image/vsdx/) | Microsoft Visio Drawing | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VSS](https://docs.fileformat.com/image/vss/) | Microsoft Visio 2003-2010 Stencil | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [VSX](https://docs.fileformat.com/image/vsx/) | Microsoft Visio 2003-2010 XML Stencil | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [WAV](https://docs.fileformat.com/audio/wav/) | Waveform Audio File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [WEBP](https://docs.fileformat.com/image/webp/) | WebP Image | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [WMF](https://docs.fileformat.com/image/wmf/) | Windows Metafile (WMF) | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Revision 13.0 | | [XLS](https://docs.fileformat.com/spreadsheet/xls/) | Excel Workbook 97-2003 | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | \*.xls versions starting from Microsoft Excel 95 | | [XLSM](https://docs.fileformat.com/spreadsheet/xlsm/) | OOXML Macro Enabled Workbook | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [XLSX](https://docs.fileformat.com/spreadsheet/xlsx/) | OOXML 2007-2010 | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [XLTM](https://docs.fileformat.com/spreadsheet/xltm/) | OOXML Macro Enabled Workbook Template | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) |   | | [ZIP](https://docs.fileformat.com/compression/zip/) | Archive File Format | ![(tick)](/metadata/net/images/check.png) | ![(tick)](/metadata/net/images/check.png) | Supported since version 6.3.4 | {{< alert style="tip" >}} **Can’t find your file format?** We’re here to help! Please post a request on our [Free Support Forum](https://forum.groupdocs.com/c/metadata/14), and our team will assist you. {{< /alert >}} --- ## Working with IPTC IIM metadata Path: /metadata/python-net/working-with-iptc-iim-metadata/ ## What is IPTC IIM? The IPTC Information Interchange Model (IIM) is a set of metadata properties that can be applied to text, images, and other media. The standard also defines a data structure used to store the properties. IPTC IIM was developed by the International Press Telecommunications Council (IPTC) to speed up the international exchange of news, and is now also commonly used by photographers. IPTC IIM metadata can be embedded into a variety of image formats such as JPEG and TIFF. {{< alert style="info" >}}For more information on the IPTC IIM standard please refer to https://www.iptc.org/std/IIM/4.2/specification/IIMV4.2.pdf.{{< /alert >}} ## Reading basic IPTC IIM properties To access IPTC metadata in a file of any supported format, GroupDocs.Metadata provides the `iptc_package` property on the root package, which exposes `envelope_record` and `application_record`. {{< tabs "iptc-read-basic">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def read_basic_iptc_properties(): with Metadata("iptc.jpg") as metadata: root = metadata.get_root_package() iptc = getattr(root, "iptc_package", None) if iptc is not None: # The envelope record carries transmission-level fields if iptc.envelope_record is not None: print(iptc.envelope_record.date_sent) print(iptc.envelope_record.destination) print(iptc.envelope_record.file_format) # The application record carries the editorial fields if iptc.application_record is not None: print(iptc.application_record.headline) print(iptc.application_record.by_line) print(iptc.application_record.caption_abstract) print(iptc.application_record.city) print(iptc.application_record.date_created) if __name__ == "__main__": read_basic_iptc_properties() ``` {{< /tab >}} {{< tab "iptc.jpg" >}} {{< tab-text >}} `iptc.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/iptc.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-basic-iptc-properties.txt" >}} ```text 2019-09-21 00:00:00 None 8 test None None None 2019-09-18 00:00:00 ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/read_basic_iptc_properties/read-basic-iptc-properties.txt) {{< /tab >}} {{< /tabs >}} ## Reading all IPTC IIM datasets The API provides direct access to the IPTC datasets extracted from a file, including custom ones. {{< tabs "iptc-read-datasets">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def read_iptc_datasets(): with Metadata("iptc.psd") as metadata: root = metadata.get_root_package() iptc = getattr(root, "iptc_package", None) if iptc is not None: # to_data_set_list() returns every raw IPTC dataset for dataset in iptc.to_data_set_list(): print(dataset.record_number) # record (e.g. 1=envelope, 2=application) print(dataset.data_set_number) # dataset id within the record print(dataset.alternative_name) # human-readable name print(dataset.value.raw_value) # underlying value if __name__ == "__main__": read_iptc_datasets() ``` {{< /tab >}} {{< tab "iptc.psd" >}} {{< tab-text >}} `iptc.psd` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/iptc.psd) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-iptc-datasets.txt" >}} ```text 1 90 CodedCharacterSet GroupDocs.Metadata.Common.PropertyValue[] 2 0 RecordVersion 32 2 55 [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/read_iptc_datasets/read-iptc-datasets.txt) {{< /tab >}} {{< /tabs >}} ## Updating IPTC IIM properties Update IPTC metadata using the `IptcRecordSet` properties. Create the records if they are missing. {{< tabs "iptc-update">}} {{< tab "Python" >}} ```python import uuid from datetime import date, datetime from groupdocs.metadata import Metadata from groupdocs.metadata.standards.iptc import IptcApplicationRecord, IptcEnvelopeRecord, IptcRecordSet def update_iptc_properties(): with Metadata("input.jpg") as metadata: root = metadata.get_root_package() # Create the IPTC record set if the image has none if getattr(root, "iptc_package", None) is None: root.iptc_package = IptcRecordSet() # Fill the envelope record (create it first if missing) if root.iptc_package.envelope_record is None: root.iptc_package.envelope_record = IptcEnvelopeRecord() root.iptc_package.envelope_record.date_sent = datetime.now() root.iptc_package.envelope_record.product_id = str(uuid.uuid4()) # Fill the application record (create it first if missing) if root.iptc_package.application_record is None: root.iptc_package.application_record = IptcApplicationRecord() root.iptc_package.application_record.by_line = "GroupDocs" root.iptc_package.application_record.headline = "test" root.iptc_package.application_record.by_line_title = "code sample" root.iptc_package.application_record.release_date = date.today() # Persist the changes metadata.save("output.jpg") if __name__ == "__main__": update_iptc_properties() ``` {{< /tab >}} {{< tab "input.jpg" >}} {{< tab-text >}} `input.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/input.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 885 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/update_iptc_properties/output.jpg) {{< /tab >}} {{< /tabs >}} ## Adding or updating custom IPTC IIM datasets The API allows adding or updating custom datasets in an IPTC package. {{< tabs "iptc-set-custom">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.standards.iptc import ( IptcApplicationRecordDataSet, IptcDataSet, IptcRecordSet, IptcRecordType, ) def set_custom_iptc_dataset(): with Metadata("iptc.psd") as metadata: root = metadata.get_root_package() if getattr(root, "iptc_package", None) is None: root.iptc_package = IptcRecordSet() # Add a known property using the DataSet API root.iptc_package.set(IptcDataSet( int(IptcRecordType.APPLICATION_RECORD), int(IptcApplicationRecordDataSet.BYLINE_TITLE), "test code sample", )) # Add a fully custom IPTC DataSet root.iptc_package.set(IptcDataSet(255, 255, bytes([1, 2, 3]))) metadata.save("output.psd") if __name__ == "__main__": set_custom_iptc_dataset() ``` {{< /tab >}} {{< tab "iptc.psd" >}} {{< tab-text >}} `iptc.psd` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/iptc.psd) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.psd" >}} ```text Binary file (PSD, 19.5 MB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/set_custom_iptc_dataset/output.psd) {{< /tab >}} {{< /tabs >}} ## Removing IPTC IIM metadata To remove the IPTC package from a file, assign `None` to the `iptc_package` property. {{< tabs "iptc-remove">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def remove_iptc_metadata(): with Metadata("iptc.jpg") as metadata: root = metadata.get_root_package() # Assigning None drops the entire IPTC package root.iptc_package = None metadata.save("output.jpg") if __name__ == "__main__": remove_iptc_metadata() ``` {{< /tab >}} {{< tab "iptc.jpg" >}} {{< tab-text >}} `iptc.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/iptc.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 948 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata/remove_iptc_metadata/output.jpg) {{< /tab >}} {{< /tabs >}} ## See also - [Working with EXIF metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata.md" >}}) - [Working with XMP metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata.md" >}}) - [Working with metadata standards]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Load a file of a specific format Path: /metadata/python-net/load-a-file-of-a-specific-format/ This example demonstrates how to load a file of a particular format. Explicitly specifying the format through `LoadOptions` can spare the time spent on automatic format detection. {{< tabs "load-a-file-of-a-specific-format">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.common import FileFormat from groupdocs.metadata.options import LoadOptions def loading_file_of_specific_format(): load_options = LoadOptions(FileFormat.SPREADSHEET) with Metadata("input.xlsx", load_options) as metadata: root = metadata.get_root_package() # Use format-specific properties to extract or edit metadata print(f"Author: {root.document_properties.author}") if __name__ == "__main__": loading_file_of_specific_format() ``` {{< /tab >}} {{< tab "input.xlsx" >}} {{< tab-text >}} `input.xlsx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/loading-files/load-a-file-of-a-specific-format/input.xlsx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "loading-file-of-specific-format.txt" >}} ```text Author: gena ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/loading-files/load-a-file-of-a-specific-format/loading_file_of_specific_format/loading-file-of-specific-format.txt) {{< /tab >}} {{< /tabs >}} ## See also - [Load a password-protected document]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-password-protected-document.md" >}}) - [Loading files]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Remove metadata properties Path: /metadata/python-net/remove-metadata-properties/ ## Remove metadata properties using various criteria The easiest way to remove metadata properties from a file is to use the corresponding tags that let you locate the desired properties across all metadata packages. But sometimes it's necessary to remove metadata entries that have a particular value. With a Python predicate you can find and remove properties that satisfy a condition as complex as you need. The following example demonstrates how to remove specific metadata properties using a combination of criteria. 1. **Load** a file to update 2. Pass a predicate to the **remove_properties** method to find and remove the desired properties 3. Check the number of properties that were actually removed (the return value of **remove_properties**) 4. **Save** the changes {{< tabs "remove-metadata-properties">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.common import MetadataPropertyType from groupdocs.metadata.tagging import Tags def remove_metadata_properties(): # Remove all the properties satisfying the predicate: # the property carries the "author" tag, OR # the property carries the "last editor" tag, OR # the property is a string whose value equals "John" # (to wipe any mention of John from the detected metadata) with Metadata("input.docx") as metadata: affected = metadata.remove_properties( lambda p: Tags.person.creator in list(p.tags) or Tags.person.editor in list(p.tags) or (p.value.type == MetadataPropertyType.STRING and str(p.value) == "John") ) print(f"Properties removed: {affected}") metadata.save("output.docx") if __name__ == "__main__": remove_metadata_properties() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/basic-usage/remove-metadata-properties/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.docx" >}} ```text Binary file (DOCX, 14 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/basic-usage/remove-metadata-properties/remove_metadata_properties/output.docx) {{< /tab >}} {{< /tabs >}} As a result of running the code snippet above, we remove all mentions of the document author/editor and all other string metadata properties whose value is "John". For more information on searching metadata, please refer to the following articles: * [Extracting metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) * [Removing metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/removing-metadata.md" >}}) * [Adding metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/adding-metadata.md" >}}) ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Removing metadata Path: /metadata/python-net/removing-metadata/ Not all metadata properties extracted from a file are marked with tags. Some file formats and metadata standards allow fully custom properties that can't be tagged by the library, because their purpose is not clearly defined in the corresponding specification. In such cases you can use the property name (or any other attribute) to locate and remove it. The following example demonstrates an advanced removal scenario. 1. **Load** a file to modify 2. Pass a search predicate to the **remove_properties** method 3. Check the number of properties that were actually removed 4. **Save** the changes {{< tabs "removing-metadata">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.tagging import Tags def removing_metadata(): with Metadata("input.docx") as metadata: # Remove every property whose tags fall into the "content" category affected = metadata.remove_properties( lambda p: any(tag.category == Tags.content for tag in p.tags) ) print(f"Affected properties: {affected}") metadata.save("output.docx") if __name__ == "__main__": removing_metadata() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/removing-metadata/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.docx" >}} ```text Binary file (DOCX, 13 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/removing-metadata/removing_metadata/output.docx) {{< /tab >}} {{< /tabs >}} ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Save a modified file to a stream Path: /metadata/python-net/save-a-modified-file-to-a-stream/ This example shows how to save a modified file to a stream. Pass any writable binary file-like object (for example an `io.BytesIO`) to the `save` method; the wrapper writes the result into it. {{< tabs "save-a-modified-file-to-a-stream">}} {{< tab "Python" >}} ```python import io from groupdocs.metadata import Metadata def save_file_to_specified_stream(): stream = io.BytesIO() with Metadata("input.png") as metadata: # Edit or remove metadata here metadata.sanitize() metadata.save(stream) print(f"Saved {stream.getbuffer().nbytes} bytes to the stream") if __name__ == "__main__": save_file_to_specified_stream() ``` {{< /tab >}} {{< tab "input.png" >}} {{< tab-text >}} `input.png` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-stream/input.png) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "save-file-to-specified-stream.txt" >}} ```text Saved 51759 bytes to the stream ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-stream/save_file_to_specified_stream/save-file-to-specified-stream.txt) {{< /tab >}} {{< /tabs >}} ## See also - [Save a modified file to a specified location]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/save-a-modified-file-to-a-specified-location.md" >}}) - [Saving files]({{< ref "metadata/python-net/developer-guide/advanced-usage/saving-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## System Requirements Path: /metadata/python-net/system-requirements/ ## Overview GroupDocs.Metadata for Python via .NET does not require any external software or third party tools to be installed. ## General Requirements - [Python](https://www.python.org/downloads/) versions **3.5–3.14** are supported ## Supported Operating Systems ### Windows * Microsoft Windows 11 (x64) * Microsoft Windows 10 (x64, x86) * Microsoft Windows 7, 8, 8.1, Vista, XP (x64, x86) * Microsoft Windows Server 2003 and later ### Linux and macOS (partial support) GroupDocs.Metadata include macOS support for Intel and/or Apple Silicon (M-series) processors and Linux support. ## Additional System Libraries ### Linux and macOS System Requirements * macOS-x86_64: 10.14 or later * macOS-arm64: 11.0 or later GroupDocs.Metadata for Python via .NET relies on `libgdiplus` for processing images or documents that contain images. #### Linux installation When using GroupDocs.Metadata in a Linux environment, the following packages should be installed for proper library operation: 1. **libgdiplus** - Mono library providing a GDI+-compatible API on non-Windows operating systems. 2. **libx11-dev** - Required for drawing functions (image/font rendering). 3. **fontconfig** - Enables font lookup for text rendering with System.Drawing. 4. **ttf-mscorefonts-installer** - Provides Microsoft-compatible fonts required by GroupDocs.Total. To install packages on Debian-based Linux distributions, use [apt-get](https://wiki.debian.org/apt-get): ```bash sudo apt-get update sudo apt-get install -y libgdiplus libx11-dev fontconfig ttf-mscorefonts-installer ``` If some packages are not available, you can add the contrib repository: ```bash RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list ``` #### macOS installation The library is required and can be installed using the [Homebrew](https://brew.sh/) package manager: ```ps brew install mono-libgdiplus ``` Ensure `libgdiplus` is installed if you encounter issues with processing images or documents that contain images. --- ## Working with XMP metadata Path: /metadata/python-net/working-with-xmp-metadata/ ## What is XMP? The Extensible Metadata Platform (XMP) is an XML-based ISO metadata standard, originally created by Adobe Systems. It defines a data structure, a serialization model, and basic metadata properties that form a unified metadata package which can be embedded into different media formats. The XMP data model can store any set of metadata properties — simple name/value pairs, structured values, or lists of values, nested arbitrarily. {{< alert style="info" >}}Find more information on the XMP standard at https://en.wikipedia.org/wiki/Extensible_Metadata_Platform{{< /alert >}} ## Reading XMP properties To access XMP metadata in a file of any supported format, GroupDocs.Metadata provides the `xmp_package` property on the root package. Standard schemes are reachable through `xmp_package.schemes`. {{< tabs "xmp-read">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def read_xmp_properties(): with Metadata("xmp.png") as metadata: root = metadata.get_root_package() xmp = getattr(root, "xmp_package", None) if xmp is not None: # Standard schemes are reachable through xmp.schemes; # each may be absent, so guard before reading. if xmp.schemes.xmp_basic is not None: print(xmp.schemes.xmp_basic.creator_tool) print(xmp.schemes.xmp_basic.create_date) print(xmp.schemes.xmp_basic.modify_date) if xmp.schemes.dublin_core is not None: print(xmp.schemes.dublin_core.format) print(xmp.schemes.dublin_core.coverage) print(xmp.schemes.dublin_core.identifier) if xmp.schemes.photoshop is not None: print(xmp.schemes.photoshop.color_mode) print(xmp.schemes.photoshop.city) print(xmp.schemes.photoshop.date_created) if __name__ == "__main__": read_xmp_properties() ``` {{< /tab >}} {{< tab "xmp.png" >}} {{< tab-text >}} `xmp.png` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/xmp.png) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "read-xmp-properties.txt" >}} ```text Adobe Photoshop CC 2017 (Windows) 2018-09-05 07:28:22+03:00 2018-09-05 07:37:28+03:00 image/png None None 3 None None ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/read_xmp_properties/read-xmp-properties.txt) {{< /tab >}} {{< /tabs >}} Here is a non-exhaustive list of supported XMP schemes (in `groupdocs.metadata.standards.xmp.schemes`): `XmpBasicJobTicketPackage`, `XmpBasicPackage`, `XmpCameraRawPackage`, `XmpDublinCorePackage`, `XmpDynamicMediaPackage`, `XmpIptcCorePackage`, `XmpIptcExtensionPackage`, `XmpIptcIimPackage`, `XmpMediaManagementPackage`, `XmpPagedTextPackage`, `XmpPdfPackage`, `XmpPhotoshopPackage`, `XmpRightsManagementPackage`. ## Updating XMP properties Update XMP metadata through the scheme packages. Create a scheme if it is missing. {{< tabs "xmp-update">}} {{< tab "Python" >}} ```python from datetime import date from groupdocs.metadata import Metadata from groupdocs.metadata.standards.xmp.schemes import XmpBasicPackage, XmpCameraRawPackage, XmpDublinCorePackage def update_xmp_properties(): with Metadata("xmp.gif") as metadata: root = metadata.get_root_package() xmp = getattr(root, "xmp_package", None) if xmp is not None: if xmp.schemes.dublin_core is None: xmp.schemes.dublin_core = XmpDublinCorePackage() xmp.schemes.dublin_core.format = "image/gif" if xmp.schemes.camera_raw is None: xmp.schemes.camera_raw = XmpCameraRawPackage() xmp.schemes.camera_raw.shadows = 50 xmp.schemes.camera_raw.camera_profile = "test" # Replace the whole scheme to drop old values xmp.schemes.xmp_basic = XmpBasicPackage() xmp.schemes.xmp_basic.create_date = date.today() xmp.schemes.xmp_basic.rating = 5 metadata.save("output.gif") if __name__ == "__main__": update_xmp_properties() ``` {{< /tab >}} {{< tab "xmp.gif" >}} {{< tab-text >}} `xmp.gif` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/xmp.gif) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.gif" >}} ```text Binary file (GIF, 150 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/update_xmp_properties/output.gif) {{< /tab >}} {{< /tabs >}} ## Adding a custom XMP package Besides the predefined schemes, you can create fully custom XMP packages with user-defined properties. {{< tabs "xmp-add-custom">}} {{< tab "Python" >}} ```python from datetime import date from groupdocs.metadata import Metadata from groupdocs.metadata.standards.xmp import XmpArray, XmpArrayType, XmpPackage, XmpPacketWrapper def add_custom_xmp_package(): with Metadata("input.jpg") as metadata: root = metadata.get_root_package() packet = XmpPacketWrapper() custom = XmpPackage("gd", "https://groupdocs.com") custom.set("gd:Copyright", "Copyright (C) 2026 GroupDocs. All Rights Reserved.") custom.set("gd:CreationDate", date.today()) custom.set("gd:Company", XmpArray.from_(["Aspose", "GroupDocs"], XmpArrayType.ORDERED)) packet.add_package(custom) root.xmp_package = packet metadata.save("output.jpg") if __name__ == "__main__": add_custom_xmp_package() ``` {{< /tab >}} {{< tab "input.jpg" >}} {{< tab-text >}} `input.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/input.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 885 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/add_custom_xmp_package/output.jpg) {{< /tab >}} {{< /tabs >}} ## Removing XMP metadata To remove the XMP package from a file, assign `None` to the `xmp_package` property. {{< tabs "xmp-remove">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def remove_xmp_metadata(): with Metadata("xmp.jpg") as metadata: root = metadata.get_root_package() # Assigning None drops the entire XMP packet root.xmp_package = None metadata.save("output.jpg") if __name__ == "__main__": remove_xmp_metadata() ``` {{< /tab >}} {{< tab "xmp.jpg" >}} {{< tab-text >}} `xmp.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/xmp.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.jpg" >}} ```text Binary file (JPG, 174 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-metadata-standards/working-with-xmp-metadata/remove_xmp_metadata/output.jpg) {{< /tab >}} {{< /tabs >}} ## See also - [Working with EXIF metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-exif-metadata.md" >}}) - [Working with IPTC IIM metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/working-with-iptc-iim-metadata.md" >}}) - [Working with metadata standards]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-metadata-standards/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Installation Path: /metadata/python-net/installation/ GroupDocs.Metadata for Python via .NET is distributed as a self-contained wheel that bundles the embedded .NET runtime, so **no additional software is required**. A single `py3-none-{platform}` wheel works across Python **3.5 – 3.14** on Windows, Linux, and macOS (Intel and Apple Silicon). {{< alert style="info" >}} Before you install, review the [System Requirements]({{< ref "/metadata/python-net/getting-started/system-requirements.md" >}}). On Linux and macOS, image and document-image processing additionally needs the `libgdiplus` native library — see the system-requirements page for the exact packages. {{< /alert >}} ## Install Package from PyPI All packages are hosted at [PyPI](https://pypi.org/project/groupdocs-metadata-net/). Install the latest version with `pip`: {{< tabs "install-from-pypi">}} {{< tab "Windows" >}} ```ps py -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m pip install groupdocs-metadata-net ``` {{< /tab >}} {{< /tabs >}} To upgrade an existing installation to the newest release, add the `--upgrade` flag: ```bash python3 -m pip install --upgrade groupdocs-metadata-net ``` {{< alert style="info" >}} Using a [virtual environment](https://docs.python.org/3/library/venv.html) is recommended so the package and its dependencies stay isolated from your system Python. See the [Quick Start Guide]({{< ref "/metadata/python-net/getting-started/quick-start-guide.md" >}}) for the `venv` setup steps. {{< /alert >}} ## Add the Package to `requirements.txt` For reproducible builds, pin the version in your project's `requirements.txt`: ```text groupdocs-metadata-net==26.5 ``` Then install every dependency at once: ```bash python3 -m pip install -r requirements.txt ``` ## Install from a Pre-Downloaded Wheel In environments without access to PyPI (for example, an air-gapped CI runner or a locked-down server), download the wheel for your platform and install it from a local file. Download the wheel that matches your operating system and CPU architecture from the [GroupDocs.Metadata releases](https://releases.groupdocs.com/metadata/python-net/) page: | Platform | Wheel file name ends with | | --- | --- | | Windows 64-bit | `py3-none-win_amd64.whl` | | Linux x64 (glibc) | `py3-none-manylinux1_x86_64.whl` | | macOS Apple Silicon (M-series) | `py3-none-macosx_11_0_arm64.whl` | | macOS Intel | `py3-none-macosx_10_14_x86_64.whl` | Install the downloaded file with `pip` (replace the file name with the wheel you downloaded): {{< tabs "install-from-wheel">}} {{< tab "Windows" >}} ```ps py -m pip install .\groupdocs_metadata_net-26.5-py3-none-win_amd64.whl ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m pip install ./groupdocs_metadata_net-26.5-py3-none-manylinux1_x86_64.whl ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m pip install ./groupdocs_metadata_net-26.5-py3-none-macosx_11_0_arm64.whl ``` {{< /tab >}} {{< /tabs >}} ## Verify the Installation Confirm the package is installed and importable: ```bash python3 -c "from groupdocs.metadata import Metadata; print('GroupDocs.Metadata is ready')" ``` You can also check the installed version with `pip`: ```bash python3 -m pip show groupdocs-metadata-net ``` ## Next Steps - Follow the [Quick Start Guide]({{< ref "/metadata/python-net/getting-started/quick-start-guide.md" >}}) to read and remove metadata in a few minutes. - Clone the [examples repository](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET) and read [How to Run Examples]({{< ref "/metadata/python-net/getting-started/how-to-run-examples.md" >}}). - If you work with AI agents or LLMs, see [Agents and LLM Integration]({{< ref "/metadata/python-net/agents-and-llm-integration.md" >}}) for MCP and `AGENTS.md` details. --- ## Load a password-protected document Path: /metadata/python-net/load-a-password-protected-document/ This example demonstrates how to load a password-protected document. Provide the password through `LoadOptions`. If the password is wrong, a `DocumentProtectedException` is raised. {{< tabs "load-a-password-protected-document">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata from groupdocs.metadata.options import LoadOptions def load_password_protected_document(): # Specify the password load_options = LoadOptions() load_options.password = "123" with Metadata("protected.docx", load_options) as metadata: # Extract, edit or remove metadata here print(f"Opened protected {metadata.file_format} document") if __name__ == "__main__": load_password_protected_document() ``` {{< /tab >}} {{< tab "protected.docx" >}} {{< tab-text >}} `protected.docx` is the sample file used in this example (password: `123`). Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/loading-files/load-a-password-protected-document/protected.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "load-password-protected-document.txt" >}} ```text Opened protected 3 document ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/loading-files/load-a-password-protected-document/load_password_protected_document/load-password-protected-document.txt) {{< /tab >}} {{< /tabs >}} ## See also - [Load a file of a specific format]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/load-a-file-of-a-specific-format.md" >}}) - [Loading files]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Set metadata properties Path: /metadata/python-net/set-metadata-properties/ ## Update or add metadata properties satisfying a predicate The **set_properties** method combines two operations: add and update. If an existing property satisfies the specified predicate, its value is updated. If a known property that satisfies the predicate is missing from a metadata package, it is added to the appropriate package. The code snippet below demonstrates a basic usage scenario of the **set_properties** method. 1. **Open** a file to update 2. Specify a predicate that selects the metadata properties to add/update 3. Specify the value you would like to write 4. Check the actual number of added/updated properties 5. **Save** the changes {{< tabs "set-metadata-properties">}} {{< tab "Python" >}} ```python from datetime import datetime from groupdocs.metadata import Metadata from groupdocs.metadata.common import PropertyValue from groupdocs.metadata.tagging import Tags def set_metadata_properties(): with Metadata("input.vsdx") as metadata: # The value to write into every matching property property_value = PropertyValue(datetime.now()) # set_properties = add-or-update: the predicate selects the # "created" and "modified" date/time properties across all packages affected = metadata.set_properties( lambda p: Tags.time.created in list(p.tags) or Tags.time.modified in list(p.tags), property_value, ) print(f"Properties set: {affected}") # Persist the changes to a new file metadata.save("output.vsdx") if __name__ == "__main__": set_metadata_properties() ``` {{< /tab >}} {{< tab "input.vsdx" >}} {{< tab-text >}} `input.vsdx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/basic-usage/set-metadata-properties/input.vsdx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.vsdx" >}} ```text Binary file (VSDX, 35 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/basic-usage/set-metadata-properties/set_metadata_properties/output.vsdx) {{< /tab >}} {{< /tabs >}} As a result, we update all existing metadata properties that hold the date the document was created/updated. If a metadata package doesn't contain such properties but they belong in its structure, they are added. For more information on searching metadata, please refer to the following articles: * [Extracting metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) * [Removing metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/removing-metadata.md" >}}) * [Adding metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/adding-metadata.md" >}}) ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Adding metadata Path: /metadata/python-net/adding-metadata/ Adding metadata properties is one of the most powerful features of the GroupDocs.Metadata search engine. When you call the **add_properties** method, it examines all available metadata packages and tries to pick up a known property that satisfies the specified predicate. Note that a property is added only to packages that fit the following criteria: 1. Only existing metadata packages are affected. No new packages are created during this operation. 2. There must be a known metadata property that fits the search condition but is actually missing from the package. The properties supported by a package are usually defined in the specification of the corresponding metadata standard. {{< tabs "adding-metadata">}} {{< tab "Python" >}} ```python from datetime import datetime from groupdocs.metadata import Metadata from groupdocs.metadata.common import PropertyValue from groupdocs.metadata.tagging import Tags def adding_metadata(): with Metadata("input.docx") as metadata: # Add the "last printed" date wherever it is a known but missing property property_value = PropertyValue(datetime.now()) affected = metadata.add_properties( lambda p: Tags.time.printed in list(p.tags), property_value ) print(f"Affected properties: {affected}") metadata.save("output.docx") if __name__ == "__main__": adding_metadata() ``` {{< /tab >}} {{< tab "input.docx" >}} {{< tab-text >}} `input.docx` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/adding-metadata/input.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.docx" >}} ```text Binary file (DOCX, 14 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/adding-metadata/adding_metadata/output.docx) {{< /tab >}} {{< /tabs >}} ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Clean metadata Path: /metadata/python-net/clean-metadata/ ## Remove all recognized metadata properties from a file Sometimes you just need to remove all metadata properties without applying any filters. The best way to do this is the **sanitize** method. This example demonstrates how to remove all detected metadata packages/properties. 1. **Load** a file to clean 2. Call the **sanitize** method 3. Check the actual number of removed packages/properties 4. **Save** the changes {{< tabs "clean-metadata">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def clean_metadata(): # Open the file to clean with Metadata("input.pdf") as metadata: # sanitize() removes every detected metadata property in one call affected = metadata.sanitize() print(f"Properties removed: {affected}") # Write the cleaned document to a new file metadata.save("output.pdf") if __name__ == "__main__": clean_metadata() ``` {{< /tab >}} {{< tab "input.pdf" >}} {{< tab-text >}} `input.pdf` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/basic-usage/clean-metadata/input.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "output.pdf" >}} ```text Binary file (PDF, 382 KB) ``` [Download full output](/metadata/python-net/_output_files/developer-guide/basic-usage/clean-metadata/clean_metadata/output.pdf) {{< /tab >}} {{< /tabs >}} As a result, we get a sanitized version of the original file. ## More resources ### Advanced usage topics To learn more about library features and get familiar how to manage metadata and more, please refer to the [advanced usage section]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}). ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Evaluation Limitations and Licensing Path: /metadata/python-net/evaluation-limitations-and-licensing/ To study the API quickly, GroupDocs.Metadata offers a Free Trial and a 30-day Temporary License for evaluation, along with several purchase plans. {{< alert style="info" >}}GroupDocs.Metadata also works without a license in trial mode, with certain limitations.{{< /alert >}} ## Purchased License After buying, apply the license file or include it as an embedded resource. The license needs to be set: - Only once per application - Before using any other GroupDocs.Metadata classes ## Evaluation version limitations The evaluation download is identical to the purchased one — it simply becomes licensed when you apply a license. Without a license you will face the following limitations: | API | Limitation | | --- | --- | | Document properties (PDF, Word, Excel, PowerPoint, Visio, etc.) | Only the first 5 properties can be read | | XMP API | Only the first 2 XMP schemes can be read | | EXIF API | GPS IFD and image thumbnail are unavailable; only the first 5 properties can be read | | IPTC API | Only the first 5 properties can be read | | ID3v2, Lyrics3, APEv2 tags | Only the first 5 properties can be read | | QuickTime atoms | Only the first 5 atoms can be read | | File open | A maximum of 15 files can be opened, otherwise the API throws an exception | | File save | **Not supported in trial mode** — `save()` raises an "Evaluation only" exception | ## Licensing The license file contains details such as the product name, the number of developers it is licensed to, and the subscription expiry date. It carries a digital signature, so don't modify the file — even an inadvertent extra line break will invalidate it. Set a license before using the API to avoid the evaluation limitations. The license can be loaded from a file or from a stream. ### Applying license from a file {{< tabs "set-license-from-file">}} {{< tab "Python" >}} ```python import os from groupdocs.metadata import License def set_license_from_file(): # Resolve the license path relative to the current working directory license_path = os.path.abspath("./GroupDocs.Metadata.lic") if os.path.exists(license_path): # Apply the license once, before using any other Metadata API license = License() license.set_license(license_path) print("License set successfully.") else: print("License file not found; running in evaluation mode.") if __name__ == "__main__": set_license_from_file() ``` {{< /tab >}} {{< /tabs >}} ### Applying license from a stream {{< tabs "set-license-from-stream">}} {{< tab "Python" >}} ```python import os from groupdocs.metadata import License def set_license_from_stream(): license_path = os.path.abspath("./GroupDocs.Metadata.lic") if os.path.exists(license_path): # set_license also accepts a readable binary stream with open(license_path, "rb") as stream: License().set_license(stream) print("License set successfully.") else: print("License file not found; running in evaluation mode.") if __name__ == "__main__": set_license_from_stream() ``` {{< /tab >}} {{< /tabs >}} ### Applying a Metered License {{< alert style="info" >}} You can also set a [Metered](https://reference.groupdocs.com/metadata/python-net/) license as an alternative to a license file. It is a licensing mechanism that bills based on usage. For more details, please refer to the [Metered Licensing FAQ](https://purchase.groupdocs.com/faqs/licensing/metered). {{< /alert >}} The simple steps to use the `Metered` class: 1. Create an instance of the `Metered` class. 2. Pass the public and private keys to the `set_metered_key` method. 3. Perform your processing. 4. Call `Metered.get_consumption_quantity()` to get the amount of API requests consumed so far. 5. Call `Metered.get_consumption_credit()` to get the credit consumed so far. {{< tabs "set-metered-license">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metered def set_metered_license(): public_key = "*****" # Your public key private_key = "*****" # Your private key # Guard the sample so it doesn't call the API with placeholder keys if "*" in public_key or "*" in private_key: print("Provide your real metered keys to activate metered licensing.") return # Activate metered (pay-as-you-go) billing for this process Metered().set_metered_key(public_key, private_key) print("Metered license set successfully.") if __name__ == "__main__": set_metered_license() ``` {{< /tab >}} {{< /tabs >}} {{< alert style="info" >}} Calling `License.set_license` multiple times is not harmful but simply wastes processor time. Call it once when the application starts. {{< /alert >}} --- ## How to Run Examples Path: /metadata/python-net/how-to-run-examples/ Every code example shown on this documentation site lives in a standalone, runnable form in the [GroupDocs.Metadata-for-Python-via-.NET](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET) repository on GitHub. Each example ships with its input sample files, so you can clone the repo and run anything with a single command. ## Prerequisites Before running the examples, make sure you have: 1. **A supported platform and Python version** — see [System Requirements]({{< ref "/metadata/python-net/getting-started/system-requirements.md" >}}). Windows, Linux, and macOS (Intel and Apple Silicon) are all supported. 2. **Git** — or download the repository as a ZIP from GitHub. 3. **A license file** (optional but recommended) — without one, the library runs in evaluation mode (only the first few properties of each package are read and `save()` raises an "Evaluation only" exception). See [Licensing]({{< ref "/metadata/python-net/getting-started/evaluation-limitations-and-licensing.md" >}}) for how to obtain a free temporary license. ## Get the Code Clone the repository and navigate into it: ```bash git clone https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET.git cd GroupDocs.Metadata-for-Python-via-.NET ``` ## Project Structure The repository mirrors this documentation tree. Every documentation page maps to a folder under `Examples/`, and every tabbed code block on a page maps to a `.py` file inside that folder. Input sample files live next to the script that reads them. ```md 📂 GroupDocs.Metadata-for-Python-via-.NET ├── README.md ├── LICENSE ├── AGENTS.md ← extracted from the pip package for AI tools ├── Dockerfile ← runs the whole suite on Linux ├── .github/workflows/run-examples.yml ← CI: runs all examples on every push └── Examples ├── requirements.txt ├── run_all_examples.py ├── getting-started │ └── quick-start-guide │ ├── read_metadata.py │ ├── remove_metadata.py │ ├── document_info.py │ └── input.docx ├── developer-guide │ ├── basic-usage │ │ ├── get-document-info/ │ │ ├── find-metadata-properties/ │ │ ├── set-metadata-properties/ │ │ ├── remove-metadata-properties/ │ │ └── clean-metadata/ │ └── advanced-usage │ ├── adding-metadata/ │ ├── extracting-metadata/ │ ├── removing-metadata/ │ ├── getting-known-property-descriptors/ │ ├── working-with-interpreted-values/ │ ├── loading-files/ (local disk, stream, specific format, password) │ ├── saving-files/ (location, stream, original source) │ ├── working-with-metadata-properties/ (export, extract property values) │ └── working-with-metadata-standards/ (EXIF, IPTC IIM, XMP) └── licensing ├── set_license_from_file.py ├── set_license_from_stream.py └── set_metered_license.py ``` ## Setup 1. **Create and activate a virtual environment**: Create: {{< tabs "venv-create">}} {{< tab "Windows" >}} ```ps py -m venv .venv ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m venv .venv ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m venv .venv ``` {{< /tab >}} {{< /tabs >}} Activate: {{< tabs "venv-activate">}} {{< tab "Windows" >}} ```ps .venv\Scripts\activate ``` {{< /tab >}} {{< tab "Linux" >}} ```bash source .venv/bin/activate ``` {{< /tab >}} {{< tab "macOS" >}} ```bash source .venv/bin/activate ``` {{< /tab >}} {{< /tabs >}} 2. **Install dependencies** from `Examples/requirements.txt`: {{< tabs "install-deps">}} {{< tab "Windows" >}} ```ps py -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< /tabs >}} 3. **Configure a license** (optional). The suite honours the `GROUPDOCS_LIC_PATH` environment variable and also picks up any `*.lic` file dropped into the project root. Set the variable in your shell before running `run_all_examples.py`: {{< tabs "license-env">}} {{< tab "Windows (PowerShell)" >}} ```ps $env:GROUPDOCS_LIC_PATH = "C:\path\to\GroupDocs.Metadata.lic" ``` {{< /tab >}} {{< tab "Linux" >}} ```bash export GROUPDOCS_LIC_PATH="/path/to/GroupDocs.Metadata.lic" ``` {{< /tab >}} {{< tab "macOS" >}} ```bash export GROUPDOCS_LIC_PATH="/path/to/GroupDocs.Metadata.lic" ``` {{< /tab >}} {{< /tabs >}} {{< alert style="info" >}} Learn more about licensing, evaluation limits, and how to obtain a free 30-day temporary license in the [Licensing]({{< ref "/metadata/python-net/getting-started/evaluation-limitations-and-licensing.md" >}}) documentation topic. {{< /alert >}} ## Run the Examples ### Run the Full Suite From the repository root, invoke `run_all_examples.py`. It runs every example in order, prints a per-file status line, and exits with a pass/fail summary. {{< tabs "run-all">}} {{< tab "Windows" >}} ```ps py Examples\run_all_examples.py ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 Examples/run_all_examples.py ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 Examples/run_all_examples.py ``` {{< /tab >}} {{< /tabs >}} ### Run a Single Example Change into the folder that contains the script and run it directly. Input sample files live next to each script, so relative paths resolve correctly. ```bash cd Examples/developer-guide/basic-usage/get-document-info python get_document_info.py ``` Examples that modify a file write their output artefacts into the same folder as the script. When an example is documented on this site, the generated artefact is also linked from an **output** tab next to the code block — click it to download the file that a successful run produces. ## Run with Docker The repository includes a `Dockerfile` (based on `python:3.13-slim`) that installs the required native libraries (`libgdiplus`, `libfontconfig1`, ICU) and every Python dependency, then runs the full suite. Use it when you want a clean, reproducible Linux environment without touching your host machine: ```bash docker build -t groupdocs-metadata-examples . docker run --rm \ -e GROUPDOCS_LIC_PATH=/license/GroupDocs.Metadata.lic \ -v /path/to/your/license:/license:ro \ groupdocs-metadata-examples ``` Drop the `-e` / `-v` flags to run in evaluation mode. ## Continuous Integration Every push triggers `.github/workflows/run-examples.yml`, which runs the entire example suite on `ubuntu-latest` with Python 3.13 (after installing `libicu-dev`, `libgdiplus`, and `libfontconfig1`). Fork the repository and open a pull request — the workflow runs for free on GitHub-hosted runners and is a quick way to sanity-check local changes in a clean environment. ## Troubleshooting - **`DllNotFoundException: libgdiplus`** on Linux / macOS — install the native dependencies. See [How to install libgdiplus]({{< ref "/metadata/python-net/getting-started/troubleshooting/how-to-install-libgdiplus.md" >}}) and the full list in [System Requirements]({{< ref "/metadata/python-net/getting-started/system-requirements.md" >}}). - **Garbled text or missing glyphs** — install Microsoft TrueType fonts (`ttf-mscorefonts-installer` on Debian / Ubuntu; macOS already ships them). Run `fc-cache -f` after installing so fontconfig picks them up. - **"Evaluation only" exception on `save()`, or only a few properties are read** — you are running unlicensed. Set `GROUPDOCS_LIC_PATH` to a valid license file and re-run. See [Licensing]({{< ref "/metadata/python-net/getting-started/evaluation-limitations-and-licensing.md" >}}). - **Anything else** — post on the [free support forum](https://forum.groupdocs.com/c/metadata) or visit the [Technical Support]({{< ref "metadata/python-net/technical-support" >}}) page. ## Contribute If you would like to add or improve an example, we encourage you to contribute. All examples in this repository are open source and can be freely used in your own applications. Fork the repository, edit the example, and create a pull request — we will review the changes and include them if found helpful. --- ## Getting known property descriptors Path: /metadata/python-net/getting-known-property-descriptors/ This example demonstrates how to extract information about the known properties that can be encountered in a particular package. 1. [Load]({{< ref "metadata/python-net/developer-guide/advanced-usage/loading-files/_index.md" >}}) a file to examine 2. Get the collection of property descriptors for the desired metadata package 3. Iterate through the extracted descriptors {{< tabs "getting-known-property-descriptors">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def getting_known_property_descriptors(): with Metadata("input.doc") as metadata: root = metadata.get_root_package() # Not every package exposes document properties; guard for it document_properties = getattr(root, "document_properties", None) if document_properties is not None: # Each descriptor describes a known property the package supports for descriptor in document_properties.know_property_descriptors: print(descriptor.name) # property name print(descriptor.type) # value type print(descriptor.access_level) # read-only / read-write # Tags attached to the property (used by the search predicates) for tag in descriptor.tags: print(tag) print() if __name__ == "__main__": getting_known_property_descriptors() ``` {{< /tab >}} {{< tab "input.doc" >}} {{< tab-text >}} `input.doc` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/getting-known-property-descriptors/input.doc) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "getting-known-property-descriptors.txt" >}} ```text Author 1 7 PersonCreator DocumentPropertyTypeBuiltIn Bytes 5 7 DesignationMeasure [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/getting-known-property-descriptors/getting_known_property_descriptors/getting-known-property-descriptors.txt) {{< /tab >}} {{< /tabs >}} {{< alert style="info" >}} Not all possible properties are present in the `know_property_descriptors` collection. The library provides information on the most frequently used properties only. If there is no descriptor for some property, it is still accessible through the GroupDocs.Metadata search engine in read-only mode. {{< /alert >}} ## See also - [Working with interpreted values]({{< ref "metadata/python-net/developer-guide/advanced-usage/working-with-interpreted-values.md" >}}) - [Extracting metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) - [Advanced usage]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Technical Support Path: /metadata/python-net/technical-support/ GroupDocs provides unlimited free technical support for all of its products. Support is available to all users, including evaluation. The support is provided at [Free Support Forum](https://forum.groupdocs.com/) and [Paid Support Helpdesk](https://helpdesk.groupdocs.com/). {{< alert style="info" >}} Please note that GroupDocs does not provide technical support over the phone. Phone support is only available for sales and purchase questions. {{< /alert >}} ## GroupDocs Free Support Forum If you need help with GroupDocs.Metadata, consider the following: * Make sure you are using the latest GroupDocs.Metadata version before reporting an issue. See [PyPI](https://pypi.org/project/groupdocs-metadata-net) to find out about the latest version. * Have a look through the forums, this documentation, and the API Reference before reporting an issue – perhaps your question has already been answered. * Post your question at [GroupDocs.Metadata Free Support Forum](https://forum.groupdocs.com/c/metadata/9), and we'll assist you. Questions are answered directly by the GroupDocs.Metadata development team. * When expecting a reply on the forums, please allow for time zone differences. ## Paid Support Helpdesk The paid support issues has higher priority comparing to the free support requests. * Post your question at the [Paid Support Helpdesk](https://helpdesk.groupdocs.com/) to set higher priority for the issue. ## Report an Issue or Feature Request When posting your issue, question, or feature request with GroupDocs.Metadata, follow these simple steps to make sure it is resolved in the most efficient way: * Include the original document and possibly the code snippet that is causing the problem. If you need to attach a few files, zip them into one. It is safe to attach your documents to GroupDocs.Forums because only you and the GroupDocs developers will have access to the attached files. * Add information about the environment you are facing the issue. * Try to report one issue per thread. If you have another issue, question, or feature request, please report it in a separate thread. --- ## Working with interpreted values Path: /metadata/python-net/working-with-interpreted-values/ Sometimes it's not obvious what a particular metadata property is supposed to mean. A good example is a numeric flag or enumeration. For instance, here is the description of the EXIF `ExposureProgram` tag taken from the official EXIF specification: {{< alert style="info" >}} The class of the program used by the camera to set exposure when the picture is taken. The tag values are as follows. 0 = Not defined 1 = Manual 2 = Normal program 3 = Aperture priority 4 = Shutter priority 5 = Creative program 6 = Action program 7 = Portrait mode 8 = Landscape mode {{< /alert >}} As you can see, all modes are represented by numeric values. If you are not familiar with the specification, converting these bare numbers to something meaningful is hard. This is where interpreted values come in — they provide a user-friendly description of the original property value. To get a full list of properties that have interpreted values for a particular file, use the example below. The original value is available through `prop.value.raw_value` and the human-readable one through `prop.interpreted_value.raw_value`. {{< tabs "working-with-interpreted-values">}} {{< tab "Python" >}} ```python from groupdocs.metadata import Metadata def working_with_interpreted_values(): with Metadata("input.jpg") as metadata: # Keep only properties that expose a human-readable interpreted value properties = metadata.find_properties(lambda p: p.interpreted_value is not None) for prop in properties: print(prop.name) print(prop.value.raw_value) # original (raw) value print(prop.interpreted_value.raw_value) # friendly interpretation print() if __name__ == "__main__": working_with_interpreted_values() ``` {{< /tab >}} {{< tab "input.jpg" >}} {{< tab-text >}} `input.jpg` is the sample file used in this example. Click [here](/metadata/python-net/_sample_files/developer-guide/advanced-usage/working-with-interpreted-values/input.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "working-with-interpreted-values.txt" >}} ```text FileFormat 9 Jpeg ByteOrder 1 BigEndian XResolution System.Double[] [TRUNCATED] ``` [Download full output](/metadata/python-net/_output_files/developer-guide/advanced-usage/working-with-interpreted-values/working_with_interpreted_values/working-with-interpreted-values.txt) {{< /tab >}} {{< /tabs >}} From release to release we add interpreters to metadata properties extracted from various formats. ## See also - [Getting known property descriptors]({{< ref "metadata/python-net/developer-guide/advanced-usage/getting-known-property-descriptors.md" >}}) - [Extracting metadata]({{< ref "metadata/python-net/developer-guide/advanced-usage/extracting-metadata.md" >}}) - [Advanced usage]({{< ref "metadata/python-net/developer-guide/advanced-usage/_index.md" >}}) ## More resources ### GitHub examples You may easily run the code above and see the feature in action in our GitHub examples: * [GroupDocs.Metadata for Python via .NET examples](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET/) ### Free online document metadata management App You are welcome to view and edit metadata of PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX, emails, images and more with our free online [Free Online Document Metadata Viewing and Editing App](https://products.groupdocs.app/metadata). --- ## Agents and LLM Integration Path: /metadata/python-net/agents-and-llm-integration/ ## AI agent and LLM friendly GroupDocs.Metadata for Python via .NET is designed to work seamlessly with AI agents, LLMs, and automated code generation tools. The library ships machine-readable documentation in multiple formats — including an `AGENTS.md` file inside the pip package itself — so AI assistants can discover and use the API without manual guidance. ## MCP server GroupDocs provides an [MCP (Model Context Protocol) server](https://docs.groupdocs.com/mcp) that lets LLMs query the documentation on demand instead of loading it all at once. This saves tokens and lets your AI assistant fetch only what it needs for the current task. To connect your AI tool to the MCP server, add the GroupDocs endpoint to your MCP configuration: {{< tabs "mcp-setup">}} {{< tab "Claude Code / Claude Desktop" >}} ```json // Claude Code: ~/.claude/settings.json (or project .mcp.json) // Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` {{< /tab >}} {{< tab "GitHub Copilot" >}} ```json // .vscode/mcp.json in your project root { "servers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` {{< /tab >}} {{< tab "Cursor" >}} ```json // .cursor/mcp.json in your project root { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` {{< /tab >}} {{< tab "Generic MCP" >}} ```json // Any MCP-compatible client { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` {{< /tab >}} {{< /tabs >}} See [https://docs.groupdocs.com/mcp](https://docs.groupdocs.com/mcp) for full setup instructions and the list of available tools. ## AGENTS.md — built into the package The `groupdocs-metadata-net` pip package includes an `AGENTS.md` file at `groupdocs/metadata/AGENTS.md`. AI coding assistants that scan installed packages (such as Claude Code, Cursor, and GitHub Copilot) can automatically discover the API surface, usage patterns, and troubleshooting tips. After installing the package, you can find it at: ```bash pip show -f groupdocs-metadata-net | grep AGENTS ``` ## Machine-readable documentation Every documentation page is available as a plain Markdown file that AI tools can fetch and process directly: | Resource | URL | |---|---| | Full documentation (single file) | `https://docs.groupdocs.com/metadata/python-net/llms-full.txt` | | Full documentation (all products) | `https://docs.groupdocs.com/llms-full.txt` | | Individual page (any page) | Append `.md` to the page URL | | Quick start guide | `https://docs.groupdocs.com/metadata/python-net/getting-started/quick-start-guide.md` | ### How to use with AI tools Point your AI assistant to the full documentation file for comprehensive context: ``` Fetch https://docs.groupdocs.com/metadata/python-net/llms-full.txt and use it as a reference for GroupDocs.Metadata for Python via .NET API. ``` ## Why GroupDocs.Metadata is a good building block for AI pipelines Metadata is structured, high-signal context that LLMs and RAG systems can use directly — author, dates, comments, geolocation, camera settings, document statistics, and format details — without parsing the document body. GroupDocs.Metadata exposes this uniformly across 70+ formats: - **Extract metadata for indexing / RAG** — pull author, title, keywords, and EXIF/XMP/IPTC fields into your search index or vector store. - **Sanitize before sharing** — strip author, comments, and revision history from documents an agent is about to send out. - **Compliance and DAM** — audit and normalize metadata across mixed document and image collections. - **Export for analysis** — dump the metadata tree to CSV/XLSX/JSON for downstream tooling. A typical extraction step looks like this: ```python from groupdocs.metadata import Metadata with Metadata("inbox/incoming.docx") as metadata: info = metadata.get_document_info() record = { "format": str(info.file_type.file_format), "pages": info.page_count, "encrypted": info.is_encrypted, "properties": { p.name: str(p.value) for p in metadata.find_properties(lambda p: True) }, } # feed `record` into your index, vector store, or compliance pipeline ``` For end-to-end examples — reading and editing EXIF/XMP/IPTC, searching by tag, sanitizing, and exporting — see the [Developer Guide]({{< ref "metadata/python-net/developer-guide/_index.md" >}}). Every code block has a runnable counterpart in the [examples repository](https://github.com/groupdocs-metadata/GroupDocs.Metadata-for-Python-via-.NET). ## Pair with other GroupDocs products For richer AI document pipelines, chain GroupDocs.Metadata with: - [GroupDocs.Viewer for Python via .NET](https://docs.groupdocs.com/viewer/python-net/) — render documents to HTML/PNG/PDF for vision models and OCR. - [GroupDocs.Conversion for Python via .NET](https://docs.groupdocs.com/conversion/python-net/) — normalize legacy and exotic formats before extraction. ## See also - [Quick Start Guide]({{< ref "metadata/python-net/getting-started/quick-start-guide" >}}) — your first metadata script in five minutes - [Developer Guide]({{< ref "metadata/python-net/developer-guide" >}}) — runnable examples for every API surface - [API Reference](https://reference.groupdocs.com/metadata/python-net) — full class and method documentation