# GroupDocs.Redaction for Python via .NET — Complete Documentation > Native Python library that permanently redacts sensitive content — text, metadata, annotations, and image areas — from PDF, Word, Excel, PowerPoint, and image files on Windows, Linux, and macOS. No Microsoft Office or Adobe Acrobat required. --- ## Features Overview Path: /redaction/python-net/features-overview/ GroupDocs.Redaction for Python via .NET removes or permanently obscures sensitive information across a wide range of [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}). Every redaction follows the same workflow: open a document with `Redactor`, apply one or more redactions with `apply()`, then `save()` the cleaned result either in its original format or as a sanitized PDF. The capabilities below can be combined freely in a single pass. ## Text redaction Find and replace text by an exact phrase or by a regular expression, covering both whole words and complex patterns such as e-mail addresses, phone numbers, or national ID numbers. Matched text can be replaced with substitute text or covered by a colored box so the original content cannot be recovered. In spreadsheets you can narrow the search to a single worksheet or column. See [Text Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/text-redactions.md" >}}). ## Metadata redaction Erase or rewrite document metadata — author, title, company, comments, and EXIF data on images — so no sensitive details leak through document properties. You can clear all metadata, target specific fields, or replace values with new ones. See [Metadata Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/metadata-redactions.md" >}}). ## Image-area redaction Black out a rectangular region of an embedded image or a scanned page by drawing a filled box over a given area — useful for hiding signatures, photos, headers, or footers where confidential data is expected to appear. See [Image Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/image-redactions.md" >}}). ## Annotation redaction Rewrite or delete annotations, comments, and notes. You can remove every annotation or use a regular expression to match only the ones that contain sensitive text. See [Annotation Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/annotation-redactions.md" >}}). ## Page removal Remove whole pages from PDF documents, slides from presentations, and worksheets from spreadsheets. You specify a starting page and a count, together with the direction relative to the starting point. See [Remove Page Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/remove-page-redactions.md" >}}). ## Rasterization to PDF Save the cleaned document as a PDF whose pages are rendered as raster images. The resulting file contains no searchable text and none of the original metadata, so the removed content cannot be recovered. Rasterization is the right choice when you must hand a document to third parties or conform to regulations that require PDF. You can select specific pages and request PDF/A compliance through the advanced rasterization options. See [Save in Rasterized PDF]({{< ref "redaction/python-net/developer-guide/advanced-usage/saving-documents/save-in-rasterized-pdf.md" >}}) and [Advanced Rasterization Options]({{< ref "redaction/python-net/developer-guide/advanced-usage/saving-documents/use-advanced-rasterization-options.md" >}}). ## Redaction policies Group several redactions into a reusable policy and apply the same set of rules consistently across many documents — ideal for recurring tasks such as scrubbing a standard set of fields before publishing. See [Use Redaction Policies]({{< ref "redaction/python-net/developer-guide/advanced-usage/use-redaction-policies.md" >}}). ## Loading and saving Load documents from a local path or from a stream, including password-protected files, and optionally pre-rasterize a document before redacting. When saving, keep the original format for further editing, overwrite the original file, rasterize to PDF, or write to a stream. See [Loading Documents]({{< ref "redaction/python-net/developer-guide/advanced-usage/loading-documents/_index.md" >}}) and [Saving Documents]({{< ref "redaction/python-net/developer-guide/advanced-usage/saving-documents/_index.md" >}}). ## On-premise GroupDocs.Redaction for Python via .NET runs entirely on your own infrastructure — your documents never leave your environment. The package is a self-contained wheel that bundles everything it needs, so no Microsoft Office, OpenOffice, Adobe Acrobat, or separate runtime has to be installed. See [System Requirements]({{< ref "redaction/python-net/getting-started/system-requirements.md" >}}) for the supported platforms and native dependencies. --- ## Get supported file formats Path: /redaction/python-net/get-supported-file-formats/ GroupDocs.Redaction allows to get the list of all supported file formats by these steps: * Call [GetSupportedFileTypes](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/filetype/get_supported_file_types/) of [FileType](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/filetype/) class; * Enumerate through the collection of [FileType](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/filetype/) objects*.* The following example demonstrates how to get supported file formats list. {{< tabs "code-example-list-supported-formats" >}} {{< tab "list_supported_formats.py" >}} ```python from groupdocs.redaction import FileType def list_supported_formats(): # Retrieve the collection of supported file types supported_file_types = FileType.get_supported_file_types() # Enumerate the file types sorted by extension for file_type in sorted(supported_file_types, key=lambda x: x.extension): print(file_type) if __name__ == "__main__": list_supported_formats() ``` {{< /tab >}} {{< tab "list-supported-formats.txt" >}} ```text Bitmap Image File (.bmp) Comma Separated Values File (.csv) Microsoft Word Document (.doc) Word Open XML Macro-Enabled Document (.docm) Microsoft Word Open XML Document (.docx) Word Document Template (.dot) Word Open XML Macro-Enabled Document Template (.dotm) Word Open XML Document Template (.dotx) Graphical Interchange Format File (.gif) Hypertext Markup Language File (.htm) [TRUNCATED] ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/get-supported-file-formats/list_supported_formats/list-supported-formats.txt) {{< /tab >}} {{< /tabs >}} --- ## Install GroupDocs.Redaction for Python via .NET Path: /redaction/python-net/installation/ GroupDocs.Redaction for Python via .NET is distributed as a pre-built wheel on [PyPI](https://pypi.org/project/groupdocs-redaction-net/). The PyPI index hosts a separate wheel for each supported platform, and `pip` picks the correct one automatically. Each wheel is self-contained: it bundles the embedded runtime and every managed dependency, so no Microsoft Office, OpenOffice, Adobe Acrobat, or separate runtime install is required. Before installing, confirm your environment matches the supported platforms and Python versions listed in the [System Requirements]({{< ref "redaction/python-net/getting-started/system-requirements.md" >}}) topic. ## Install Package from PyPI Open a terminal and run the install command for your platform: {{< tabs "install-pypi">}} {{< tab "Windows" >}} ```ps py -m pip install groupdocs-redaction-net ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m pip install groupdocs-redaction-net ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m pip install groupdocs-redaction-net ``` {{< /tab >}} {{< /tabs >}} After running the command you should see output similar to: ```bash Collecting groupdocs-redaction-net Downloading groupdocs_redaction_net-26.6.0-py3-none-win_amd64.whl.metadata (3.0 kB) Downloading groupdocs_redaction_net-26.6.0-py3-none-win_amd64.whl (40.0 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.0/40.0 MB 2.8 MB/s eta 0:00:00 Installing collected packages: groupdocs-redaction-net Successfully installed groupdocs-redaction-net-26.6.0 ``` The wheel file name will include a platform suffix that matches your operating system — for example `manylinux1_x86_64` on Ubuntu/Debian, `macosx_11_0_arm64` on Apple Silicon, or `win_amd64` on 64-bit Windows. ## Add the Package to `requirements.txt` For reproducible environments, pin the package version in your `requirements.txt`: ```txt groupdocs-redaction-net==26.6.0 ``` Then install all dependencies in one step: ```bash pip install -r requirements.txt ``` ## Install from a Pre-Downloaded Wheel If your build environment cannot reach PyPI, download the appropriate wheel from the [GroupDocs Releases website](https://releases.groupdocs.com/redaction/python-net/) and install it locally. Wheels are published for the following four platforms: - **Windows 64-bit**: file name ends with `win_amd64.whl` - **Linux x64 (glibc)**: file name ends with `manylinux1_x86_64.whl` - **macOS Intel**: file name ends with `macosx_10_14_x86_64.whl` - **macOS Apple Silicon**: file name ends with `macosx_11_0_arm64.whl` Place the downloaded wheel into your project folder, then install it: {{< tabs "install-wheel">}} {{< tab "Windows (64-bit)" >}} ```ps py -m pip install ./groupdocs_redaction_net-26.6.0-py3-none-win_amd64.whl ``` {{< /tab >}} {{< tab "Linux (glibc)" >}} ```bash python3 -m pip install ./groupdocs_redaction_net-26.6.0-py3-none-manylinux1_x86_64.whl ``` {{< /tab >}} {{< tab "macOS (Intel)" >}} ```bash python3 -m pip install ./groupdocs_redaction_net-26.6.0-py3-none-macosx_10_14_x86_64.whl ``` {{< /tab >}} {{< tab "macOS (Apple Silicon)" >}} ```bash python3 -m pip install ./groupdocs_redaction_net-26.6.0-py3-none-macosx_11_0_arm64.whl ``` {{< /tab >}} {{< /tabs >}} Expected output: ```bash Processing ./groupdocs_redaction_net-26.6.0-py3-none-*.whl Installing collected packages: groupdocs-redaction-net Successfully installed groupdocs-redaction-net-26.6.0 ``` ## Platform Prerequisites On Windows no extra steps are required. On Linux and macOS, install the native libraries the rendering engine depends on: {{< tabs "platform-prereqs">}} {{< tab "Linux" >}} ```bash apt install libgdiplus libfontconfig1 libicu-dev ttf-mscorefonts-installer ``` {{< /tab >}} {{< tab "macOS" >}} ```bash brew install mono-libgdiplus ``` {{< /tab >}} {{< /tabs >}} {{< alert style="warning" >}} In version 26.6.0, **rasterization to PDF and image-area redaction run only on Windows** — on Linux/macOS they raise `System.PlatformNotSupportedException`, and the native packages above do not lift that restriction. Text, metadata, annotation, and page redaction and original-format saves work on every platform. See [System Requirements]({{< ref "redaction/python-net/getting-started/system-requirements.md" >}}) for the full feature-support matrix. {{< /alert >}} ## Verify the Installation Confirm the package imported correctly and check the installed version: ```bash python -c "import groupdocs.redaction; print('GroupDocs.Redaction is ready')" ``` You can also list the installed package with `pip show groupdocs-redaction-net` to confirm the version and location. ## Next Steps - Follow the [Hello, World!]({{< ref "redaction/python-net/getting-started/hello-world.md" >}}) guide to run your first redaction. - Read the [Features Overview]({{< ref "redaction/python-net/getting-started/features-overview.md" >}}) to see everything you can redact. - Clone the [examples repository](https://github.com/groupdocs-redaction/GroupDocs.Redaction-for-Python-via-.NET) and read [How to Run Examples]({{< ref "redaction/python-net/getting-started/how-to-run-examples.md" >}}) to try every documented scenario locally. --- ## Load from local disc Path: /redaction/python-net/load-from-local-disc/ [GroupDocs.Redaction.Redactor](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/) class is a main class in Redaction API, providing functionality to open a document. When document is located on the local disk, you can pass its path to [Redactor](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor) class constructor. The following example demonstrates how to open a document from local disc: {{< tabs "code-example-load-from-local-disc" >}} {{< tab "load_from_local_disc.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import DeleteAnnotationRedaction def load_from_local_disc(): # Specify the redaction options - remove all annotations del_red = DeleteAnnotationRedaction() # Load the document to be redacted from the local disc with Redactor("./sample.docx") as redactor: # Apply the redaction redactor.apply(del_red) # Save the redacted document in its original format next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": load_from_local_disc() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/loading-documents/load-from-local-disc/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 13 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/loading-documents/load-from-local-disc/load_from_local_disc/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} --- ## GroupDocs.Redaction for Python via .NET Overview Path: /redaction/python-net/product-overview/ ## What is GroupDocs.Redaction? GroupDocs.Redaction for Python via .NET is a native Python library that **permanently removes or obscures sensitive content** from documents — across PDF, Microsoft Word, Excel, PowerPoint, and image formats — through a single, format-independent API. It runs entirely on-premise, requires no Microsoft Office or Adobe Acrobat installation, and ships as a pre-built wheel on Windows, Linux, and macOS. Typical uses include: - **PII / PHI removal** — strip names, SSNs, emails, and other personal data from a document before it is shared, published, or archived (GDPR, HIPAA, CCPA). - **Legal & e-discovery redaction** — black out privileged phrases and annotations across every page of a production set. - **Metadata sanitization** — erase or rewrite author, company, and other hidden metadata that leaks information. - **Irreversible redaction** — rasterize the cleaned document to a PDF so the removed content can never be recovered. - **Policy-driven batch redaction** — define a reusable set of redaction rules once and apply it across many documents in a pipeline. ## Key Capabilities | Capability | Description | |---|---| | **Text Redaction** | Replace or black out text matched by an exact phrase (case-sensitive or RTL-aware) or a regular expression. See [Text Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/text-redactions.md" >}}). | | **Metadata Redaction** | Erase metadata wholesale or by filter, or rewrite values that match a pattern. See [Metadata Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/metadata-redactions.md" >}}). | | **Image Redaction** | Black out a rectangular area of an image or scanned page and clean embedded image metadata. See [Image Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/image-redactions.md" >}}). | | **Annotation Redaction** | Rewrite or delete annotations, comments, and notes by pattern. See [Annotation Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/annotation-redactions.md" >}}). | | **Page Removal** | Remove whole pages, slides, or worksheets from a document. See [Remove Page Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/remove-page-redactions.md" >}}). | | **Rasterization & Saving** | Save in the original format, or rasterize to a PDF (optionally PDF/A) so redactions are irreversible. See [Saving Documents]({{< ref "redaction/python-net/developer-guide/advanced-usage/saving-documents/_index.md" >}}). | | **Redaction Policies** | Bundle several redactions into a reusable policy and apply it across many documents. See [Use Redaction Policies]({{< ref "redaction/python-net/developer-guide/advanced-usage/use-redaction-policies.md" >}}). | | **Document Inspection** | Read file type, page count, and size without modifying the document. See [Get File Info]({{< ref "redaction/python-net/developer-guide/basic-usage/get-file-info.md" >}}). | ## Quick Example Redact every occurrence of a phrase and save the result with just a few lines of code. The example rasterizes the result to a PDF named `sample_redacted.pdf`, so the removed content cannot be recovered: {{< tabs "product-overview-redact-text" >}} {{< tab "redact_text.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def redact_text(): # Open the document with Redactor("./sample.docx") as redactor: # Replace every occurrence of "John Doe" with "[personal]" redactor.apply(ExactPhraseRedaction("John Doe", ReplacementOptions("[personal]"))) # Rasterize the result to a PDF named sample_redacted.pdf save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" redactor.save(save_options) if __name__ == "__main__": redact_text() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/product-overview/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1.0 MB) ``` [Download full output](/redaction/python-net/_output_files/product-overview/redact_text/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} For finer control, apply several redactions and keep the original format with `SaveOptions(rasterize_to_pdf=False)`: {{< tabs "product-overview-redact-options" >}} {{< tab "redact_with_options.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ExactPhraseRedaction, RegexRedaction, ReplacementOptions from groupdocs.redaction.options import SaveOptions def redact_with_options(): with Redactor("./sample.docx") as redactor: # Redact a name and any 2+ digit number sequences redactor.apply(ExactPhraseRedaction("John Doe", ReplacementOptions("[personal]"))) redactor.apply(RegexRedaction(r"\d{2,}", ReplacementOptions("[number]"))) # Keep the original DOCX format instead of rasterizing to PDF options = SaveOptions() options.add_suffix = True options.rasterize_to_pdf = False options.redacted_file_suffix = "redacted" redactor.save(options) if __name__ == "__main__": redact_with_options() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/product-overview/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/product-overview/redact_with_options/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} ## Where to next 1. **Install the package** — [Installation]({{< ref "redaction/python-net/getting-started/installation.md" >}}) walks through PyPI and offline wheel installation for Windows, Linux, and macOS. 2. **Run your first redaction** — [Hello, World!]({{< ref "redaction/python-net/getting-started/hello-world.md" >}}) redacts a document in under five minutes. 3. **Explore runnable examples** — [How to Run Examples]({{< ref "redaction/python-net/getting-started/how-to-run-examples.md" >}}) clones the GitHub repository and runs every documented scenario locally or in Docker. 4. **Use it in depth** — the [Developer Guide]({{< ref "redaction/python-net/developer-guide/_index.md" >}}) covers every API surface with runnable, copy-paste code examples. 5. **Plug it into AI pipelines** — [AI Agents & LLM Integration]({{< ref "redaction/python-net/agents-and-llm-integration.md" >}}) explains the bundled `AGENTS.md`, the MCP server, and machine-readable docs. --- ## Save in original format Path: /redaction/python-net/save-in-original-format/ The following example demonstrates how to save file in its original format with current date as a suffix: {{< tabs "code-example-save-in-original-format" >}} {{< tab "save_in_original_format.py" >}} ```python from datetime import datetime from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def save_in_original_format(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction redactor.apply(ex_red) # Save the redacted document in its original format with the current date as a suffix so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False date_time_str = datetime.now().strftime("%Y-%m-%d %H-%M-%S") so.redacted_file_suffix = date_time_str result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": save_in_original_format() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/save-in-original-format/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_2026-06-11 17-10-50.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/save-in-original-format/save_in_original_format/sample_2026-06-11 17-10-50.docx) {{< /tab >}} {{< /tabs >}} --- ## Get file info Path: /redaction/python-net/get-file-info/ GroupDocs.Redaction provides general document information, which includes: * FileType * PageCount * FileSize The following code examples demonstrate how to get document information. ## Get file info for a file from local disk {{< tabs "code-example-get-local-file-info" >}} {{< tab "get_local_file_info.py" >}} ```python from groupdocs.redaction import Redactor def get_local_file_info(): # Load the document from local disk with Redactor("./sample.docx") as redactor: # Retrieve general document information info = redactor.get_document_info() print(f"File type: {info.file_type}") print(f"Number of pages: {info.page_count}") print(f"Document size: {info.size} bytes") if __name__ == "__main__": get_local_file_info() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/get-file-info/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "get-local-file-info.txt" >}} ```text File type: Microsoft Word Open XML Document (.docx) Number of pages: 1 Document size: 19370 bytes ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/get-file-info/get_local_file_info/get-local-file-info.txt) {{< /tab >}} {{< /tabs >}} ## Get file info for a file from Stream {{< tabs "code-example-get-file-info-from-stream" >}} {{< tab "get_file_info_from_stream.py" >}} ```python from groupdocs.redaction import Redactor def get_file_info_from_stream(): # Open the document as a binary stream with open("./sample.docx", "rb") as stream: # Load the document from the stream with Redactor(stream) as redactor: # Retrieve general document information info = redactor.get_document_info() print(f"File type: {info.file_type}") print(f"Number of pages: {info.page_count}") print(f"Document size: {info.size} bytes") if __name__ == "__main__": get_file_info_from_stream() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/get-file-info/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "get-file-info-from-stream.txt" >}} ```text File type: Microsoft Word Open XML Document (.docx) Number of pages: 1 Document size: 19370 bytes ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/get-file-info/get_file_info_from_stream/get-file-info-from-stream.txt) {{< /tab >}} {{< /tabs >}} --- ## Hello, World! Path: /redaction/python-net/hello-world/ ## Introduction A "Hello, World!" example is often the first step when exploring GroupDocs.Redaction for Python via .NET. It serves as a simple test to confirm that your development environment is correctly set up and that the library is functioning as expected. ## Overview GroupDocs.Redaction for Python via .NET lets you search, redact, and remove sensitive information from various document formats. A wide range of [supported formats](/redaction/python-net/getting-started/supported-document-formats/) makes it versatile for different use cases. ## How to redact a document The following steps demonstrate how to redact sensitive information from a document using GroupDocs.Redaction for Python via .NET: 1. Import the `groupdocs.redaction` classes you need. 2. Describe the redaction (here, an exact phrase to replace with a colored box). 3. Instantiate a `Redactor` with the path to the sample document. 4. Apply the redaction. 5. Save the result. ## Complete example The example below replaces every occurrence of the phrase "John Doe" with a semi-transparent red box and saves the redacted document: {{< tabs "code-example-hello-world" >}} {{< tab "hello_world.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.pydrawing import Color def hello_world(): # Draw a semi-transparent red box over every occurrence of "John Doe" options = ReplacementOptions(Color.from_argb(128, 255, 0, 0)) redaction = ExactPhraseRedaction("John Doe", options) # Load the document, apply the redaction, and save the result with Redactor("./sample.docx") as redactor: redactor.apply(redaction) save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully. Output saved to {result_path}.") if __name__ == "__main__": hello_world() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/getting-started/hello-world/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1.0 MB) ``` [Download full output](/redaction/python-net/_output_files/getting-started/hello-world/hello_world/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} This example rasterizes the result to a PDF named `sample_redacted.pdf`, so the redacted content cannot be recovered (`save()` rasterizes to PDF by default; the `redacted_file_suffix` option just controls the output name). To keep the original format instead, set `rasterize_to_pdf = False`. ## Additional resources This demo references the GroupDocs.Redaction for Python via .NET [code samples](https://github.com/groupdocs-redaction/GroupDocs.Redaction-for-Python-via-.NET/). --- ## Load from Stream Path: /redaction/python-net/load-from-stream/ As an alternative to a local file, [Redactor](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/) can open a document from stream. The following example demonstrates how to load and redact a document using Stream: {{< tabs "code-example-load-from-stream" >}} {{< tab "load_from_stream.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import RasterizationOptions from groupdocs.redaction.redactions import DeleteAnnotationRedaction def load_from_stream(): # Specify the redaction options - remove all annotations del_red = DeleteAnnotationRedaction() # Load the document as a stream to be redacted with open("./sample.docx", "rb") as stream_in: with Redactor(stream_in) as redactor: # Apply the redaction redactor.apply(del_red) # Save the redacted document to a stream as a rasterized PDF with open("./redacted-sample.pdf", "wb") as stream_out: ro = RasterizationOptions() redactor.save(stream_out, ro) print("Document redacted successfully.") if __name__ == "__main__": load_from_stream() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/loading-documents/load-from-stream/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "redacted-sample.pdf" >}} ```text Binary file (PDF, 1.2 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/loading-documents/load-from-stream/load_from_stream/redacted-sample.pdf) {{< /tab >}} {{< /tabs >}} --- ## Save in rasterized PDF Path: /redaction/python-net/save-in-rasterized-pdf/ The following example demonstrates how to save the document as a rasterized PDF file: {{< tabs "code-example-save-in-rasterized-pdf" >}} {{< tab "save_in_rasterized_pdf.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def save_in_rasterized_pdf(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction redactor.apply(ex_red) # Save the redacted document as a rasterized PDF so = SaveOptions() so.add_suffix = False so.rasterize_to_pdf = True result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": save_in_rasterized_pdf() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/save-in-rasterized-pdf/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample.pdf" >}} ```text Binary file (PDF, 1024 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/save-in-rasterized-pdf/save_in_rasterized_pdf/sample.pdf) {{< /tab >}} {{< /tabs >}} --- ## Supported Document Formats Path: /redaction/python-net/supported-document-formats/ ## Supported File Formats The following table indicates the file formats, supported by GroupDocs.Redaction for Python via .NET. | Format | Description | Document body | Metadata | Annotations(comments) | Remarks | Embedded images | OCR | Remove Page | Page Filters | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | [PDF](https://docs.fileformat.com/pdf/) | Saves the document as PDF (Adobe Portable Document) format | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [DOC](https://docs.fileformat.com/word-processing/doc) | Microsoft Word 97 - 2007 Document. | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [DOT](https://docs.fileformat.com/word-processing/dot/) | Microsoft Word 97 - 2007 Template. | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [DOCX](https://docs.fileformat.com/word-processing/docx/) | Office Open XML WordprocessingML Document (macro-free) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [DOCM](https://docs.fileformat.com/word-processing/docm/) | Office Open XML WordprocessingML Macro-Enabled Document | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [DOTX](https://docs.fileformat.com/word-processing/dotx/) | Office Open XML WordprocessingML Template (macro-free) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [DOTM](https://docs.fileformat.com/word-processing/dotm/) | Office Open XML WordprocessingML Macro-Enabled Template. | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [RTF](https://docs.fileformat.com/word-processing/rtf/) | RTF format. | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLSX](https://docs.fileformat.com/spreadsheet/xlsx/) | OOXML 2007-2010 | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLSM](https://docs.fileformat.com/spreadsheet/xlsm/) | OOXML Macro Enabled Workbook | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLTX](https://docs.fileformat.com/spreadsheet/xltx/) | OOXML Workbook Template | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLTM](https://docs.fileformat.com/spreadsheet/xltm/) | OOXML Macro Enabled Workbook Template | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLS](https://docs.fileformat.com/spreadsheet/xls/) | Excel Workbook 97-2003 | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [XLT](https://docs.fileformat.com/spreadsheet/xlt/) | Excel Workbook Template 97-2003 | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [CSV](https://docs.fileformat.com/spreadsheet/csv/) | CSV (Comma Separated Value) file. | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | | | |   | | [PPTX](https://docs.fileformat.com/presentation/pptx/) | OOXML Microsoft PowerPoint Presentations format | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PPT](https://docs.fileformat.com/presentation/ppt/) | PowerPoint Presentation 97-2003 | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PPSX](https://docs.fileformat.com/presentation/ppsx/) | PowerPoint Open XML | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [POT](https://docs.fileformat.com/presentation/pot/) | PowerPoint template files | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PPS](https://docs.fileformat.com/presentation/pps/) | Microsoft PowerPoint 97-2003 Slide Show | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PPTM](https://docs.fileformat.com/presentation/pptm/) | Microsoft PowerPoint Open XML Macro-Enabled Presentation file | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PPSM](https://docs.fileformat.com/presentation/ppsm/) | Microsoft PowerPoint Open XML Macro-Enabled Slide Show file | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [POTM](https://docs.fileformat.com/presentation/potm/) | Microsoft PowerPoint template | ![(tick)](/redaction/python-net/images/check.png)  | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [JPEG](https://docs.fileformat.com/image/jpeg/) | The image file format was standardized by the Joint Photographic Experts Group. | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   |   | | ![(tick)](/redaction/python-net/images/check.png) | | ![(tick)](/redaction/python-net/images/check.png) | | [TIF/TIFF](https://docs.fileformat.com/image/tiff/) | Tagged Image File Format | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   |   | | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) | | [PNG](https://docs.fileformat.com/image/png/) | Portable Network Graphics Image | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   |   | | ![(tick)](/redaction/python-net/images/check.png) | | ![(tick)](/redaction/python-net/images/check.png) | | [BMP](https://docs.fileformat.com/image/bmp/) | Bitmap Image Files | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   |   | | ![(tick)](/redaction/python-net/images/check.png) | | ![(tick)](/redaction/python-net/images/check.png) | | [GIF](https://docs.fileformat.com/image/gif/) | Graphical Interchange Format Image | ![(tick)](/redaction/python-net/images/check.png) | ![(tick)](/redaction/python-net/images/check.png) |   |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | | [DJVU](https://docs.fileformat.com/image/djvu/) | DjVu Document Format | ![(tick)](/redaction/python-net/images/check.png) | |   |   | | | ![(tick)](/redaction/python-net/images/check.png) |   | {{< 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/redaction/33), and our team will assist you. {{< /alert >}} --- ## Use PDF redaction filters Path: /redaction/python-net/use-pdf-redaction-filters/ You can combine [PageRangeFilter](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/pagerangefilter/) and [PageAreaFilter](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/pageareafilter/) filters in one set in order to set the scope of redaction to an area on a specific page. You have to set an array of instances to **Filters** property of the [ReplacementOptions](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/replacementoptions/). The following example demonstrates how to apply redaction to the bottom half of the last page in a PDF document. {{< tabs "code-example-use-pdf-redaction-filters" >}} {{< tab "use_pdf_redaction_filters.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ( ExactPhraseRedaction, ReplacementOptions, PageRangeFilter, PageAreaFilter, PageSeekOrigin, ) from groupdocs.pydrawing import Point, Size def use_pdf_redaction_filters(): # Load the document to be redacted with Redactor("./multipage_sample.pdf") as redactor: # Get the actual size information for the last page doc_info = redactor.get_document_info() last_page = doc_info.pages[doc_info.page_count - 1] # Define the redaction area start point sample_point = Point(0, int(last_page.height / 2)) # Define the redaction area size sample_size = Size(last_page.width, int(last_page.height / 2)) # Combine page-range and page-area filters to scope the redaction filters = [ PageRangeFilter(PageSeekOrigin.END, 0, 1), PageAreaFilter(sample_point, sample_size), ] # Specify the redaction options with the filters repl_opt = ReplacementOptions("[secret]") repl_opt.filters = filters ex_red = ExactPhraseRedaction("bibliography", False, repl_opt) # Apply the redaction redactor.apply(ex_red) # Save the redacted document save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": use_pdf_redaction_filters() ``` {{< /tab >}} {{< tab "multipage_sample.pdf" >}} {{< tab-text >}} `multipage_sample.pdf` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/using-redaction-filters/use-pdf-redaction-filters/multipage_sample.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "multipage_sample_redacted.pdf" >}} ```text Binary file (PDF, 2.5 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/using-redaction-filters/use-pdf-redaction-filters/use_pdf_redaction_filters/multipage_sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} --- ## Load password-protected file Path: /redaction/python-net/load-password-protected-file/ In order to open password-protected documents, you have to pass your password to [LoadOptions](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.options/loadoptions/) class constructor or assign it to its [Password](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.options/loadoptions/password/) property of an instance of [LoadOptions](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.options/loadoptions/) class: {{< tabs "code-example-load-password-protected-file" >}} {{< tab "load_password_protected_file.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions, LoadOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def load_password_protected_file(): # Specify the load options with the document password load_opt = LoadOptions("mypassword") # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the password-protected document to be redacted with Redactor("./protected.docx", load_opt) as redactor: # Apply the redaction redactor.apply(ex_red) # Save the redacted document in its original format so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": load_password_protected_file() ``` {{< /tab >}} {{< tab "protected.docx" >}} {{< tab-text >}} `protected.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/loading-documents/load-password-protected-file/protected.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "protected_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/loading-documents/load-password-protected-file/load_password_protected_file/protected_redacted.docx) {{< /tab >}} {{< /tabs >}} --- ## Save overwriting original file Path: /redaction/python-net/save-overwriting-original-file/ The following example demonstrates how to save the redacted document, replacing an original file: {{< tabs "code-example-save-overwriting-original-file" >}} {{< tab "save_overwriting_original_file.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.pydrawing import Color def save_overwriting_original_file(): # Define the color of redaction color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = ReplacementOptions(color) ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) if result.status != RedactionStatus.FAILED: # Save the redacted document, overwriting the original file so = SaveOptions() so.add_suffix = False so.rasterize_to_pdf = False result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}") else: print("Redaction failed!") if __name__ == "__main__": save_overwriting_original_file() ``` {{< /tab >}} {{< tab "sample.docx" >}} ```text Binary file (DOCX, 17 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/save-overwriting-original-file/save_overwriting_original_file/sample.docx) {{< /tab >}} {{< /tabs >}} --- ## Redaction basics Path: /redaction/python-net/redaction-basics/ GroupDocs.Redaction supports an effective set of document redaction features. It allows to apply redactions for [text]({{< ref "redaction/python-net/developer-guide/basic-usage/text-redactions.md" >}}), [metadata]({{< ref "redaction/python-net/developer-guide/basic-usage/metadata-redactions.md" >}}), [annotations]({{< ref "redaction/python-net/developer-guide/basic-usage/annotation-redactions.md" >}}), [images]({{< ref "redaction/python-net/developer-guide/basic-usage/image-redactions.md" >}}). Wide range of document formats is supported, such as: PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX and others. See full list of supported formats at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article ## Redaction types GroupDocs.Redaction comes with the following redaction types: | Type | Description | Classes | | --- | --- | --- | | [Text]({{< ref "redaction/python-net/developer-guide/basic-usage/text-redactions.md" >}}) | Replaces or hides with color block a portion of text within document body | [ExactPhraseRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/exactphraseredaction/), [RegexRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/regexredaction/) | | [Metadata]({{< ref "redaction/python-net/developer-guide/basic-usage/metadata-redactions.md" >}}) | Replace metadata values with empty ones or redacts metadata texts | [EraseMetadataRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/erasemetadataredaction/), [MetadataSearchRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatasearchredaction/) | | [Annotations]({{< ref "redaction/python-net/developer-guide/basic-usage/annotation-redactions.md" >}}) | Deletes annotations from document or redacts its texts | [DeleteAnnotationRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/deleteannotationredaction/), [AnnotationRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/annotationredaction/) | | [Images]({{< ref "redaction/python-net/developer-guide/basic-usage/image-redactions.md" >}}) | Replaces specific area of an image with a colored box | [ImageAreaRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/imagearearedaction/) | | [Pages]({{< ref "redaction/python-net/developer-guide/basic-usage/remove-page-redactions.md" >}}) | Removes specific range of pages (slides, worksheets, etc.) | [RemovePageRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/removepageredaction/) | ## Apply redaction Applying redaction to a document is done through [Redactor.Apply](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/apply/) method. As a result, you receive [RedactorChangeLog](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorchangelog/) instance, containing a log entry for each redaction applied. The entry contains reference to [Redacton](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redaction/) instance including its options, status of the operation (see below) and textual descriptions when applicable. If at least one redaction failed, you will see [Status == RedactionStatus.Failed](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionstatus/): {{< tabs "code-example-apply-redaction" >}} {{< tab "apply_redaction.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def apply_redaction(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) if result.status != RedactionStatus.FAILED: # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": apply_redaction() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/redaction-basics/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/redaction-basics/apply_redaction/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} All possible statuses of the [RedactionStatus](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionstatus/) enumeration are listed in this table: | Status | Description | Possible reasons | | --- | --- | --- | | *Applied* | Redaction was fully and successfully applied | All operations within redaction process were successfully applied | | *PartiallyApplied* | Redaction was applied only to a part of its matches | 1) Trial limitations for replacements were exceeded2) At least one change was rejected by user | | *Skipped* | Redaction was skipped (not applied) | 1) Trial limitations for redactions were exceeded2) Redaction cannot be applied to this type of document3) All replacements were rejected by user and no changes were made | | *Failed* | Redaction failed with exception | An exception occurred in process of redaction | For detailed information you have to iterate through redaction log entries in [RedactorChangeLog.RedactionLog](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorchangelog/redaction_log/) and check for [ErrorMessage](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionresult/error_message/) property of any items with status other than *Applied*: ```python result = redactor.apply(redaction) if result.status != RedactionStatus.FAILED: # By default, the redacted document is saved in PDF format save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully.\nCheck output in {result_path}") else: # Dump all failed or skipped redactions print("Redaction failed!") for log_entry in result.redaction_log: if log_entry.result.status != RedactionStatus.APPLIED: print(f"Status is {log_entry.result.status}, details: {log_entry.result.error_message}") ``` ## Apply multiple redactions You can apply as much redactions as you need in a single call to [Redactor.Apply](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/apply/) method, since its overload accepts an array of redactions and redaction policy. In this case, redactions will be applied in the same order as they appear in the array. As an alternative to specifying redaction sets in your code, you can create an XML file with redaction policy, as described [here]({{< ref "redaction/python-net/developer-guide/advanced-usage/use-redaction-policies.md" >}}). {{< tabs "code-example-apply-multiple-redactions" >}} {{< tab "apply_multiple_redactions.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ( ExactPhraseRedaction, RegexRedaction, ReplacementOptions, DeleteAnnotationRedaction, EraseMetadataRedaction, MetadataFilters, ) from groupdocs.pydrawing import Color def apply_multiple_redactions(): # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Provide a list of redactions to apply in order redaction_list = [ ExactPhraseRedaction("John Doe", ReplacementOptions("[Client]")), RegexRedaction("Redaction", ReplacementOptions("[Product]")), RegexRedaction("\\d{2}\\s*\\d{2}[^\\d]*\\d{6}", ReplacementOptions(color)), DeleteAnnotationRedaction(), EraseMetadataRedaction(MetadataFilters.ALL), ] # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the list of redactions result = redactor.apply(redaction_list) if result.status != RedactionStatus.FAILED: # By default, the redacted document is saved in PDF format save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" redactor.save(save_options) else: # Dump all failed or skipped redactions print("Redaction failed!") for log_entry in result.redaction_log: if log_entry.result.status != RedactionStatus.APPLIED: print(f"Status is {log_entry.result.status}, details: {log_entry.result.error_message}") if __name__ == "__main__": apply_multiple_redactions() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/redaction-basics/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1.2 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/redaction-basics/apply_multiple_redactions/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} --- ## Save with default options Path: /redaction/python-net/save-with-default-options/ The simplest way to save the document is it provide no parameters to [Save](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/save/) method. In this case the document will be rasterized to PDF and will have the same name as the original one except its extension (.PDF). The PDF file will be overwritten. The following example demonstrates usage of [Save()](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/save/) method with default options. {{< tabs "code-example-save-with-default-options" >}} {{< tab "save_with_default_options.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def save_with_default_options(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction redactor.apply(ex_red) # Save the document with default options (convert pages into images, save as PDF) save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": save_with_default_options() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/save-with-default-options/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1024 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/save-with-default-options/save_with_default_options/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} --- ## Showcases Path: /redaction/python-net/showcases/ {{< alert style="info" >}}Want to try GroupDocs.Redaction for Python via .NET by yourself? Explore the Python code examples, the real-world use cases below, and the free online demonstration to learn more about the document redaction features.{{< /alert >}} ## GitHub Examples To get started with GroupDocs.Redaction for Python via .NET, explore the runnable code examples on GitHub. The repository provides standalone scripts that showcase every documented capability — text, metadata, image-area, annotation, and page redactions, as well as loading, saving, rasterizing to PDF, and reusable policies. [GroupDocs.Redaction for Python via .NET GitHub Repository](https://github.com/groupdocs-redaction/GroupDocs.Redaction-for-Python-via-.NET) See [How to Run Examples]({{< ref "redaction/python-net/getting-started/how-to-run-examples.md" >}}) to set up the project and run everything locally, and the [Developer Guide]({{< ref "redaction/python-net/developer-guide/_index.md" >}}) for step-by-step explanations. ## Use cases GroupDocs.Redaction fits a wide range of document-sanitization scenarios: - **GDPR and PII removal** — strip personally identifiable information such as names, e-mail addresses, phone numbers, and national ID numbers from documents before they are stored, shared, or published. Regular-expression text redaction combined with metadata erasure removes both visible and hidden personal data. See [Text Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/text-redactions.md" >}}) and [Metadata Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/metadata-redactions.md" >}}). - **Legal and e-discovery redaction** — black out privileged or confidential passages in evidence and case files, delete reviewer comments and annotations, and remove pages that should not be disclosed. Rasterizing the result to PDF guarantees the hidden text cannot be recovered. See [Annotation Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/annotation-redactions.md" >}}) and [Remove Page Redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/remove-page-redactions.md" >}}). - **Sharing scrubbed PDFs** — produce a sanitized, flattened PDF whose pages are raster images, carrying no searchable text and no original metadata, ready to hand to clients, contractors, or the public. Optional PDF/A compliance suits long-term archival. See [Save in Rasterized PDF]({{< ref "redaction/python-net/developer-guide/advanced-usage/saving-documents/save-in-rasterized-pdf.md" >}}). - **Batch compliance pipelines** — bundle a standard set of redactions into a reusable policy and apply it consistently across thousands of documents in an automated workflow. See [Use Redaction Policies]({{< ref "redaction/python-net/developer-guide/advanced-usage/use-redaction-policies.md" >}}). ## Online Demo To experience GroupDocs.Redaction without any installation, try the free online redaction app. It lets you upload a document, redact sensitive content, and download the cleaned result right in your browser: [Free Online Document Redaction App](https://products.groupdocs.app/redaction) The online demo is a convenient way to evaluate the library's capabilities in a real-world environment and decide whether it fits your document-sanitization needs. --- ## Use redaction policies Path: /redaction/python-net/use-redaction-policies/ If you have a corporate sensitive data removal policy as a list of redaction rules, you don't need to specify them in your code. You can specify an XML document with a list of pre-configured redactions. Below is an example of redaction policy XML file (code properties mapping is obvious): **RedactionPolicy.xml** ```xml ``` You can use RedactionPolicy.save() method to create XML documents of this structure, configuring redactions in runtime. The following example demonstrates how to save a [RedactionPolicy](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionpolicy/) to an XML file. {{< tabs "code-example-create-redaction-policy" >}} {{< tab "create_redaction_policy.py" >}} ```python from groupdocs.redaction import RedactionPolicy from groupdocs.redaction.redactions import ( ExactPhraseRedaction, ReplacementOptions, RegexRedaction, DeleteAnnotationRedaction, EraseMetadataRedaction, MetadataFilters, ) from groupdocs.pydrawing import Color def create_redaction_policy(): # Define the color of redaction color = Color.from_argb(255, 220, 20, 60) # Configure the redactions redactions = [ ExactPhraseRedaction("Redaction", ReplacementOptions("[Product]")), RegexRedaction("\\d{2}\\s*\\d{2}[^\\d]*\\d{6}", ReplacementOptions(color)), DeleteAnnotationRedaction(), EraseMetadataRedaction(MetadataFilters.ALL), ] # Create the policy policy = RedactionPolicy(redactions) # Save the redaction policy to an XML file policy.save("./sample_policy.xml") print("Redactions policy saved to ./sample_policy.xml") if __name__ == "__main__": create_redaction_policy() ``` {{< /tab >}} {{< tab "sample_policy.xml" >}} ```text ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/use-redaction-policies/create_redaction_policy/sample_policy.xml) {{< /tab >}} {{< /tabs >}} You can have as many policies as you need, loading them to redact your documents. The example below loads a redaction policy from an XML file and applies every rule it contains to a document in a single `apply` call: {{< tabs "code-example-use-redaction-policy" >}} {{< tab "use_redaction_policy.py" >}} ```python from groupdocs.redaction import Redactor, RedactionPolicy from groupdocs.redaction.options import SaveOptions def use_redaction_policy(): # Load the redaction policy from an XML file policy = RedactionPolicy.load("./redaction_policy.xml") # Load the document and apply the whole policy in one call with Redactor("./sample.docx") as redactor: redactor.apply(policy) # Keep the original format and append a suffix to the output name save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = False save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Redaction policy applied. Output saved to {result_path}.") if __name__ == "__main__": use_redaction_policy() ``` {{< /tab >}} {{< tab "redaction_policy.xml" >}} {{< tab-text >}} `redaction_policy.xml` is the policy file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/use-redaction-policies/redaction_policy.xml) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the document redacted in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/use-redaction-policies/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/use-redaction-policies/use_redaction_policy/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} --- ## Licensing and evaluation Path: /redaction/python-net/licensing-and-subscription/ To explore the system effectively, you may want immediate access to the API. GroupDocs.Redaction simplifies this by offering various purchase plans, along with a Free Trial and a 30-day Temporary License for evaluation. {{< alert style="info" >}} To learn more about licensing options, purchasing, and evaluation policies, refer to the [Purchase Policies and FAQ](https://purchase.groupdocs.com/policies) section. {{< /alert >}} ## Purchased License After purchasing GroupDocs.Redaction for Python via .NET, you will receive a license file that unlocks the full functionality of the API. A few rules apply: - Apply the license **only once** per process, in your start-up code. - Apply it **before** constructing any `Redactor` or other GroupDocs.Redaction object. - A license can be applied from a file path, from a binary stream (handy when the license is an embedded resource), or as a [Metered License](https://purchase.groupdocs.com/faqs/licensing/metered/) that bills by usage. Use the [set_license](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/license/set_license/) method to license the component. Calling it more than once is harmless — it simply wastes a little processor time. ### Set a license from a file The example below applies a license from a file path. It reads the path from the `GROUPDOCS_LIC_PATH` environment variable and falls back to a local `GroupDocs.Redaction.lic` file: {{< tabs "code-example-set-license-from-file" >}} {{< tab "set_license_from_file.py" >}} ```python import os from groupdocs.redaction import License def set_license_from_file(): # Resolve the license path from the environment, with a local fallback license_path = os.environ.get("GROUPDOCS_LIC_PATH", "./GroupDocs.Redaction.lic") # Apply the license before using any redaction features if os.path.exists(license_path): 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 >}} ### Set a license from a stream You can also apply a license from any readable binary stream — useful when the license ships as an embedded resource: {{< tabs "code-example-set-license-from-stream" >}} {{< tab "set_license_from_stream.py" >}} ```python import os from groupdocs.redaction import License def set_license_from_stream(): # Resolve the license path from the environment, with a local fallback license_path = os.environ.get("GROUPDOCS_LIC_PATH", "./GroupDocs.Redaction.lic") # Apply the license from an open binary stream if os.path.exists(license_path): 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 >}} ### Set a metered license A Metered License lets you pay for what you use. Set the public and private keys with [set_metered_key](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/metered/set_metered_key/) before using the API, then query consumption at any time: {{< tabs "code-example-set-metered-license" >}} {{< tab "set_metered_license.py" >}} ```python from groupdocs.redaction import Metered def set_metered_license(): # Replace these placeholders with your real metered public/private keys public_key = "*****" private_key = "*****" # Skip the call until real keys are supplied (placeholder keys are rejected) if "*" in public_key or "*" in private_key: print("Provide real metered keys to enable metered licensing.") return # Apply the metered keys before using any redaction features Metered().set_metered_key(public_key, private_key) # Query the current metered consumption quantity = Metered().get_consumption_quantity() credit = Metered().get_consumption_credit() print(f"Consumption quantity: {quantity}, credit: {credit}") if __name__ == "__main__": set_metered_license() ``` {{< /tab >}} {{< /tabs >}} ### Changing the license file name You are not required to keep the license file name as `GroupDocs.Redaction.lic`. You can rename it to any preferred name and use that name when applying the license in your application. ### "Cannot find license filename" exception When you download the license from the GroupDocs website it is saved as `GroupDocs.Redaction.lic`. However, some web browsers may automatically append `.xml`, resulting in `GroupDocs.Redaction.lic.xml`. If your Windows settings are configured to hide file extensions (the default), the file may still appear as `GroupDocs.Redaction.lic` in File Explorer even though the actual name is `GroupDocs.Redaction.lic.xml`. This discrepancy can cause `set_license` to throw an exception. To fix it, manually rename the file to remove the `.xml` extension, or disable "Hide extensions for known file types" in Windows. ## How to evaluate GroupDocs.Redaction You can evaluate GroupDocs.Redaction for Python via .NET without purchasing a license by using one of the following options. ### Free Trial The evaluation version is identical to the purchased one; it becomes fully licensed once you set a license. Without a license the Free Trial gives you access to the API's features, but with some limitations: - Only **one document** can be opened per process (a subsequent open raises a `TrialLimitationsException`). - Only **one redaction** can be applied to the document. - Any redaction is limited to **four replacements/deletions**, even if there are more matches. - Trial badges are placed at the top of each page of the output document. ### Temporary License To experience the complete features of GroupDocs.Redaction without the limitations of the Free Trial, you can request a 30-day ["Temporary License"](https://purchase.groupdocs.com/temporary-license). --- ## Pre-rasterize Path: /redaction/python-net/pre-rasterize/ In some cases, you might need to pre-rasterize the document before opening it and applying redactions. For instance, you might need to use an [ImageAreaRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/imagearearedaction/) for a whole page of a document with search-able text and images. In order to do that, you will need to pass the Boolean flag to the [LoadOptions](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.options/loadoptions/) class constructor. The following example demonstrates how to pre-rasterize a Microsoft Word document: {{< tabs "code-example-pre-rasterize-document" >}} {{< tab "pre_rasterize_document.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def pre_rasterize_document(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) if result.status != RedactionStatus.FAILED: # By default, the redacted document is saved in PDF format save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully.\nCheck output in {result_path}") else: print("Redaction failed!") if __name__ == "__main__": pre_rasterize_document() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/loading-documents/pre-rasterize/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1024 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/loading-documents/pre-rasterize/pre_rasterize_document/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} --- ## Select specific pages for rasterized PDF Path: /redaction/python-net/select-specific-pages-for-rasterized-pdf/ Saving document as a rasterized PDF, you can specify starting page index (zero based) and the number of pages from this index to save. Also, you can change the Compliance level from PDF/A-1b, which is used by default, to PDF/A-1a: {{< tabs "code-example-select-specific-pages-for-rasterized-pdf" >}} {{< tab "select_specific_pages_for_rasterized_pdf.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions, PdfComplianceLevel from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.pydrawing import Color def select_specific_pages_for_rasterized_pdf(): # Define the color of redaction color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = ReplacementOptions(color) ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./multipage_sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) if result.status != RedactionStatus.FAILED: # Save the processed document, selecting the page range and compliance level so = SaveOptions() so.rasterization.enabled = True # convert pages to images for compatibility so.rasterization.page_index = 5 # start from 6th page (index is 0-based) so.rasterization.page_count = 1 # save only one page so.rasterization.compliance = PdfComplianceLevel.PDF_A1A # PDF/A-1a format so.add_suffix = False result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}") else: print("Redaction failed!") if __name__ == "__main__": select_specific_pages_for_rasterized_pdf() ``` {{< /tab >}} {{< tab "multipage_sample.docx" >}} {{< tab-text >}} `multipage_sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/select-specific-pages-for-rasterized-pdf/multipage_sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "multipage_sample.pdf" >}} ```text Binary file (PDF, 10.8 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/select-specific-pages-for-rasterized-pdf/select_specific_pages_for_rasterized_pdf/multipage_sample.pdf) {{< /tab >}} {{< /tabs >}} --- ## Text redaction Path: /redaction/python-net/text-redactions/ GroupDocs.Redaction allows to easily redact data of sensitive or private nature from your documents. The most popular redaction case is to remove a text from a document. With GroupDocs.Redaction API you can apply text redaction using exact phrase or [regular expression](https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expressions) for documents of different formats like PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX and others. See full list at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article. ## Use exact phrase redaction In the example below, we apply textual redaction, replacing personal exact phrase "John Doe" with "\[personal\]" (or any exemption code): {{< tabs "code-example-redact-exact-phrase" >}} {{< tab "redact_exact_phrase.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def redact_exact_phrase(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_exact_phrase() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_exact_phrase/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} By default, search for exact phase is case insensitive. For a case-sensitive redaction, there is a constructor parameter and corresponding public property: {{< tabs "code-example-redact-case-sensitive-phrase" >}} {{< tab "redact_case_sensitive_phrase.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def redact_case_sensitive_phrase(): # Enable case-sensitive matching case_sensitive = True # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", case_sensitive, repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_case_sensitive_phrase() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_case_sensitive_phrase/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} If you need a color box over the redacted text, you can use color instead of replacement string. The redaction will erase matched text and put a rectangle of the specified color in place of redacted text: {{< tabs "code-example-redact-with-color-box" >}} {{< tab "redact_with_color_box.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.pydrawing import Color def redact_with_color_box(): # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = ReplacementOptions(color) ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_with_color_box() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 17 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_with_color_box/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} You might need to apply redaction to a right-to-left document, such as Arabic or Hebrew. The following example demonstrates how to apply ExactPhraseRedaction to an Arabic PDF document: {{< tabs "code-example-redact-right-to-left-text" >}} {{< tab "redact_right_to_left_text.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def redact_right_to_left_text(): # Specify the redaction options with an Arabic phrase repl_opt = ReplacementOptions("[test]") ex_red = ExactPhraseRedaction("انتقد", repl_opt) # Load the document to be redacted with Redactor("./arabic.pdf") as redactor: # Apply the redaction result = redactor.apply(ex_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_right_to_left_text() ``` {{< /tab >}} {{< tab "arabic.pdf" >}} {{< tab-text >}} `arabic.pdf` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/arabic.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "arabic_redacted.pdf" >}} ```text Binary file (PDF, 23 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_right_to_left_text/arabic_redacted.pdf) {{< /tab >}} {{< /tabs >}} ## Use regular expression Behind the scenes, "exact phrase" redaction works though regular expressions, which are the baseline approach for redaction. In the example below, we redact out any text, matching "2 digits, space or nothing, 2 digits, again space and 6 digits" with a blue color box: {{< tabs "code-example-redact-with-regex" >}} {{< tab "redact_with_regex.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import RegexRedaction, ReplacementOptions from groupdocs.pydrawing import Color def redact_with_regex(): # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = ReplacementOptions(color) reg_red = RegexRedaction("\\d{2}\\s*\\d{2}[^\\d]*\\d{6}", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(reg_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_with_regex() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_with_regex/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} If you need to apply redact a whole paragraph, you might also need to use RegexRedaction. The following example demonstrates how to redact the whole paragraph in a PDF document: {{< tabs "code-example-redact-whole-paragraph" >}} {{< tab "redact_whole_paragraph.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import RegexRedaction, ReplacementOptions from groupdocs.pydrawing import Color def redact_whole_paragraph(): # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options that match an entire paragraph repl_opt = ReplacementOptions(color) reg_red = RegexRedaction("(Lorem(\n|.)+?urna)", repl_opt) # Load the document to be redacted with Redactor("./sample.pdf") as redactor: # Apply the redaction result = redactor.apply(reg_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_whole_paragraph() ``` {{< /tab >}} {{< tab "sample.pdf" >}} {{< tab-text >}} `sample.pdf` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/text-redactions/sample.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 68 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/text-redactions/redact_whole_paragraph/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} --- ## AI agents and LLM integration Path: /redaction/python-net/agents-and-llm-integration/ GroupDocs.Redaction for Python via .NET is designed to work smoothly with AI coding assistants such as Claude Code, Cursor, and GitHub Copilot in agent mode. ## Built into the package The `groupdocs-redaction-net` wheel ships a bundled `AGENTS.md` reference. Once the package is installed, AI tools discover it automatically at `groupdocs/redaction/AGENTS.md`. It covers the canonical imports, the load → apply → save workflow, per-operation recipes, licensing, the full API-surface tables, and troubleshooting — everything an agent needs to write correct redaction code without guessing. ## MCP server For on-demand documentation lookups, point your AI tool at the GroupDocs MCP server: ```json { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` This works with Claude Code (`~/.claude/settings.json`), Cursor (`.cursor/mcp.json`), VS Code Copilot (`.vscode/mcp.json`), and any MCP-compatible client. ## Machine-readable documentation LLM-optimized documentation for retrieval-augmented generation and context loading is available at [`https://docs.groupdocs.com/redaction/python-net/llms-full.txt`](https://docs.groupdocs.com/redaction/python-net/llms-full.txt). ## AGENTS.md reference The complete reference bundled inside the wheel is reproduced below. ````markdown # GroupDocs.Redaction for Python via .NET -- AGENTS.md > Instructions for AI agents working with this package. Permanently remove sensitive content from documents -- redact text by exact phrase or regex, scrub or rewrite metadata, replace or delete annotations, black out image regions, remove pages, and rasterize the result so nothing redacted can be recovered. Works across Word, Excel, PowerPoint, PDF, images, and text formats through one unified API, with no MS Office or external software installed. ## Install ```bash pip install groupdocs-redaction-net ``` **Python**: 3.5 - 3.14 | **Platforms**: Windows, Linux, macOS ## Resources | Resource | URL | |---|---| | Documentation | https://docs.groupdocs.com/redaction/python-net/ | | LLM-optimized docs | https://docs.groupdocs.com/redaction/python-net/llms-full.txt | | API reference | https://reference.groupdocs.com/redaction/python-net/ | | Code examples | https://docs.groupdocs.com/redaction/python-net/developer-guide/ | | Release notes | https://releases.groupdocs.com/redaction/python-net/release-notes/ | | PyPI | https://pypi.org/project/groupdocs-redaction-net/ | | Free support forum | https://forum.groupdocs.com/c/redaction/ | | Temporary license | https://purchase.groupdocs.com/temporary-license | ## MCP Server If your environment has MCP configured, you can connect your AI tool to the GroupDocs documentation server for on-demand API lookups: ```json { "mcpServers": { "groupdocs-docs": { "url": "https://docs.groupdocs.com/mcp" } } } ``` Works with Claude Code (`~/.claude/settings.json`), Cursor (`.cursor/mcp.json`), VS Code Copilot (`.vscode/mcp.json`), and any MCP-compatible client. If MCP is unavailable, fall back to the LLM-optimized docs URL above and this file -- both are shipped inside the wheel. ## Imports ```python from groupdocs.redaction import ( License, Metered, Redactor, RedactionPolicy, RedactionResult, RedactionStatus, RedactorChangeLog, RedactorLogEntry, FileType, IDocumentInfo, ) from groupdocs.redaction.redactions import ( # Text ExactPhraseRedaction, RegexRedaction, CellColumnRedaction, CellFilter, PageAreaRedaction, ReplacementOptions, RegionReplacementOptions, # Metadata EraseMetadataRedaction, MetadataSearchRedaction, MetadataFilters, # Annotations AnnotationRedaction, DeleteAnnotationRedaction, # Image / page ImageAreaRedaction, RemovePageRedaction, PageSeekOrigin, # Custom rules / callback ICustomRedactionHandler, CustomRedactionContext, CustomRedactionResult, IRedactionCallback, RedactionDescription, RedactionType, RedactionActionType, ) from groupdocs.redaction.options import ( LoadOptions, SaveOptions, RasterizationOptions, AdvancedRasterizationOptions, PdfComplianceLevel, PreviewOptions, PreviewFormats, RedactorSettings, ) from groupdocs.redaction.exceptions import ( GroupDocsRedactionException, DocumentFormatException, IncorrectPasswordException, PasswordRequiredException, TrialLimitationsException, ) from groupdocs.pydrawing import Color, Point, Size # for box / image-area redactions ``` ## Load + Apply + Save (the core workflow) `Redactor` is the entry point. The flow is always: **open → one or more `apply(...)` calls → `save()`**. Each redaction mutates the in-memory document, so you can apply several before a single save. Use `Redactor` as a context manager so the native document handle is released. ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions with Redactor("document.docx") as redactor: redactor.apply(ExactPhraseRedaction("confidential", ReplacementOptions("[REDACTED]"))) redactor.save() ``` **Redactor constructor.** `Redactor(file_path)` or `Redactor(stream)`, optionally with `load_options` and/or `RedactorSettings`: `Redactor(file_path, LoadOptions(password="..."))`, `Redactor(stream, LoadOptions(...), RedactorSettings(...))`. **`apply(...)`** accepts a single `Redaction`, a list of redactions, or a `RedactionPolicy`. It returns a `RedactorChangeLog` whose `.status` is a `RedactionStatus` (`APPLIED`, `PARTIALLY_APPLIED`, `SKIPPED`, `FAILED`). **`save(...)`** writes the current state and returns the output path (when saving to a file). **By default it rasterizes the document to a PDF and appends a `_Redacted` suffix.** To control this, pass `SaveOptions` or `RasterizationOptions` (see Rasterization below). ## Operations ### Text redaction (exact phrase / regex) ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ExactPhraseRedaction, RegexRedaction, ReplacementOptions from groupdocs.pydrawing import Color with Redactor("document.docx") as redactor: redactor.apply(ExactPhraseRedaction("John Doe", ReplacementOptions("[CUSTOMER]"))) # case-insensitive redactor.apply(ExactPhraseRedaction("ACME", True, ReplacementOptions("[CO]"))) # case-sensitive redactor.apply(RegexRedaction(r"\d{2,}", ReplacementOptions("[NUM]"))) # regex match redactor.apply(RegexRedaction(r"\bsecret\b", ReplacementOptions(Color.BLACK))) # draw a black box redactor.save() ``` `ReplacementOptions(text)` replaces the match with a string; `ReplacementOptions(Color)` draws a filled box over it. `ExactPhraseRedaction` also exposes `is_right_to_left`. `CellColumnRedaction(CellFilter, regex, ReplacementOptions)` targets a spreadsheet column. ### Metadata redaction ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import EraseMetadataRedaction, MetadataSearchRedaction, MetadataFilters with Redactor("document.docx") as redactor: redactor.apply(EraseMetadataRedaction(MetadataFilters.ALL)) # erase everything redactor.apply(EraseMetadataRedaction(MetadataFilters.AUTHOR)) # erase one field redactor.apply(MetadataSearchRedaction(".*@acme\\.com", "[EMAIL]")) # rewrite by value pattern redactor.save() ``` `MetadataFilters` is a flags-style enum: `AUTHOR`, `COMPANY`, `COMMENTS`, `MANAGER`, `TITLE`, `SUBJECT`, `KEYWORDS`, `CONTENT_STATUS`, … and `ALL`. `MetadataSearchRedaction(value_pattern, replacement, key_pattern=...)` can match on key and/or value. ### Annotation redaction ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import AnnotationRedaction, DeleteAnnotationRedaction with Redactor("document.pdf") as redactor: redactor.apply(AnnotationRedaction("(?i)approved", "[REVIEW]")) # rewrite annotation text redactor.apply(DeleteAnnotationRedaction("(?i)internal")) # delete matching annotations redactor.save() ``` ### Image-area and page-area redaction ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ImageAreaRedaction, PageAreaRedaction, RegionReplacementOptions, ReplacementOptions from groupdocs.pydrawing import Point, Size, Color with Redactor("scan.pdf") as redactor: # black out a fixed rectangle on every page redactor.apply(ImageAreaRedaction(Point(50, 60), RegionReplacementOptions(Color.BLACK, Size(200, 80)))) # redact text AND its image rendering in a page area redactor.apply(PageAreaRedaction(r"\d{3}-\d{2}-\d{4}", ReplacementOptions("[SSN]"), RegionReplacementOptions(Color.BLACK, Size(120, 20)))) redactor.save() ``` ### Page removal ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import RemovePageRedaction, PageSeekOrigin with Redactor("document.pdf") as redactor: redactor.apply(RemovePageRedaction(PageSeekOrigin.BEGIN, 0, 1)) # drop the first page redactor.save() ``` ### Custom redaction rule / callback A `RedactorSettings(callback=...)` receives every redaction description and decides whether to accept it. Pass a plain Python callable -- the binding wraps it as the .NET `IRedactionCallback` automatically. `RedactorSettings` is the **third** Redactor argument, after `load_options`, so pass `LoadOptions()` (or a configured one) as well. ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.redaction.options import LoadOptions, RedactorSettings def accept(description): # description.original_text, .redaction_type, .action_type return "keep-me" not in (description.original_text or "") # return False to skip this match with Redactor("document.docx", LoadOptions(), RedactorSettings(callback=accept)) as redactor: redactor.apply(ExactPhraseRedaction("secret", ReplacementOptions("[X]"))) redactor.save() ``` The callback returns `bool` (accept/reject) -- `IRedactionCallback.accept_redaction` returns a boolean. For text-rewriting rules use `ICustomRedactionHandler` via `ReplacementOptions.custom_redaction`. ### Rasterization (flatten to PDF) ```python from groupdocs.redaction import Redactor from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.redaction.options import SaveOptions, RasterizationOptions, AdvancedRasterizationOptions with Redactor("document.docx") as redactor: redactor.apply(ExactPhraseRedaction("secret", ReplacementOptions("[X]"))) # (a) default: rasterize to PDF, "_Redacted" suffix redactor.save() # (b) keep original format, no rasterization redactor.save(SaveOptions(rasterize_to_pdf=False)) # (c) rasterize with anti-extraction effects ro = RasterizationOptions() ro.enabled = True ro.add_advanced_option(AdvancedRasterizationOptions.NOISE) ro.add_advanced_option(AdvancedRasterizationOptions.GRAYSCALE) redactor.save(ro) ``` `RasterizationOptions`: `enabled`, `page_index`, `page_count`, `compliance` (`PdfComplianceLevel.AUTO` / `PDF_A1A`), `add_advanced_option(AdvancedRasterizationOptions.{TILT,NOISE,BORDER,GRAYSCALE})`. ### Save to a stream `save(stream, rasterization_options)` writes to any writable stream. Return a path-backed or `io.BytesIO` stream; `BytesIO` is updated after the call. ```python import io from groupdocs.redaction.options import RasterizationOptions with Redactor("document.docx") as redactor: redactor.apply(ExactPhraseRedaction("secret", ReplacementOptions("[X]"))) ro = RasterizationOptions(); ro.enabled = False # keep original format buf = io.BytesIO() redactor.save(buf, ro) data = buf.getvalue() ``` ### Redaction policy (reusable rule set) ```python from groupdocs.redaction import Redactor, RedactionPolicy from groupdocs.redaction.redactions import ExactPhraseRedaction, RegexRedaction, ReplacementOptions policy = RedactionPolicy([ ExactPhraseRedaction("ACME", ReplacementOptions("[CO]")), RegexRedaction(r"\d{2,}", ReplacementOptions("[NUM]")), ]) with Redactor("document.docx") as redactor: redactor.apply(policy=policy) redactor.save() ``` Build the policy in memory and reuse it across documents. (A policy can also be authored as an XML file and read with `RedactionPolicy.load(path)`.) ### Document info & preview ```python with Redactor("document.pdf") as redactor: info = redactor.get_document_info() print(info.file_type.file_format, info.page_count, info.size) ``` `get_document_info()` returns an `IDocumentInfo`: `file_type` (a `FileType`), `page_count`, `size`, `pages`. `generate_preview(PreviewOptions(...))` renders pages to images (`PreviewFormats.PNG`/`JPEG`/`BMP`) via a `create_page_stream(page_number)` callback that returns a writable file/path stream (not `BytesIO`). ## Licensing ```python from groupdocs.redaction import License # From file License().set_license("path/to/license.lic") # From stream with open("license.lic", "rb") as f: License().set_license(f) ``` Or auto-apply: `export GROUPDOCS_LIC_PATH="path/to/license.lic"` Metered licensing is also available: ```python from groupdocs.redaction import Metered Metered().set_metered_key("public-key", "private-key") print(Metered().get_consumption_quantity(), Metered().get_consumption_credit()) ``` **Evaluation vs licensed.** Without a license the library still runs, but **only one document may be opened per process** (subsequent opens raise a trial-limitation error), PDF output carries an evaluation watermark, and other formats show an equivalent evaluation mark. Set `GROUPDOCS_LIC_PATH` (or call `License().set_license(...)`) and re-run to clear these. A 30-day full license is free: https://purchase.groupdocs.com/temporary-license ## API Reference ### Redactor | Method | Returns | Description | |---|---|---| | `Redactor(file_path / stream [, load_options [, settings]])` | | Open by path or binary stream; optional `LoadOptions` and `RedactorSettings`. Use as a context manager. | | `apply(redaction)` / `apply(redactions=[...])` / `apply(policy=...)` | `RedactorChangeLog` | Apply one redaction, a list, or a `RedactionPolicy`. `.status` is a `RedactionStatus`. | | `save([save_options])` | `str` | Write to disk; default rasterizes to PDF + `_Redacted` suffix. Returns the output path. | | `save(stream [, rasterization_options])` | `str` | Write to a stream (file/path stream or `io.BytesIO`). | | `generate_preview(preview_options)` | `None` | Render pages to images via a `create_page_stream` callback. | | `get_document_info()` | `IDocumentInfo` | `file_type`, `page_count`, `size`, `pages`. | | `dispose()` | `None` | Release native resources (handled by `with`). | ### Redactions | Type | Notes | |---|---| | `ExactPhraseRedaction(phrase [, is_case_sensitive], options)` | Replace/box an exact phrase. `is_right_to_left` for RTL. | | `RegexRedaction(pattern, options)` | Replace/box a regex match. | | `CellColumnRedaction(CellFilter, regex, options)` | Redact a spreadsheet column. | | `PageAreaRedaction(regex, options, RegionReplacementOptions)` | Text + image redaction over a page area. | | `EraseMetadataRedaction(MetadataFilters)` | Erase metadata by filter. | | `MetadataSearchRedaction(value_pattern, replacement [, key_pattern])` | Rewrite metadata by key/value pattern. | | `AnnotationRedaction(pattern, replacement)` / `DeleteAnnotationRedaction(pattern)` | Rewrite or delete annotations. | | `ImageAreaRedaction(Point, RegionReplacementOptions)` | Black out a rectangle on a page. | | `RemovePageRedaction(PageSeekOrigin, index, count)` | Remove pages from the start/end. | | `ReplacementOptions(text)` / `ReplacementOptions(Color)` | Text replacement vs. a filled box. `filters`, `custom_redaction`. | | `RegionReplacementOptions(fill_color, size [, font, expected_text])` | Box geometry for image/page-area redactions. | ### Options & enums | Type | Notes | |---|---| | `LoadOptions(password=..., pre_rasterize=...)` | Open protected / pre-rasterized input. | | `SaveOptions(rasterize_to_pdf=..., suffix=...)` | Control format + `_Redacted` suffix. | | `RasterizationOptions()` | `enabled`, `page_index`, `page_count`, `compliance`, `add_advanced_option(...)`. | | `AdvancedRasterizationOptions` | `NONE`, `TILT`, `NOISE`, `BORDER`, `GRAYSCALE`. | | `PdfComplianceLevel` | `AUTO`, `PDF_A1A`. | | `PreviewOptions(create_page_stream [, release_page_stream])` | `width`, `height`, `page_numbers`, `preview_format`. | | `PreviewFormats` | `PNG`, `JPEG`, `BMP`. | | `RedactorSettings(logger=..., callback=..., ocr_connector=...)` | Inject a logger, an `IRedactionCallback`, or OCR. | | `MetadataFilters` | `AUTHOR`, `COMPANY`, `COMMENTS`, `MANAGER`, `TITLE`, `SUBJECT`, `KEYWORDS`, …, `ALL`. | | `RedactionStatus` | `APPLIED`, `PARTIALLY_APPLIED`, `SKIPPED`, `FAILED`. | | `RedactionType` / `RedactionActionType` | `TEXT`/`METADATA`/`ANNOTATION`/`IMAGE_AREA`/`PAGE`; `REPLACEMENT`/`CLEANUP`/`DELETION`. | | `PageSeekOrigin` | `BEGIN`, `END`. | ### License / Metered `License().set_license(path_or_stream)` · `Metered().set_metered_key(public, private)` · `Metered().get_consumption_quantity()` · `Metered().get_consumption_credit()` ## Key Patterns - **Properties**: use `snake_case` -- auto-mapped to .NET `PascalCase` - **Context managers**: `with Redactor(...) as r:` ensures the document handle is released - **Chaining**: each `apply()` mutates in place; run several before one `save()` - **Default save rasterizes**: `save()` produces a PDF + `_Redacted` suffix; pass `SaveOptions(rasterize_to_pdf=False)` to keep the source format - **Colors / geometry**: `Color`, `Point`, `Size` come from `groupdocs.pydrawing`; `ReplacementOptions(Color)` draws a box - **Regex args**: pass a plain Python regex string -- the binding wraps it as a .NET `Regex` - **Streams**: pass `open("file", "rb")` or `io.BytesIO(data)` where .NET expects a Stream; `BytesIO` is updated after `save(stream)` - **Enums**: case-insensitive, lazy-loaded (e.g., `MetadataFilters.ALL`, `PreviewFormats.PNG`) - **Callbacks**: a Python callable is accepted for `IRedactionCallback`; it returns `bool` to accept/reject each match - **Exceptions**: catch `PasswordRequiredException` / `IncorrectPasswordException` / `DocumentFormatException` / `TrialLimitationsException` (all subclass `GroupDocsRedactionException`) ## Platform Requirements | Platform | Requirements | |---|---| | Windows | None | | Linux | `apt install libgdiplus libfontconfig1 ttf-mscorefonts-installer` | | macOS | `brew install mono-libgdiplus` | ## Troubleshooting **`Trial mode allows only 1 document to open` / `TrialLimitationsException`** -- no license. Apply one with `License().set_license(...)` or set `GROUPDOCS_LIC_PATH`; a free 30-day license is at https://purchase.groupdocs.com/temporary-license **`PasswordRequiredException` / `IncorrectPasswordException`** -- the source is encrypted. Open it with `Redactor(path, LoadOptions(password="..."))`. **`DocumentFormatException`** -- the file format isn't supported or the file is corrupted. Check it against the supported-formats list. **`System.Drawing.Common is not supported`** -- install libgdiplus: `sudo apt install libgdiplus` (Linux) / `brew install mono-libgdiplus` (macOS) **`Gdip` type initializer exception** -- outdated libgdiplus: `brew reinstall mono-libgdiplus` (macOS) **Garbled text / missing fonts** -- install fonts: `sudo apt install ttf-mscorefonts-installer fontconfig && sudo fc-cache -f` **`DllNotFoundException: libSkiaSharp`** -- stale system copy conflicts with bundled version. Rename it: `sudo mv /usr/local/lib/libSkiaSharp.dylib /usr/local/lib/libSkiaSharp.dylib.bak` **`DOTNET_SYSTEM_GLOBALIZATION_INVARIANT` errors** -- do NOT set this. Install ICU: `sudo apt install libicu-dev` **`TypeLoadException`** -- reinstall: `pip install --force-reinstall groupdocs-redaction-net` **Still stuck?** Post your question at https://forum.groupdocs.com/c/redaction/ -- the development team responds directly. ```` --- ## Extend supported extensions list Path: /redaction/python-net/extend-supported-extensions-list/ This method can be used when for some reason files have non-standard extensions or if its format is supported, but not pre-configured. For instance, all kinds of plain text files (batch, command files, etc.) could be opened. In this case you do not need to create your own format handler. As it is shown below, you can add file extension (e.g. ".dump") as being handled by the same *[DocumentFormatInstance](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.integration/documentformatinstance/)* as all plain text files: {{< tabs "code-example-extend-supported-extensions-list" >}} {{< tab "extend_supported_extensions_list.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.configuration import RedactorConfiguration from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def extend_supported_extensions_list(): # Add the .dump format to the list of supported formats, handled as plain text config = RedactorConfiguration.get_instance() settings = config.find_format(".txt") settings.extension_filter = settings.extension_filter + ",.dump" # Specify the redaction options repl_opt = ReplacementOptions("[redacted]") ex_red = ExactPhraseRedaction("dolor", repl_opt) # Load the document with the newly supported extension with Redactor("./sample.dump") as redactor: # Apply the redaction redactor.apply(ex_red) # Save the redacted document save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" result_path = redactor.save(save_options) print(f"Document redacted successfully.\nCheck output in {result_path}.") if __name__ == "__main__": extend_supported_extensions_list() ``` {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1.9 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/extend-supported-extensions-list/extend_supported_extensions_list/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} In detail, creating your own document format instances is covered in another article. --- ## Metadata redactions Path: /redaction/python-net/metadata-redactions/ With GroupDocs.Redaction API you can apply metadata redactions for documents of different formats like PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX and others. See full list at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article. GroupDocs.Redactions provides a flexible API that allows to replace or remove metadata using filters or search by regular expression. ## Filter metadata Base functionality for all redactions, derived from [MetadataRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadataredaction/) base class is *metadata filtering* and it is mandatory for metadata redactions. It uses flagged enumeration [MetadataFilters](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatafilters/), containing items for most frequent metadata entries. You can set the filter to *All*, or any combination of metadata. For instance, the example below sets filter to *Author*, *Manager* and *NameOfApplication* - for textual redaction or cleaning them out: ```python # redaction derived from MetadataRedaction redaction.filter = MetadataFilters.AUTHOR | MetadataFilters.MANAGER | MetadataFilters.NAME_OF_APPLICATION ``` Below is the table with full list of [MetadataFilters](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatafilters/) items: | Filter | Numeric value | Description | | --- | --- | --- | | *None* | 0 | Empty filter setting, matches no metadata items | | *Author* | 1 | Author of the document | | *Category* | 2 | Category of the document | | *Comments* | 4 | Document comment | | *Company* | 8 | Company of the Author | | *ContentStatus* | 16 | Content status | | *CreatedTime* | 32 | Created time | | *HyperlinkBase* | 64 | Hyperlink base | | *LastPrinted* | 128 | Last printed date and time | | *LastSavedBy* | 256 | Last saved by user | | *LastSavedTime* | 1024 | Last saved date and time | | *NameOfApplication* | 2048 | Name of application where the document was created | | *Manager* | 4096 | Author's manager name | | *RevisionNumber* | 8192 | Revision number | | *Subject* | 16384 | Subject of the document | | *Template* | 32768 | Document template name | | *Title* | 65536 | Document title | | *TotalEditingTime* | 131072 | Total editing time | | *Version* | 262144 | Document's version | | *Description* | 524288 | Document's description | | *Keywords* | 1048576 | Document's keywords | | *ContentType* | 2097152 | Content type | | *All* | 2147483647 | All types of the metadata items | ## Clean metadata You can replace all or specific metadata in the document with empty (blank or minimal) values using [EraseMetadataRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/erasemetadataredaction/) class. The example below blanks out all properties of the document: {{< tabs "code-example-clean-all-metadata" >}} {{< tab "clean_all_metadata.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import EraseMetadataRedaction, MetadataFilters def clean_all_metadata(): # Specify the redaction options to erase all metadata met_red = EraseMetadataRedaction(MetadataFilters.ALL) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(met_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": clean_all_metadata() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/metadata-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/metadata-redactions/clean_all_metadata/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} You can specify [MetadataFilter.All](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatafilters/) or use default constructor to blank out all metadata within given document, Custom - to clear all custom metadata entries. ## Redact metadata You can use [MetadataSearchRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatasearchredaction/) to remove sensitive data from document's metadata using regular expressions. For instance, we can remove any mention of "Company Ltd.": {{< tabs "code-example-redact-metadata" >}} {{< tab "redact_metadata.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import MetadataSearchRedaction def redact_metadata(): # Specify the redaction options: search pattern and replacement string met_red = MetadataSearchRedaction("Company Ltd.", "--company--") # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(met_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_metadata() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/metadata-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/metadata-redactions/redact_metadata/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} First argument is regular expression, second is a replacement string. You can also set scope for redaction by setting filter, e.g. to [MetadataFilter.Company](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/metadatafilters/). - it will leave the regular expressions matches undone in all metadata items, except "Company" property: {{< tabs "code-example-redact-metadata-with-filter" >}} {{< tab "redact_metadata_with_filter.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import MetadataSearchRedaction, MetadataFilters def redact_metadata_with_filter(): # Specify the redaction options: search pattern and replacement string met_red = MetadataSearchRedaction("Company Ltd.", "--company--") # Limit the redaction scope to the Company metadata item only met_red.filter = MetadataFilters.COMPANY # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(met_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_metadata_with_filter() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/metadata-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.docx" >}} ```text Binary file (DOCX, 16 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/metadata-redactions/redact_metadata_with_filter/sample_redacted.docx) {{< /tab >}} {{< /tabs >}} ## Metadata redaction status All metadata redactions apply to each metadata item separately, and even if metadata item redaction fails, the rest of the metadata items will be updated. You can find a list of failed, skipped (rejected) metadata items and reasons for that in [ErrorMessage](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionresult/error_message/) property of [RedactorLogEntry.Result](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorlogentry/result/). --- ## Save to Stream Path: /redaction/python-net/save-to-stream/ You might need to save a document to any custom file at any location on the local disc or a even a Stream. The following example demonstrates how to save a document to any location. {{< tabs "code-example-save-to-stream" >}} {{< tab "save_to_stream.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import RasterizationOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions from groupdocs.pydrawing import Color def save_to_stream(): # Define the color of redaction color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = ReplacementOptions(color) ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction result = redactor.apply(ex_red) if result.status != RedactionStatus.FAILED: # Save the document to a stream and convert its pages to images ro = RasterizationOptions() ro.enabled = True with open("./redacted-sample.pdf", "wb") as stream_out: redactor.save(stream_out, ro) print("Document redacted successfully.\nCheck output in ./redacted-sample.pdf") else: print("Redaction failed!") if __name__ == "__main__": save_to_stream() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/save-to-stream/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "redacted-sample.pdf" >}} ```text Binary file (PDF, 1024 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/save-to-stream/save_to_stream/redacted-sample.pdf) {{< /tab >}} {{< /tabs >}} --- ## System Requirements Path: /redaction/python-net/system-requirements/ {{< alert style="info" >}} GroupDocs.Redaction for Python via .NET operates independently of external software like Microsoft Word, Excel, PowerPoint, or Adobe Acrobat. To install it, simply follow one of the methods described in the [Installation]({{< ref "redaction/python-net/getting-started/installation.md" >}}) section. {{< /alert >}} ## Overview GroupDocs.Redaction for Python via .NET does not require Microsoft Office, OpenOffice, Adobe Acrobat, or any other external software to be installed. The package is a self-contained wheel that bundles everything it needs, so the only prerequisites are a supported version of Python and the operating-system packages listed below. ## Supported Python Versions GroupDocs.Redaction for Python via .NET supports the following Python versions: * Python 3.5 * Python 3.6 * Python 3.7 * Python 3.8 * Python 3.9 * Python 3.10 * Python 3.11 * Python 3.12 * Python 3.13 * Python 3.14 ## Supported Operating Systems The package is distributed as a self-contained wheel that runs on the following platforms: ### Windows * Windows x64 No additional dependencies are required on Windows. ### Linux * Linux x64 On Linux you need to install a few system packages for graphics, fonts, and globalization: ```bash apt install libgdiplus libfontconfig1 libicu-dev ttf-mscorefonts-installer ``` ### macOS * macOS x64 (Intel) * macOS ARM64 (Apple Silicon) On macOS install the graphics library via Homebrew: ```bash brew install mono-libgdiplus ``` ## Platform-Specific Feature Support {{< alert style="warning" >}} **Rasterization to PDF and image-area redaction currently require Windows.** In version 26.6.0 the bundled engine renders rasterized output and processes images through `System.Drawing.Common`, which the embedded .NET runtime supports only on Windows. On Linux and macOS these specific operations raise a `System.PlatformNotSupportedException` ("System.Drawing.Common is not supported on this platform"). Installing `libgdiplus` / `mono-libgdiplus` does **not** lift this restriction. {{< /alert >}} The following redaction operations work on **all** platforms — Windows, Linux, and macOS: * Text redaction (exact phrase and regular expression) * Metadata redaction (erase, and search-and-replace) * Annotation redaction (rewrite and delete) * Page removal * Saving in the **original** format with `SaveOptions(rasterize_to_pdf=False)` The following operations currently require **Windows**: * The default `save()` — which rasterizes the result to a PDF — and any `RasterizationOptions` or rasterized-PDF save path * `ImageAreaRedaction` and image cleaning / image-export operations On Linux and macOS, keep the source format with `SaveOptions(rasterize_to_pdf=False)`, or perform the rasterization and image-redaction steps on Windows. ## No Third-Party Software Required Unlike many document-processing tools, GroupDocs.Redaction for Python via .NET does not depend on Microsoft Office, OpenOffice, Adobe Acrobat, or any other application being installed on the machine. All loading, redacting, and saving of Word Processing documents, Spreadsheets, Presentations, PDFs, and images is performed entirely by the bundled engine. --- ## Annotation redactions Path: /redaction/python-net/annotation-redactions/ With GroupDocs.Redaction API you can apply annotation redactions for documents of different formats like PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX and others. See full list at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article. GroupDocs.Redactions provides a flexible API that allows to remove sensitive data from annotation text, or completely remove annotations by a regular expression. ## Remove annotations (comments etc) You can use GroupDocs.Redaction to remove all or specific comments and other annotations from the document. For example, we can remove all comments from the document, containing texts like "use", "show" or "describe" in its body: {{< tabs "code-example-remove-all-annotations" >}} {{< tab "remove_all_annotations.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import DeleteAnnotationRedaction def remove_all_annotations(): # Specify the redaction options to delete annotations matching the pattern a_red = DeleteAnnotationRedaction("(?im:(use|show|describe))") # Load the document to be redacted with Redactor("./annotated.xlsx") as redactor: # Apply the redaction result = redactor.apply(a_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": remove_all_annotations() ``` {{< /tab >}} {{< tab "annotated.xlsx" >}} {{< tab-text >}} `annotated.xlsx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/annotation-redactions/annotated.xlsx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "annotated_redacted.xlsx" >}} ```text Binary file (XLSX, 12 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/annotation-redactions/remove_all_annotations/annotated_redacted.xlsx) {{< /tab >}} {{< /tabs >}} You can use constructor without arguments to remove all annotations within the document. ## Redact annotations Instead of removing all or specific annotations, you can remove sensitive data from the annotation text. For instance, we can remove all mentions of "John" in the given document, e.g.: {{< tabs "code-example-redact-annotations" >}} {{< tab "redact_annotations.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import AnnotationRedaction def redact_annotations(): # Specify the redaction options: search pattern and replacement string a_red = AnnotationRedaction("(?im:john)", "[redacted]") # Load the document to be redacted with Redactor("./annotated.xlsx") as redactor: # Apply the redaction result = redactor.apply(a_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_annotations() ``` {{< /tab >}} {{< tab "annotated.xlsx" >}} {{< tab-text >}} `annotated.xlsx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/annotation-redactions/annotated.xlsx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "annotated_redacted.xlsx" >}} ```text Binary file (XLSX, 12 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/annotation-redactions/redact_annotations/annotated_redacted.xlsx) {{< /tab >}} {{< /tabs >}} --- ## How to Run Examples Path: /redaction/python-net/how-to-run-examples/ {{< alert style="warning" >}}Before running an example make sure that GroupDocs.Redaction for Python via .NET has been installed successfully.{{< /alert >}} The complete examples project for **GroupDocs.Redaction for Python via .NET** is hosted on [GitHub](https://github.com/groupdocs-redaction/GroupDocs.Redaction-for-Python-via-.NET). It contains standalone, runnable scripts together with the sample documents they use, so the examples work out of the box. ## Prerequisites - [Python](https://www.python.org/) 3.5 – 3.14 installed and on your `PATH`. - [git](https://git-scm.com/) to clone the repository (or download the ZIP). - On Linux and macOS, the native libraries listed in the [System Requirements]({{< ref "redaction/python-net/getting-started/system-requirements.md" >}}) (`libgdiplus`, `libfontconfig1`, `libicu-dev`, and fonts). - Optionally, a GroupDocs.Redaction license to remove the [evaluation limitations]({{< ref "redaction/python-net/getting-started/licensing-and-subscription.md" >}}). ## Get the code Clone the repository with your favourite git client, or download the ZIP from GitHub: ```bash git clone https://github.com/groupdocs-redaction/GroupDocs.Redaction-for-Python-via-.NET.git cd GroupDocs.Redaction-for-Python-via-.NET ``` ## Project Structure The examples live under the `Examples/` folder, organized by topic. Directory names are kebab-case and each script is standalone: ```text GroupDocs.Redaction-for-Python-via-.NET/ ├── Dockerfile └── Examples/ ├── requirements.txt ├── run_all_examples.py ├── licensing/ │ └── set_license_from_file.py ├── getting-started/ │ └── hello-world/ │ └── hello_world.py └── developer-guide/ ├── basic-usage/ │ ├── text-redactions.py │ ├── metadata-redactions.py │ ├── image-redactions.py │ ├── annotation-redactions.py │ └── remove-page-redactions.py └── advanced-usage/ ├── use-redaction-policies.py ├── loading-documents/ └── saving-documents/ ``` ## Setup Create and activate a virtual environment, then install the dependencies listed in `Examples/requirements.txt`: {{< tabs "setup-venv">}} {{< tab "Windows" >}} ```ps py -m venv .venv .venv\Scripts\activate py -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< tab "Linux" >}} ```bash python3 -m venv .venv source .venv/bin/activate python3 -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< tab "macOS" >}} ```bash python3 -m venv .venv source .venv/bin/activate python3 -m pip install -r Examples/requirements.txt ``` {{< /tab >}} {{< /tabs >}} To run the examples without evaluation limitations, point the `GROUPDOCS_LIC_PATH` environment variable at your license file. The example scripts read this variable and apply the license automatically: {{< tabs "setup-license">}} {{< tab "Windows" >}} ```ps $env:GROUPDOCS_LIC_PATH = "C:\path\to\GroupDocs.Redaction.lic" ``` {{< /tab >}} {{< tab "Linux" >}} ```bash export GROUPDOCS_LIC_PATH="/path/to/GroupDocs.Redaction.lic" ``` {{< /tab >}} {{< tab "macOS" >}} ```bash export GROUPDOCS_LIC_PATH="/path/to/GroupDocs.Redaction.lic" ``` {{< /tab >}} {{< /tabs >}} See [Licensing and Evaluation]({{< ref "redaction/python-net/getting-started/licensing-and-subscription.md" >}}) for details on obtaining and applying a license. ## Run Run every example at once with the runner script: ```bash python Examples/run_all_examples.py ``` Or run a single example by passing its path directly: ```bash python Examples/developer-guide/basic-usage/text-redactions.py ``` The repository ships with all the sample documents and resources used by the examples, so the scripts run out of the box. {{< alert style="info" >}}Without a license the examples run in evaluation mode, which raises a `TrialLimitationsException` if more than one document is opened in the same process. The `run_all_examples.py` runner launches each example in its own process so they all complete even unlicensed, but redaction output is limited (one redaction per document, up to four replacements, and trial badges on each page).{{< /alert >}} ## Run with Docker The repository includes a `Dockerfile` that installs the native dependencies and Python packages so you can run the examples in a clean, reproducible container. From the repository root: ```bash docker build -t groupdocs-redaction-examples . docker run --rm groupdocs-redaction-examples ``` To use a license inside the container, mount it and pass `GROUPDOCS_LIC_PATH`: ```bash docker run --rm \ -v /path/to/GroupDocs.Redaction.lic:/app/GroupDocs.Redaction.lic:ro \ -e GROUPDOCS_LIC_PATH=/app/GroupDocs.Redaction.lic \ groupdocs-redaction-examples ``` ## Continuous integration Because the examples run headlessly and exit with a non-zero status on failure, they fit naturally into a CI pipeline. Install `Examples/requirements.txt`, supply the license through the `GROUPDOCS_LIC_PATH` environment variable (store the license as a protected secret), make sure the Linux native dependencies are present on the runner, and invoke `python Examples/run_all_examples.py` as a build step. The provided `Dockerfile` is a convenient base image for such jobs. ## Troubleshooting - **"…rasterization / image-export step is not supported on this platform" on Linux/macOS** — expected on non-Windows in 26.6.0. The rasterized-PDF and image-redaction paths use `System.Drawing.Common`, which the bundled runtime supports only on Windows, so they raise `System.PlatformNotSupportedException`. The `run_all_examples.py` runner catches this and logs the note so the suite still completes; the example's text/metadata/annotation steps still run. To exercise rasterization and image redaction, run on Windows, or save in the original format with `SaveOptions(rasterize_to_pdf=False)`. See [System Requirements]({{< ref "redaction/python-net/getting-started/system-requirements.md" >}}) for the full platform-support matrix. Installing `libgdiplus` does **not** remove this restriction. - **Missing or substituted fonts** — install fonts so rasterized output (on Windows) matches the original: `apt install libfontconfig1 ttf-mscorefonts-installer`. - **ICU / globalization errors on Linux** — install ICU: `apt install libicu-dev`. - **`TrialLimitationsException`** — you are running unlicensed in evaluation mode, which permits only one document open per process, one redaction, and up to four replacements. Set `GROUPDOCS_LIC_PATH` to a valid license to remove these limits. ## Contribute If you would like to add or improve an example, we encourage you to contribute to the project. All examples in this repository are open source and can be freely used in your own applications. To contribute, fork the repository, edit the code, and create a pull request. We will review the changes and include them if found helpful. --- ## Technical Support Path: /redaction/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 the [Free Support Forum](https://forum.groupdocs.com/) and the [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.Redaction, consider the following: * Make sure you are using the latest GroupDocs.Redaction version before reporting an issue. See [PyPI](https://pypi.org/project/groupdocs-redaction-net) to find out about the latest version. * Have a look through the forums, this documentation, and the [API Reference](https://reference.groupdocs.com/redaction/python-net/) before reporting an issue – perhaps your question has already been answered. * Post your question at the [GroupDocs.Redaction Free Support Forum](https://forum.groupdocs.com/c/redaction), and we'll assist you. Questions are answered directly by the GroupDocs.Redaction development team. * When expecting a reply on the forums, please allow for time zone differences. ## Paid Support Helpdesk Paid support issues have higher priority compared to free support requests. * Post your question at the [Paid Support Helpdesk](https://helpdesk.groupdocs.com/) to set a higher priority for the issue. ## Report an Issue or Feature Request When posting your issue, question, or feature request with GroupDocs.Redaction, follow these simple steps to make sure it is resolved in the most efficient way: * Include the original document and, if possible, 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 the 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 in — operating system, Python version, and GroupDocs.Redaction version. * Try to report one issue per thread. If you have another issue, question, or feature request, please report it in a separate thread. --- ## Use advanced rasterization options Path: /redaction/python-net/use-advanced-rasterization-options/ ## Use advanced rasterization options In order to use the advanced rasterization options you have to pass one of the options to [Save](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactor/save/) method. In this case the document will be rasterized to PDF, but the scan-like effects will be applied to its pages. The following example demonstrates how to apply the [AdvancedRasterizationOptions](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.options/advancedrasterizationoptions/) with default settings. {{< tabs "code-example-use-advanced-rasterization-options" >}} {{< tab "use_advanced_rasterization_options.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions, AdvancedRasterizationOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def use_advanced_rasterization_options(): # Specify the redaction options repl_opt = ReplacementOptions("[personal]") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction redactor.apply(ex_red) # Save the document with advanced options (convert pages into images, and save PDF with scan-like pages) so = SaveOptions() so.rasterization.enabled = True so.redacted_file_suffix = "_scan" so.rasterization.add_advanced_option(AdvancedRasterizationOptions.BORDER) so.rasterization.add_advanced_option(AdvancedRasterizationOptions.NOISE) so.rasterization.add_advanced_option(AdvancedRasterizationOptions.GRAYSCALE) so.rasterization.add_advanced_option(AdvancedRasterizationOptions.TILT) result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}") if __name__ == "__main__": use_advanced_rasterization_options() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/use-advanced-rasterization-options/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample.pdf" >}} ```text Binary file (PDF, 1.0 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/use-advanced-rasterization-options/use_advanced_rasterization_options/sample.pdf) {{< /tab >}} {{< /tabs >}} ### Use grayscale rasterization option The following example demonstrates how to apply the grayscale advanced rasterization option. {{< tabs "code-example-use-grayscale-rasterization-option" >}} {{< tab "use_grayscale_rasterization_option.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions, AdvancedRasterizationOptions def use_grayscale_rasterization_option(): # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Save the document with the custom grayscale effect so = SaveOptions() so.rasterization.enabled = True so.redacted_file_suffix = "_scan" so.rasterization.add_advanced_option(AdvancedRasterizationOptions.GRAYSCALE) result_path = redactor.save(so) print(f"Document redacted successfully.\nCheck output in {result_path}") if __name__ == "__main__": use_grayscale_rasterization_option() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/saving-documents/use-advanced-rasterization-options/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample.pdf" >}} ```text Binary file (PDF, 979 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/saving-documents/use-advanced-rasterization-options/use_grayscale_rasterization_option/sample.pdf) {{< /tab >}} {{< /tabs >}} --- ## Create PDF with Image Redaction Path: /redaction/python-net/create-pdf-with-image-redaction/ In some cases you might need to redact the pages of a document as images, redacting entire areas of the page instead or in addition to a specific text. With GroupDocs.Redaction you can use the following approach: * open the document and apply all required redactions to the document's body (text, annotations, etc.); * save it as a rasterized PDF file (containing images of the original document's pages); * apply ImageAreaRedaction to remove specific areas on the pages within the PDF document. The following example demonstrates how to create a rasterized PDF from a Microsoft Word document and apply image redactions to its pages: {{< tabs "code-example-create-pdf-with-image-redaction" >}} {{< tab "create_pdf_with_image_redaction.py" >}} ```python from io import BytesIO from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import RasterizationOptions from groupdocs.redaction.redactions import ImageAreaRedaction, RegionReplacementOptions from groupdocs.pydrawing import Point, Size, Color def create_pdf_with_image_redaction(): # Create an in-memory binary stream stream = BytesIO() # Load the document and rasterize it to a PDF in the stream with Redactor("./sample.docx") as redactor: # Save the rasterized document to the stream ro = RasterizationOptions() ro.enabled = True redactor.save(stream, ro) stream.seek(0) # Define the position on the image sample_point = Point(40, 160) # Define the size of the area which needs to be redacted sample_size = Size(350, 75) # Define the color of redaction color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = RegionReplacementOptions(color, sample_size) img_red = ImageAreaRedaction(sample_point, repl_opt) # Load the stream to be redacted with Redactor(stream) as redactor: # Apply the redaction result = redactor.apply(img_red) # Re-open the rasterized PDF document to redact its pages as images if result.status != RedactionStatus.FAILED: # Save the document to a file and convert its pages to images ro = RasterizationOptions() ro.enabled = True with open("./redacted-sample.pdf", "wb") as stream_out: redactor.save(stream_out, ro) print("Document redacted successfully.\nCheck output in ./redacted-sample.pdf") else: print("Redaction failed!") if __name__ == "__main__": create_pdf_with_image_redaction() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/advanced-usage/create-pdf-with-image-redaction/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "redacted-sample.pdf" >}} ```text Binary file (PDF, 879 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/advanced-usage/create-pdf-with-image-redaction/create_pdf_with_image_redaction/redacted-sample.pdf) {{< /tab >}} {{< /tabs >}} Please, note that you don't have to use GroupDocs.Redaction to create a rasterized PDF from an office document. You will be able to use it, if you don't have any other tool for that. --- ## Spreadsheet redactions Path: /redaction/python-net/spreadsheet-redactions/ GroupDocs.Redaction allows to redact data of sensitive or private nature from your XLS, XLSX, ODS spreadsheet document formats and others. See full list at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article. ## Redact spreadsheet content {{< tabs "code-example-redact-spreadsheet-content" >}} {{< tab "redact_spreadsheet_content.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ExactPhraseRedaction, ReplacementOptions def redact_spreadsheet_content(): # Specify the redaction options repl_opt = ReplacementOptions("-redacted-") ex_red = ExactPhraseRedaction("John Doe", repl_opt) # Load the spreadsheet to be redacted with Redactor("./sample.xlsx") as redactor: # Apply the redaction result = redactor.apply(ex_red) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": redact_spreadsheet_content() ``` {{< /tab >}} {{< tab "sample.xlsx" >}} {{< tab-text >}} `sample.xlsx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/spreadsheet-redactions/sample.xlsx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.xlsx" >}} ```text Binary file (XLSX, 15 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/spreadsheet-redactions/redact_spreadsheet_content/sample_redacted.xlsx) {{< /tab >}} {{< /tabs >}} --- ## Image redactions Path: /redaction/python-net/image-redactions/ GroupDocs.Redactions provides a set of features to redact data of sensitive nature from images of various formats like JPG, PNG, TIFF and others. See full list at [supported document formats]({{< ref "redaction/python-net/getting-started/supported-document-formats.md" >}}) article. GroupDocs.Redaction supports two ways of redacting images, both in separate image files and embedded images: * You can put a colored box over a given area, such as header, footer, or an area, where customer's data are expected to appear. * You can use any 3-rd party OCR engine to process the image, search it for text and redact sensitive data within the image. GroupDocs.Redaction for Python via .NET also allows you to change image metadata (e.g. edit EXIF data of an image or act as an "EXIF eraser"). ## Redact image area In order to redact image area, you have to use [ImageAreaRedaction](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction.redactions/imagearearedaction/) class: {{< tabs "code-example-redact-image-area" >}} {{< tab "redact_image_area.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ImageAreaRedaction, RegionReplacementOptions from groupdocs.pydrawing import Color, Point, Size def redact_image_area(): # Define the top-left position of the area to redact sample_point = Point(385, 485) # Define the size of the area which needs to be redacted sample_size = Size(1793, 2069) # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = RegionReplacementOptions(color, sample_size) img_red = ImageAreaRedaction(sample_point, repl_opt) # Load the document to be redacted with Redactor("./sample.jpg") as redactor: # Apply the redaction result = redactor.apply(img_red) if result.status != RedactionStatus.FAILED: # By default, the redacted document is saved in PDF format save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" redactor.save(save_options) if __name__ == "__main__": redact_image_area() ``` {{< /tab >}} {{< tab "sample.jpg" >}} {{< tab-text >}} `sample.jpg` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/image-redactions/sample.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 2.7 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/image-redactions/redact_image_area/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} If the redaction cannot be applied to this type of files, e.g. MS Word document without embedded images, [RedactorChangeLog.Status](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorchangelog/status/) will be [RedactionStatus.Skipped](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionstatus/). ## Clean image metadata The following example demonstrates how to edit exif data (erase them) from a photo or any other image: {{< tabs "code-example-clean-image-metadata" >}} {{< tab "clean_image_metadata.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import EraseMetadataRedaction, MetadataFilters def clean_image_metadata(): # Specify the redaction options to remove all image metadata (e.g. EXIF) er_opt = EraseMetadataRedaction(MetadataFilters.ALL) # Load the image to be redacted with Redactor("./sample.jpg") as redactor: # Apply the redaction result = redactor.apply(er_opt) # Save the redacted image next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": clean_image_metadata() ``` {{< /tab >}} {{< tab "sample.jpg" >}} {{< tab-text >}} `sample.jpg` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/image-redactions/sample.jpg) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.jpg" >}} ```text Binary file (JPG, 3.1 MB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/image-redactions/clean_image_metadata/sample_redacted.jpg) {{< /tab >}} {{< /tabs >}} If the redaction cannot be applied to this type of files, e.g. BMP image, [RedactorChangeLog.Status](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorchangelog/status/) will be [RedactionStatus.Skipped](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionstatus/). ## Redact embedded images You can redact image area within all kinds of embedded images inside a document. The following example demonstrates how to redact all embedded images within a Microsoft Word document: {{< tabs "code-example-redact-embedded-images" >}} {{< tab "redact_embedded_images.py" >}} ```python from groupdocs.redaction import Redactor, RedactionStatus from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import ImageAreaRedaction, RegionReplacementOptions from groupdocs.pydrawing import Color, Point, Size def redact_embedded_images(): # Define the top-left position of the area to redact sample_point = Point(516, 311) # Define the size of the area which needs to be redacted sample_size = Size(170, 35) # Define the color of the redaction box color = Color.from_argb(255, 220, 20, 60) # Specify the redaction options repl_opt = RegionReplacementOptions(color, sample_size) img_red = ImageAreaRedaction(sample_point, repl_opt) # Load the document to be redacted with Redactor("./sample.docx") as redactor: # Apply the redaction to all embedded images result = redactor.apply(img_red) if result.status != RedactionStatus.FAILED: # By default, the redacted document is saved in PDF format save_options = SaveOptions() save_options.add_suffix = True save_options.rasterize_to_pdf = True save_options.redacted_file_suffix = "redacted" redactor.save(save_options) if __name__ == "__main__": redact_embedded_images() ``` {{< /tab >}} {{< tab "sample.docx" >}} {{< tab-text >}} `sample.docx` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/image-redactions/sample.docx) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.pdf" >}} ```text Binary file (PDF, 1022 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/image-redactions/redact_embedded_images/sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} If the redaction cannot be applied to this type of files, e.g. a spreadsheet document, [RedactorChangeLog.Status](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactorchangelog/status/) will be [RedactionStatus.Skipped](https://reference.groupdocs.com/redaction/python-net/groupdocs.redaction/redactionstatus/). ## Multi-frame images You can remove frames from a multi-frame image with a given origin and frame count. For additional information look at [remove page redactions]({{< ref "redaction/python-net/developer-guide/basic-usage/remove-page-redactions.md" >}}) article. Some image formats, such as DjVu documents, require [pre-rasterization]({{< ref "redaction/python-net/developer-guide/advanced-usage/loading-documents/pre-rasterize.md" >}}) and further saving in PDF format. --- ## Remove page redactions Path: /redaction/python-net/remove-page-redactions/ GroupDocs.Redaction allows to easily to remove pages from PDF documents, slides from presentations and worksheets from spreadsheet documents. With GroupDocs.Redaction API you can remove pages by specifying the page range by means of its relative position (the beginning or the end), zero-based index and the count of pages to remove. At this time the supported formats are: PDF, presentations (Microsoft PowerPoint, OpenOffice Presentations), word processing documents (Microsoft Word, OpenOffice Texts, Rich Text Files), spreadsheets (Microsoft Excel, OpenOffice Spreadsheets, etc.) and multi-frame images. ## Remove page range In the example below, we remove 2nd, 3rd and 4th pages from the document, if the document has enough pages: {{< tabs "code-example-remove-page-range" >}} {{< tab "remove_page_range.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import RemovePageRedaction, PageSeekOrigin def remove_page_range(): # Load the document to be redacted with Redactor("./multipage_sample.pdf") as redactor: # Get document info doc_info = redactor.get_document_info() # Requires at least 4 pages if doc_info.page_count > 3: # Remove 3 pages starting from the 2nd one (zero-based index 1) rem_opt = RemovePageRedaction(PageSeekOrigin.BEGIN, 1, 3) # Apply the redaction result = redactor.apply(rem_opt) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": remove_page_range() ``` {{< /tab >}} {{< tab "multipage_sample.pdf" >}} {{< tab-text >}} `multipage_sample.pdf` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/remove-page-redactions/multipage_sample.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< /tabs >}} ## Remove last page In some cases you might need to delete the last page or a number of pages, no matter how many pages are there. The following example demonstrates how to remove the last page from a document: {{< tabs "code-example-remove-last-page" >}} {{< tab "remove_last_page.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import RemovePageRedaction, PageSeekOrigin def remove_last_page(): # Remove 1 page counting from the end of the document rem_opt = RemovePageRedaction(PageSeekOrigin.END, 0, 1) # Load the document to be redacted with Redactor("./multipage_sample.pdf") as redactor: # Get document info doc_info = redactor.get_document_info() # Requires at least 2 pages so the document is not left empty if doc_info.page_count > 1: # Apply the redaction result = redactor.apply(rem_opt) # Save the redacted document next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": remove_last_page() ``` {{< /tab >}} {{< tab "multipage_sample.pdf" >}} {{< tab-text >}} `multipage_sample.pdf` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/remove-page-redactions/multipage_sample.pdf) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "multipage_sample_redacted.pdf" >}} ```text Binary file (PDF, 190 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/remove-page-redactions/remove_last_page/multipage_sample_redacted.pdf) {{< /tab >}} {{< /tabs >}} ## Remove frame from image In case of a multi-frame image you might need to delete a number of frames (treated as "pages"). The following example demonstrates how to remove 3 frames from an animated GIF image: {{< tabs "code-example-remove-frame-from-image" >}} {{< tab "remove_frame_from_image.py" >}} ```python from groupdocs.redaction import Redactor from groupdocs.redaction.options import SaveOptions from groupdocs.redaction.redactions import RemovePageRedaction, PageSeekOrigin def remove_frame_from_image(): # Remove frames starting from the 3rd one (zero-based index 2) rem_opt = RemovePageRedaction(PageSeekOrigin.BEGIN, 2, 5) # Load the multi-frame image to be redacted with Redactor("./sample.gif") as redactor: # Get document info doc_info = redactor.get_document_info() # Requires at least 7 frames if doc_info.page_count >= 7: # Apply the redaction result = redactor.apply(rem_opt) # Save the redacted image next to the source file so = SaveOptions() so.add_suffix = True so.rasterize_to_pdf = False so.redacted_file_suffix = "redacted" redactor.save(so) if __name__ == "__main__": remove_frame_from_image() ``` {{< /tab >}} {{< tab "sample.gif" >}} {{< tab-text >}} `sample.gif` is the sample file used in this example. Click [here](/redaction/python-net/_sample_files/developer-guide/basic-usage/remove-page-redactions/sample.gif) to download it. {{< /tab-text >}} {{< /tab >}} {{< tab "sample_redacted.gif" >}} ```text Binary file (GIF, 704 KB) ``` [Download full output](/redaction/python-net/_output_files/developer-guide/basic-usage/remove-page-redactions/remove_frame_from_image/sample_redacted.gif) {{< /tab >}} {{< /tabs >}}