Issues on exporting / importing flows using the api

i have two instances of node red running, i would like to copy a given flow from instance one to instance two.

flow_id = '8429e42d5be21f50'
handler.get_flow(flow_id)
print(json.dumps(flow, indent=4))

provides:

{'disabled': False,
 'env': [],
 'id': '8429e42d5be21f50',
 'info': '',
 'label': 'Simple-Export',
 'nodes': [{'crontab': '',
            'id': '5f74a245600e657d',
            'name': '',
            'once': False,
            'onceDelay': 0.1,
            'payload': '',
            'payloadType': 'date',
            'props': [{'p': 'payload'}, {'p': 'topic', 'vt': 'str'}],
            'repeat': '',
            'topic': '',
            'type': 'inject',
            'wires': [['a009c29205ae3027']],
            'x': 500,
            'y': 260,
            'z': '8429e42d5be21f50'},
           {'action': '',
            'from': '',
            'id': 'a009c29205ae3027',
            'name': '',
            'property': '',
            'reg': False,
            'rules': [{'p': 'payload',
                       'pt': 'msg',
                       't': 'set',
                       'to': 'set',
                       'tot': 'str'}],
            'to': '',
            'type': 'change',
            'wires': [['aef6a32098eda1e8']],
            'x': 750,
            'y': 260,
            'z': '8429e42d5be21f50'},
           {'active': True,
            'complete': 'payload',
            'console': False,
            'id': 'aef6a32098eda1e8',
            'name': '',
            'statusType': 'auto',
            'statusVal': 'payload',
            'targetType': 'msg',
            'tosidebar': True,
            'tostatus': True,
            'type': 'debug',
            'wires': [],
            'x': 1010,
            'y': 260,
            'z': '8429e42d5be21f50'}]}

            "rules": [
                {
                    "t": "set",
                    "p": "payload",
                    "pt": "msg",
                    "to": "set",
                    "tot": "str"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 750,
            "y": 260,
            "wires": [
                [
                    "aef6a32098eda1e8"
                ]
            ]
        },
        {
            "id": "aef6a32098eda1e8",
            "type": "debug",
            "z": "8429e42d5be21f50",
            "name": "",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 1010,
            "y": 260,
            "wires": []
        }
    ]
}

after copying that one to the second instance using:

handler.copy_flow(flow_id)

i get:
200
{'id': '435a67050951dc8a'}

the code used for sending the flow was:
r = requests.post('https://{destination}/flow'.format(destination=self.destination), data=flow, headers=self.headers)

in the node-red log i see:

25 Jan 09:52:12 - [info] Waiting for missing types to be registered:
25 Jan 09:52:12 - [info] - undefined
25 Jan 09:52:12 - [info] Adding flow: Simple-Export [435a67050951dc8a]

if i reload the flows in the destination installation of node red i get following error:

Cannot read properties of undefined (reading 'substring')

i don't have an idea where this undefined is comming from.

thanks for help!

Does the Node-red instance you are importing into have the cron node installed?

Paul, you probably didnt notice the type property is "inject" (crontab is a property of the inject node)

1 Like

Somewhere in your code, you are trying to set a flow with a value of False by the looks of it (false in JavaScript/JSON is false not False)

Are you processing via python?

yes iam using a python script for executing the api calls

crontab ist installed on the source system, but not yet on the destination system.
iam installing only modules used (identified as used) by the source flow.

As explained above, crontab is not a node type.

A node type is defined by the type field!

flows.json before the import:

[
    {
        "id": "5c1bbfa9991b92e6",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "8e869e83530d854d",
        "type": "ui_base",
        "theme": {
            "name": "theme-light",
            "lightTheme": {
                "default": "#0094CE",
                "baseColor": "#0094CE",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
                "edited": true,
                "reset": false
            },
            "darkTheme": {
                "default": "#097479",
                "baseColor": "#097479",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
                "edited": false
            },
            "customTheme": {
                "name": "Untitled Theme 1",
                "default": "#4B7930",
                "baseColor": "#4B7930",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
            },
            "themeState": {
                "base-color": {
                    "default": "#0094CE",
                    "value": "#0094CE",
                    "edited": false
                },
                "page-titlebar-backgroundColor": {
                    "value": "#0094CE",
                    "edited": false
                },
                "page-backgroundColor": {
                    "value": "#fafafa",
                    "edited": false
                },
                "page-sidebar-backgroundColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "group-textColor": {
                    "value": "#1bbfff",
                    "edited": false
                },
                "group-borderColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "group-backgroundColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "widget-textColor": {
                    "value": "#111111",
                    "edited": false
                },
                "widget-backgroundColor": {
                    "value": "#0094ce",
                    "edited": false
                },
                "widget-borderColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "base-font": {
                    "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
                }
            },
            "angularTheme": {
                "primary": "indigo",
                "accents": "blue",
                "warn": "red",
                "background": "grey",
                "palette": "light"
            }
        },
        "site": {
            "name": "Node-RED Dashboard",
            "hideToolbar": "false",
            "allowSwipe": "false",
            "lockMenu": "false",
            "allowTempTheme": "true",
            "dateFormat": "DD.MM.YYYY",
            "sizes": {
                "sx": 48,
                "sy": 48,
                "gx": 6,
                "gy": 6,
                "cx": 6,
                "cy": 6,
                "px": 0,
                "py": 0
            }
        }
    }
]

after the import:

[
    {
        "id": "5c1bbfa9991b92e6",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "8e869e83530d854d",
        "type": "ui_base",
        "theme": {
            "name": "theme-light",
            "lightTheme": {
                "default": "#0094CE",
                "baseColor": "#0094CE",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
                "edited": true,
                "reset": false
            },
            "darkTheme": {
                "default": "#097479",
                "baseColor": "#097479",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
                "edited": false
            },
            "customTheme": {
                "name": "Untitled Theme 1",
                "default": "#4B7930",
                "baseColor": "#4B7930",
                "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
            },
            "themeState": {
                "base-color": {
                    "default": "#0094CE",
                    "value": "#0094CE",
                    "edited": false
                },
                "page-titlebar-backgroundColor": {
                    "value": "#0094CE",
                    "edited": false
                },
                "page-backgroundColor": {
                    "value": "#fafafa",
                    "edited": false
                },
                "page-sidebar-backgroundColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "group-textColor": {
                    "value": "#1bbfff",
                    "edited": false
                },
                "group-borderColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "group-backgroundColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "widget-textColor": {
                    "value": "#111111",
                    "edited": false
                },
                "widget-backgroundColor": {
                    "value": "#0094ce",
                    "edited": false
                },
                "widget-borderColor": {
                    "value": "#ffffff",
                    "edited": false
                },
                "base-font": {
                    "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
                }
            },
            "angularTheme": {
                "primary": "indigo",
                "accents": "blue",
                "warn": "red",
                "background": "grey",
                "palette": "light"
            }
        },
        "site": {
            "name": "Node-RED Dashboard",
            "hideToolbar": "false",
            "allowSwipe": "false",
            "lockMenu": "false",
            "allowTempTheme": "true",
            "dateFormat": "DD.MM.YYYY",
            "sizes": {
                "sx": 48,
                "sy": 48,
                "gx": 6,
                "gy": 6,
                "cx": 6,
                "cy": 6,
                "px": 0,
                "py": 0
            }
        }
    },
    {
        "type": "tab",
        "label": "Simple-Export",
        "id": "916297197f476c45",
        "info": "",
        "disabled": "False"
    },
    "id",
    "type",
    "z",
    "name",
    "props",
    "repeat",
    "crontab",
    "once",
    "onceDelay",
    "topic",
    "payload",
    "payloadType",
    "x",
    "y",
    "wires",
    "id",
    "type",
    "z",
    "name",
    "rules",
    "action",
    "property",
    "from",
    "to",
    "reg",
    "x",
    "y",
    "wires",
    "id",
    "type",
    "z",
    "name",
    "active",
    "tosidebar",
    "console",
    "tostatus",
    "complete",
    "targetType",
    "statusVal",
    "statusType",
    "x",
    "y",
    "wires"
]

Where did you get these JSON from? From the flows file? from the API?

You do realise the 2nd JSON is completely invalid (from the POV of node-red)


You need to capture to file (for later inspection) the following:

  • what was retrieved from instance 1
  • what was sent to instance 2
  • what is in flows file of instance 2
    • before
    • after

Once you have this, you will see where your processing is being broken

yes understootd, i thought that maybe the property causes the issue because it is not installed in the desitnation system. i reduced the exported flow to :slight_smile:

{
    "id": "8429e42d5be21f50",
    "label": "Simple-Export",
    "disabled": false,
    "info": "",
    "env": [],
    "nodes": [
        {
            "id": "a009c29205ae3027",
            "type": "change",
            "z": "8429e42d5be21f50",
            "name": "",
            "rules": [
                {
                    "t": "set",
                    "p": "payload",
                    "pt": "msg",
                    "to": "set",
                    "tot": "str"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 750,
            "y": 260,
            "wires": [
                [
                    "aef6a32098eda1e8"
                ]
            ]
        },
        {
            "id": "aef6a32098eda1e8",
            "type": "debug",
            "z": "8429e42d5be21f50",
            "name": "",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 1010,
            "y": 260,
            "wires": []
        }
    ]
}

i have still the same issue.

should it worl to use the api on instance one with get /flow/flowid and taking the result json and use it on instance two two with put /flow ?

that's why i am wondering:
the json from my last reply is what i have retreived from a as json and what i have sent to b as json

thx for the dumping hint, i found the issue - it was sent as get params.

wondering that there is no error thrown on the api call.

is there a way to "copy" a flow including their related config nodes like broker on the mqtt nodes?

Hello
I'm in the same situation as @msmthng
I would like to backup individual flows automatically in the same format as the "Export - current flow" menu does which mean including subflows and configuration nodes.

I have been able to use the API for individual flow: GET /flow/:id GET /flow/:id : Node-RED
But as you know, subflows and configuration nodes are not part of it

Is there a way to get that from a single API call ?
Or must I go through the complete JSON with GET /flows or even reading the flows.json file and parse it myself ?

I haven't looked into node-red code, but I can do if you can point me to the part of the code that match the "Export - current flow" menu.

Thanks

This code might help - it's from the NR codebase and does an flow export in the client, not server. It generates the same format that export flow uses.

Thanks @gregorius
I wouldn't event thought about looking in the client code base
I will investigate that path