---
title: "DWS Processor API with Python"
canonical_url: "https://www.nutrient.io/guides/dws-processor/supported-languages/python/"
md_url: "https://www.nutrient.io/guides/dws-processor/supported-languages/python.md"
last_updated: "2026-05-27T15:15:53.462Z"
description: "Learn how to use Nutrient DWS Processor API with Python to process documents through HTTP requests and enhance your development experience."
---

With Nutrient DWS Processor API, you can process your documents by making HTTP requests to one of our [50+ API tools](https://dashboard.nutrient.io/processor-api/playground/). You can make a single request to one tool or combine API actions to generate, edit, OCR, and convert your document (1 document can have multiple API actions).

## Using our Python client

For the best developer experience, we recommend using our [official Python client library](https://github.com/PSPDFKit/nutrient-dws-client-python).

### Installation

```sh

pip install nutrient-dws

# Enable enhanced code completion and documentation for Claude Code using the Nutrient DWS SDK.

dws-add-claude-code-rule

# Enable enhanced code completion and documentation for GitHub Copilot using the Nutrient DWS SDK.

dws-add-github-copilot-rule

# Enable enhanced code completion and documentation for Junie (Jetbrains) using the Nutrient DWS SDK.

dws-add-junie-rule

# Enable enhanced code completion and documentation for Cursor using the Nutrient DWS SDK.

dws-add-cursor-rule

# Enable enhanced code completion and documentation for Windsurf using the Nutrient DWS SDK.

dws-add-windsurf-rule

```

### Example

```python

import asyncio
from nutrient_dws import NutrientClient
from nutrient_dws.builder.constant import BuildActions

async def main():
    client = NutrientClient(api_key='your_api_key_here')

    # Add an image watermark to a document.

    image_result = await client.watermark_image('./document.pdf', './logo.png', {
        'width': {'value': 50, 'unit': '%'}
    })

    with open('./watermarked-document.pdf', 'wb') as f:
        f.write(image_result.buffer)

    # Redact and archive a document set using chained workflow.

    archived_result = await (client.workflow()
        # Add documents from multiple formats (PDF, DOCX, PNG)..add_file_part("./form.docx").add_file_part("./policy.pdf").add_file_part("./image.png")
        # Apply multiple actions: watermark and redactions using apply_actions.apply_actions([
            BuildActions.create_redactions_preset('email-address'),
            BuildActions.create_redactions_preset('international-phone-number'),
            BuildActions.create_redactions_preset('north-american-phone-number'),
            BuildActions.apply_redactions(),
            BuildActions.watermark_text('ARCHIVED', {
                'opacity': 0.45,
                'fontSize': 32,
                'fontColor': '#FF0000',

                'rotation': 45,
                'fontStyle': ['bold']
            }),
        ])
        # Output as PDF/A format..output_pdfa({
            'conformance': 'pdfa-2b',
            'vectorization': True,
            'metadata': {
                'title': 'Multi-Format Merged Document',
                'author': 'Archive.org',
            },
            'optimize': {
                'mrcCompression': True,
                'imageOptimizationQuality': 3
            }
        })
        # Tracking progress..execute(on_process= lambda current, total: print(f"Processing step {current} of {total}")))

    with open('./archived-document.pdf', 'wb') as f:
        f.write(archived_result.buffer)

if __name__ == "__main__":
    asyncio.run(main())

```

## Alternative: Using raw HTTP requests

If you prefer to use raw HTTP requests or want to understand the underlying API calls, you can also interact with the API directly using any HTTP client.

This section demonstrates how to use the [`requests`](https://requests.readthedocs.io/) library to make HTTP requests with Nutrient DWS Processor API. Keep in mind that you can use any HTTP client you want; this example uses `requests` to demonstrate the principles of interacting with Nutrient DWS Processor API.

It involves three main steps:

1. Installing the required dependencies

2. Preparing the payload

3. Making the request

### Installing the required dependencies

First, you need to make sure you have all the dependencies set up:

```sh

python -m pip install requests

```

You’ll also need to add the `document.pdf` and `logo.png` files to the root of your Python project (the same folder you’ll be creating the `pspdfkit.py` file in). You can use the sample files provided by us — [document.pdf](https://www.nutrient.io/assets/guides/dws-processor/watermark/document.pdf) and [logo.png](https://www.nutrient.io/assets/guides/dws-processor/watermark/logo.png) — or use your own.

Now that you have your dependencies and assets set up, you’re ready to start making requests to Nutrient DWS Processor API.

First, create a `pspdfkit.py` file, which will contain your code to call Nutrient DWS Processor API. You can immediately import your dependencies as well:

```py

import requests
import json

```

Next, you’ll prepare the payload.

### Preparing the payload

Create your `instructions` object:

```py

instructions = {
  'parts': [
    {
      'file': 'document'
    }
  ],
  'actions': [
    {
      'type': 'watermark',
      'image': 'company-logo',
      'width': '50%'
    },
    {
      'type': 'watermark',
      'text': 'Property of Nutrient',
      'width': 150,
      'height': 20,
      'left': 0,
      'bottom': '100%'
    }
  ]
}

payload = {
  'instructions': json.dumps(instructions)
}

```

Since Nutrient DWS Processor API expects the `instructions` to be a JSON object, you first create a dictionary that you then convert to a JSON object using the `json.dumps` function. In this example, you’ll be adding an image watermark. For examples of how the watermark API can be used (for example, adding multiple watermarks to the document, watermarking the last page of the document, and watermark alignments), refer to our [PDF watermark API](https://www.nutrient.io/api/pdf-watermark-api/) page.

Next, you need to prepare your assets to be sent:

```py

files = {
  'document': open('document.pdf', 'rb'),
  'company-logo': open('logo.png', 'rb')
}

```

The `requests` library expects a `file` object to be passed in, so open your assets here.

### Making the request

Finally, you’re ready to make your request. Make sure to replace the `your_api_key_here` placeholder with your actual API key if it hasn’t been replaced yet:

```py

headers = {
  'Authorization': 'Bearer your_api_key_here'
}

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers=headers,
  files=files,
  data=payload,
  stream=True
)

with open('result.pdf', 'wb') as fd:
  for chunk in response.iter_content(chunk_size=8096):
    fd.write(chunk)

```

This will make a request to Nutrient DWS Processor API, send your previously defined `instructions` object and your assets to the API, and save the resulting PDF as `result.pdf` in the same folder as your Python file.

And with that, you’re ready to make a request. Run `python pspdfkit.py`, and `result.pdf` will show up next to your Python file.

While this example made use of our watermarking API, this same approach can be used for all our available [API tools](https://dashboard.nutrient.io/processor-api/playground/).

## Complete code

For your convenience, the complete code is below:

```py

import requests
import json

instructions = {
  'parts': [
    {
      'file': 'document'
    }
  ],
  'actions': [
    {
      'type': 'watermark',
      'image': 'company-logo',
      'width': '50%'
    },
    {
      'type': 'watermark',
      'text': 'Property of Nutrient',
      'width': 150,
      'height': 20,
      'left': 0,
      'bottom': '100%'
    }
  ]
}

payload = {
  'instructions': json.dumps(instructions)
}

headers = {
  'Authorization': 'Bearer your_api_key_here'
}

files = {
  'document': open('document.pdf', 'rb'),
  'company-logo': open('logo.png', 'rb')
}

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers=headers,
  files=files,
  data=payload,
  stream=True
)

with open('result.pdf', 'wb') as fd:
  for chunk in response.iter_content(chunk_size=8096):
    fd.write(chunk)

```
---

## Related pages

- [Supported languages](/guides/dws-processor/supported-languages.md)
- [DWS Processor API with Java](/guides/dws-processor/supported-languages/java.md)
- [DWS Processor API with C#](/guides/dws-processor/supported-languages/csharp.md)
- [Enable enhanced code completion and documentation for Claude Code using the Nutrient DWS SDK.](/guides/dws-processor/supported-languages/javascript.md)
- [DWS Processor API with PHP](/guides/dws-processor/supported-languages/php.md)
- [DWS Processor API with other languages](/guides/dws-processor/supported-languages/other.md)

