| 
 | 1 | +---  | 
 | 2 | +layout: default  | 
 | 3 | +title: Executing code  | 
 | 4 | +nav_order: 7  | 
 | 5 | +---  | 
 | 6 | + | 
 | 7 | +The [MarkLogic REST service extension](https://docs.marklogic.com/REST/client/service-extension) supports the  | 
 | 8 | +execution of custom code, whether via an inline script or an existing module in your application's modules database.   | 
 | 9 | +The MarkLogic Python client supports execution of custom code by simplifying the submission of custom code  | 
 | 10 | +and converting the multipart response into more useful Python data types.  | 
 | 11 | + | 
 | 12 | +## Setup  | 
 | 13 | + | 
 | 14 | +The examples below all depend on the instructions in the [setup guide](example-setup.md) having already been performed.  | 
 | 15 | + | 
 | 16 | +To try out the examples, start a Python shell and first run the following:  | 
 | 17 | + | 
 | 18 | +```  | 
 | 19 | +from marklogic import Client  | 
 | 20 | +client = Client('http://localhost:8000', digest=('python-user', 'pyth0n'))  | 
 | 21 | +```  | 
 | 22 | + | 
 | 23 | +## Executing ad-hoc queries  | 
 | 24 | + | 
 | 25 | +The [v1/eval REST endpoint](https://docs.marklogic.com/REST/POST/v1/eval) supports the execution of ad-hoc JavaScript   | 
 | 26 | +and XQuery queries. Each type of query can be easily submitted via the client:  | 
 | 27 | + | 
 | 28 | +```  | 
 | 29 | +client.eval(javascript="fn.currentDateTime()")  | 
 | 30 | +client.eval(xquery="fn:current-dateTime()")  | 
 | 31 | +```  | 
 | 32 | + | 
 | 33 | +Variables can optionally be provided via a `dict`:  | 
 | 34 | + | 
 | 35 | +```  | 
 | 36 | +results = client.eval(javascript='Sequence.from([{"hello": myValue}])', vars={"myValue": "world"})  | 
 | 37 | +assert "world" == results[0]["hello"]  | 
 | 38 | +```  | 
 | 39 | + | 
 | 40 | +Because the REST endpoint returns a sequence of items, the client will always return a list of values. See the section  | 
 | 41 | +below on how data types are converted to understand how the client will convert each value into an appropriate Python  | 
 | 42 | +data type.  | 
 | 43 | + | 
 | 44 | +## Invoking modules  | 
 | 45 | + | 
 | 46 | +The [v1/invoke REST endpoint](https://docs.marklogic.com/REST/POST/v1/invoke) supports the execution of JavaScript  | 
 | 47 | +and XQuery main modules that have been deployed to your application's modules database.   | 
 | 48 | + | 
 | 49 | +If you wish to attempt the examples below (instead of invoking your own modules), first run the following to   | 
 | 50 | +insert a simple runnable module into the out-of-the-box "Modules" database:  | 
 | 51 | + | 
 | 52 | +```  | 
 | 53 | +from marklogic.documents import Document  | 
 | 54 | +module = Document('/sample.sjs', 'const doc = {"hello": "world"}; doc', permissions={"rest-reader": ["read", "update", "execute"]})  | 
 | 55 | +client.documents.write(module, params={"database": "Modules"})  | 
 | 56 | +```  | 
 | 57 | + | 
 | 58 | +A module can be invoked via the client in the following manner:  | 
 | 59 | + | 
 | 60 | +```  | 
 | 61 | +# Set the input to the URI of the module you wish to invoke in your application's   | 
 | 62 | +# modules database.  | 
 | 63 | +client.invoke("/sample.sjs")  | 
 | 64 | +```  | 
 | 65 | + | 
 | 66 | +You can provide variables to your module in the same fashion as when evaluating custom   | 
 | 67 | +code (the variable will not have any impact on the sample module loaded above; this is  | 
 | 68 | +shown purely to demonstrate how to define variables):  | 
 | 69 | + | 
 | 70 | +```  | 
 | 71 | +client.invoke("/sample.sjs", vars={"my_var1": "value1"})  | 
 | 72 | +```  | 
 | 73 | + | 
 | 74 | +## Conversion of data types  | 
 | 75 | + | 
 | 76 | +The REST endpoints for evaluating ad-hoc code and for invoking a module both return a sequence of values, with each   | 
 | 77 | +value having MarkLogic-specific type information. The client will use this type information to convert each value into  | 
 | 78 | +an appropriate Python data type. For example, each JSON object into the example below is converted into a `dict`:  | 
 | 79 | + | 
 | 80 | +```  | 
 | 81 | +results = client.eval(javascript='Sequence.from([{"doc": 1}, {"doc": 2}])')  | 
 | 82 | +assert len(results) == 2  | 
 | 83 | +assert results[0]["doc"] == 1  | 
 | 84 | +assert results[1]["doc"] == 2  | 
 | 85 | +```  | 
 | 86 | + | 
 | 87 | +The following table describes how each MarkLogic type is associated with a Python data type. For any   | 
 | 88 | +MarkLogic type not listed in the table, such as `hexBinary` and `base64Binary`, the value is not converted and will   | 
 | 89 | +remain of type `bytes`.   | 
 | 90 | + | 
 | 91 | +| MarkLogic type | Python type |   | 
 | 92 | +| --- | --- |  | 
 | 93 | +| string | str |  | 
 | 94 | +| integer | int |  | 
 | 95 | +| boolean | bool |  | 
 | 96 | +| decimal | [Decimal](https://docs.python.org/3/library/decimal.html) |  | 
 | 97 | +| map | dict |  | 
 | 98 | +| element() | str |  | 
 | 99 | +| array | list |  | 
 | 100 | +| array-node() | list |  | 
 | 101 | +| object-node() | dict or `marklogic.documents.Document` |  | 
 | 102 | +| document-node() | str or `marklogic.documents.Document` |  | 
 | 103 | +| binary() | bytes or `marklogic.documents.Document` |   | 
 | 104 | + | 
 | 105 | +For the `object-node()`, `document-node()`, and `binary()` entries in the above table, a   | 
 | 106 | +`marklogic.documents.Document` instance will be returned if the value is associated with a URI via   | 
 | 107 | +the multipart `X-URI` header. Otherwise, a value of type `dict`, `str`, or `bytes` is returned respectively.  | 
 | 108 | + | 
 | 109 | +## Returning the original HTTP response  | 
 | 110 | + | 
 | 111 | +Each `client.eval` method and `client.invoke` accept a `return_response` argument. When that  | 
 | 112 | +argument is set to `True`, the original response is returned. This can be useful for custom  | 
 | 113 | +processing of the response or debugging requests.  | 
 | 114 | + | 
 | 115 | +## Referencing a transaction  | 
 | 116 | + | 
 | 117 | +The `client.eval` and `client.invoke` functions both support referencing a   | 
 | 118 | +[REST API transaction](https://docs.marklogic.com/REST/client/transaction-management) via the `tx`   | 
 | 119 | +argument. See [the guide on transactions](transactions.md) for further information.  | 
0 commit comments