Skip to content

Commit 353a381

Browse files
committed
add cmemc - Python Scripts documentation
1 parent 5510b0b commit 353a381

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

docs/develop/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ nav:
33
- Accessing Graphs with Java Applications: accessing-graphs-with-java-applications
44
- Python Plugins: python-plugins
55
- cmempy - Python API: cmempy-python-api
6+
- cmemc - Python Scripts: cmemc-scripts
67
- Build (DataIntegration) APIs: dataintegration-apis
78
- Explore backend APIs: dataplatform-apis
89

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
status: new
3+
icon: material/language-python
4+
tags:
5+
- cmemc
6+
- Python
7+
- Automate
8+
---
9+
# cmemc - Python Scripts
10+
11+
## Introduction
12+
13+
As a more lightweight and fault-tolerant alternative to using cmempy directly, we recommend to call [cmemc commands](../../automate/cmemc-command-line-interface/command-reference/index.md) directly in your Python automation scripts.
14+
15+
The advantages of this approach are:
16+
17+
- You can test and use your calls in the command line before integrating them.
18+
- You don't have to worry about internal details and have a well-documented and stable interface.
19+
- Authorization is done in the same way, cmemc is doing this.
20+
21+
## Installation
22+
23+
cmemc is published as an Apache 2 licensed open source python package at [pypi.org](https://pypi.org/project/cmem-cmempy/), hence you are able to install it with a simple pip command:
24+
25+
``` shell
26+
pip install cmem-cmemc
27+
```
28+
29+
30+
## Configure a connection
31+
32+
Assuming you have already [configured your cmemc connection](../../automate/cmemc-command-line-interface/configuration/file-based-configuration/index.md), using it in Python scripts is quite easy.
33+
34+
``` python
35+
from os import environ
36+
37+
# use the cmemc connection
38+
environ["CMEMC_CONNECTION"] = "my-dev-cmem"
39+
```
40+
41+
This will tell cmemc to use the configured connection `my-dev-cmem`.
42+
43+
## Running commands
44+
45+
In order to execute a command and process the results, you can use this wrapper function:
46+
47+
``` python
48+
import json
49+
50+
from click.testing import CliRunner
51+
52+
from cmem_cmemc.cli import cli
53+
54+
55+
def cmemc(params: list[str]) -> str | list[str] | list[dict]:
56+
"""Run a cmemc command and provide the output.
57+
58+
When using the --raw option, output is a parsed list of dictionaries.
59+
When using the --id-only option, output is a parsed list of strings.
60+
Returns plain text output otherwise.
61+
62+
Have a look at click API documentation for more options:
63+
https://click.palletsprojects.com/en/stable/api/#click.testing.CliRunner
64+
"""
65+
result = CliRunner().invoke(cli, params)
66+
if result.exit_code != 0:
67+
raise RuntimeError(result.exception)
68+
output: str = result.stdout
69+
if "--id-only" in params:
70+
return output.splitlines()
71+
if "--raw" in params:
72+
return json.loads(output)
73+
return output
74+
```
75+
76+
This function will use the configured connection to execute a command and return the result.
77+
Please note that the output can bei either a multi-line string, a list of strings or a list of dictionaries.
78+
This is because we made sure that `--raw` outputs JSON and `--id-only` only identifier.
79+
80+
As a last step, you can iterate and process the results:
81+
82+
``` python
83+
# specify the command as a list of arguments - in this case: list all existing worflows
84+
command = ["workflow", "list", "--raw"]
85+
86+
# iterate and process the output
87+
for workflow in cmemc(command):
88+
project_id = workflow.get("projectId")
89+
workflow_id = workflow.get("id")
90+
print(f"Workflow '{workflow_id}' in '{project_id}'")
91+
```
92+
93+
## Using a shebang to create an executable file
94+
95+
As a nice addon, you could extend your script with a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to start [uv](https://docs.astral.sh/uv/).
96+
This will also install and manage dependencies and python versions for you:
97+
98+
The complete script looks like this:
99+
100+
``` python
101+
#!/usr/bin/env -S uv run --script
102+
# /// script
103+
# dependencies = [
104+
# "cmem-cmemc",
105+
# ]
106+
# ///
107+
import json
108+
from os import environ
109+
110+
from click.testing import CliRunner
111+
112+
from cmem_cmemc.cli import cli
113+
114+
115+
def cmemc(params: list[str]) -> str | list[str] | list[dict]:
116+
"""Run a cmemc command and provide the output.
117+
118+
When using the cmemc --raw option, output is a parsed list of dictionaries.
119+
When using the cmemc --id-only option, output is a parsed list of strings.
120+
121+
Have a look at click API documentation for more options:
122+
https://click.palletsprojects.com/en/stable/api/#click.testing.CliRunner
123+
"""
124+
result = CliRunner().invoke(cli, params)
125+
if result.exit_code != 0:
126+
raise RuntimeError(result.exception)
127+
output: str = result.stdout
128+
if "--id-only" in params:
129+
return output.splitlines()
130+
if "--raw" in params:
131+
return json.loads(output)
132+
return output
133+
134+
135+
# use the cmemc connection
136+
environ["CMEMC_CONNECTION"] = "my-dev-cmem"
137+
138+
# specify the command as a list of arguments
139+
# in this case: list all existing worflows
140+
command = ["workflow", "list", "--raw"]
141+
142+
# iterate and process the output
143+
for workflow in cmemc(command):
144+
project_id = workflow.get("projectId")
145+
workflow_id = workflow.get("id")
146+
print(f"Workflow '{workflow_id}' in '{project_id}'")
147+
148+
```
149+
150+
Executing this python script will look like this:
151+
152+
``` shell-session
153+
$ ./cmemc-script.py
154+
Workflow 'input-output' in 'io'
155+
Workflow 'input-output-replaceable' in 'io'
156+
Workflow 'normal' in 'io'
157+
Workflow 'only-input' in 'io'
158+
Workflow 'only-input-included' in 'io'
159+
Workflow 'only-input-replaceable' in 'io'
160+
Workflow 'only-output' in 'io'
161+
Workflow 'only-output-replaceable' in 'io'
162+
```
163+

0 commit comments

Comments
 (0)