> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arc.cdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Writing Python

> How to write and execute Python scripts in CData Arc, including built-in variables, context objects, and practical examples.

export const siteNameShort = "Arc";

Once you have completed the [prerequisites](./python-prerequisites), {siteNameShort} can read and execute Python anywhere {siteNameShort}Script can be written. This includes the [Script](../connectors/script) connector, [events](./scripting#event-scripting), code scripts in the [XML Map](../connectors/xml-map/xml-map) connector, and so on.

To tell {siteNameShort}'s scripting engine to use Python instead of {siteNameShort}Script, you must define Python as the language being used. This is done by setting the `language` attribute on an [arc:script](./keyword-reference/op-arc-script) keyword, as shown below:

```xml theme={null}
<arc:script language="python">
# Python code goes here
</arc:script>
```

Python is embedded directly into {siteNameShort}'s scripting engine, which allows users who are familiar with writing Python to use a similar syntax to interact with messages and context in their scripts.

You can also use {siteNameShort}Script and Python in the same script. This is useful when you already have {siteNameShort}Script written but need to implement some additional logic using Python. You can use Python to directly access items written in {siteNameShort}Script, as shown in the following example:

```xml theme={null}
<arc:set attr="CustomerA.OrderID" value="123456" />
<arc:script language="python">
print("The OrderId for CustomerA is", _ctx.CustomerA.OrderID)
</arc:script>
```

A number of Python methods and variables work specifically with the message, item and attribute context in {siteNameShort}.

## Built-in Object Interfaces

Two main interfaces are used in {siteNameShort}'s Python implementation. These contain and provide access to the built-in variables listed below:

* [{siteNameShort}ScriptContext](#scriptcontext)
* [{siteNameShort}ScriptItem](#scriptitem)

### {siteNameShort}ScriptContext

This represents the main scripting context object for Python scripts in {siteNameShort}. It provides dictionary-like access to items and includes logging capabilities. This interface provides access to the `_ctx` variable which you can use to access the context.

The available methods are:

* [push](#push)
* [log](#log)

### {siteNameShort}ScriptItem

This represents individual data items in the {siteNameShort} scripting environment. It provides dictionary-like access to attributes and maintains value lists. The following variables are {siteNameShort}ScriptItem instances that are automatically available:

* [\_input](#_input)
* [output](#output)
* [\_message](#_message)
* [result](#result)

The available methods are:

* [get](#get)
* [clear](#clear)

At a high level, `_ctx` provides access to the scripting context while `_input`, `output`, and `_message` are pre-instantiated {siteNameShort}ScriptItem objects. Use the syntax `_ctx.itemname` to create or access custom items dynamically. See [Built-in Variables](#built-in-variables) and [Operations](#operations) for more information.

## Built-in Variables

These variables provide access to the core of the message context in a scripting environment. Use these to interact with the items available in the scripting engine.

### \_ctx

The main variable for accessing the scripting environment. It provides:

* Access to all items available in the script
* The ability to create new items, push items, and log to the application logs

In the following example, the `log` method on the `_ctx` variable is called to log information to the [application log](../getting-started/administration/activity#application-logs) using the `INFO` log level:

```xml theme={null}
<arc:script language="python">
...
_ctx.log('INFO', 'Successfully analyzed all data!')
...
</arc:script>
```

### \_input

The read-only input item of the scripting engine. The available attributes vary based on the context in which you are writing your script (such as connector [action type](../connectors/script#actions)). For example, in a [Script](../connectors/script) connector set to the *Transform* action, you can use the following attributes:

* ConnectorId
* WorkspaceId
* MessageId
* FilePath
* FileName
* Attachment#
* Header:\*

However, if you set the Script connector to the *Trigger* action where no input is provided to the connector, only ConnectorId and WorkspaceId are available.

The following example prints the name of the connector to the log file of the current message:

```xml theme={null}
<arc:script language="python">
...
print(_input.ConnectorId)
...
</arc:script>
```

This example takes the input file, renames it, logs the original name, then pushes the same file with a new name:

```xml theme={null}
<arc:script language="python">
originalname = _input.Filename
print("The original filename was ", originalname)
output.Filename = "mynewfile.xml"
output.Filepath = _input.Filepath
</arc:script>
```

This example checks the name of the input file to see whether it is a list of perishable or non-perishable items. Then it sets a perishable header and value based on the filename:

```xml theme={null}
<arc:script language="python">
# Check if it's a perishable product list based on the filename
is_perishable = "perishables" in _input.FileName.lower()
# Set a perishable header and value based on the filename
output['Header:category'] = 'perishable' if is_perishable else 'non-perishable'
</arc:script>
```

### output

A built-in item that serves as an alternative to creating and pushing your own item when only a single output is needed. Unlike custom items that require you to explicitly call `push()` to send them as output, the `output` item is automatically pushed when the script completes. You just need to modify its properties and it is automatically pushed as output once the script execution is complete, without any additional `push()` calls needed.

You can set attributes directly on the item or define them using a `dict`, and you can do the same thing with items you define yourself. The following example pushes an output file with some data:

```xml theme={null}
<arc:script language="python">
output = {'data': 'This is a test',
          'filename': 'foo.txt'}
</arc:script>
```

This example takes the input file, renames it, logs the original name, then pushes the same file with a new name:

```xml theme={null}
<arc:script language="python">
originalname = _input.Filename
print("The original filename was ", originalname)
output.Filename = "mynewfile.xml"
output.Filepath = _input.Filepath
</arc:script>
```

### \_message

Provides access to the current message when one is loaded in context. The variable is only accessible when a message is actively being processed by a connector in these specific scenarios (such as when there is a message loaded in context). For example, the `_message` variable is not available in connectors whose [action](../connectors/script#actions) is set to *Trigger* because a message is not present until the connector is finished working. When this variable is unavailable, a `_message is not defined` exception appears.

You can use the following attributes:

* Header:Message-Id
* Header:FileName
* Header:\*
* body

The following example does some simple string manipulation on the message body:

```xml theme={null}
<arc:script language="python">
# The message body in this example is plain text of "Example data for Arc."
# Perform string manipulation
transformed = _message.body.replace('a', '@').replace('e', '3')
print("Original:", _message.body)
print("Transformed:", transformed)
...
</arc:script>
```

The resulting output is printed to the log of the message:

```
Original: Example data for Arc.
Transformed: 3x@mpl3 d@t@ for Arc.
```

This example shows how to read a CustomerID header from the `_message` item and print it as an entry in the log file for the current message.

```xml theme={null}
<arc:script language="python">
...
print("The data is valid for customer", _message["Header:CustomerID"])
...
</arc:script>
```

### result

A special variable for use specifically in [XML Map](../connectors/xml-map/xml-map) script nodes. It is treated as the result of the whole script. The value of this variable is used as the node's value in the map. However, it can also be used as a debugging tool in [Script](../connectors/script) connectors.

This example, which is used in a script in a destination node of an XML Map connector, reads the source file's address/city xpath from an {siteNameShort}Script item declared at the top, then uses Python to modify the value to be the first three letters, all capitalized. The new value is then sent as the value of `result`:

```xml theme={null}
<arc:set attr="source.city" value="[xpath(address/city)]" />
<arc:script language="python">
city_value = _ctx.source.get("city")
# Normalize: extract from list if needed
if isinstance(city_value, list):
    city = city_value[0] if city_value else None
else:
    city = city_value
# Final logic
result = city[:3].upper() if city else ""
</arc:script>
```

In this example, the `result` variable is used to add entries to the log file of a Script connector:

```xml theme={null}
<arc:script language="python">
result = ["Step 1"]
output = {
  "Filename": "test.txt",
  "Data": "foo"
}
result.append("Step 2")
</arc:script>
```

The script output looks like this:

```
[2025-06-12T17:14:36.878-04:00][Info] Output File: test.txt
[2025-06-12T17:14:36.883-04:00][Info] Receiving done.
[2025-06-12T17:14:36.883-04:00][Info] Script output:
["Step 1","Step 2"]
```

## Operations

### log

`log(level, message)` is a method available on the `_ctx` variable that allows you to write entries directly to the {siteNameShort} [application log](../getting-started/administration/activity#application-logs). The available log levels are DEBUG, INFO, WARNING and ERROR.

```xml theme={null}
<arc:script language="python">
...
_ctx.log('ERROR', f'Data evaluation failed in connector {_input.ConnectorId}!')
...
</arc:script>
```

The previous example produces the following log entry:

<img src="https://mintcdn.com/cdata-arc/AKthyJ-LnqphL8js/public/images/python_log_result.png?fit=max&auto=format&n=AKthyJ-LnqphL8js&q=85&s=8c4530629ed8dc052d43c24c0cf845ad" alt="Python log result in the Activity log" width="700" data-path="public/images/python_log_result.png" />

### push

`push(item)` pushes the supplied item as output of the script. If an output is not specified, the `output` item is pushed.

In this example a new item, `foo`, is created in the {siteNameShort}ScriptContext, assigned some data and a filename, then pushed out.

```xml theme={null}
<arc:script language="python">
foo = _ctx.foo
foo.Filename = "test2.txt"
foo.Data = "bar"
_ctx.push(foo)
</arc:script>
```

### get

`get(attr)` returns the value of the specified attribute on the {siteNameShort}ScriptItem. This method provides a programmatic way to access item attributes by name. It is functionally equivalent to accessing the attribute directly using dot notation (such as `_input.myattr`) or using dictionary-style access (such as `_input.get('myattr')`).

The following example prints the value list of the `tags` attribute on the `item` object to the log file of the current script.

```xml theme={null}
<arc:script language="python">
item = _ctx.item
item.name = 'Milk'
item.price = '2.99'
item.tags = ['perishable', 'dairy', 'noreturn']
print(item.get('tags'))
</arc:script>
```

### clear

`clear()` clears the {siteNameShort}ScriptItem on which the method is called. The item remains the same, just empty.

```xml theme={null}
<arc:script language="python">
product = _ctx.product
product.name = 'Milk'
product.price = '2.99'
product.tags = ['perishable', 'dairy', 'noreturn']
print("Before clear:", product)
# Use the clear() method to remove all items
product.clear()
print("After clear:", product)
</arc:script>
```

The previous example produces the following output:

* Before clear: `{"price":"2.99","name":"Milk","tags":["perishable","dairy","noreturn"]}`
* After clear: `{}`
