Open-EO / openeo-web-editor

An interactive and easy to use web-based editor for the OpenEO API.
https://editor.openeo.org
Apache License 2.0
12 stars 17 forks source link

Code generation of nested callback functions broken #238

Closed m-mohr closed 2 years ago

m-mohr commented 2 years ago

There's an issue if you nest callbacks deeply. Example PG:

{
  "process_graph": {
    "1": {
      "process_id": "apply_dimension",
      "arguments": {
        "dimension": "t",
        "process": {
          "process_graph": {
            "1": {
              "process_id": "array_apply",
              "arguments": {
                "context": {
                  "from_parameter": "data"
                },
                "data": {
                  "from_parameter": "data"
                },
                "process": {
                  "process_graph": {
                    "1": {
                      "process_id": "array_element",
                      "arguments": {
                        "index": {
                          "from_node": "4"
                        },
                        "data": {
                          "from_parameter": "context"
                        }
                      }
                    },
                    "3": {
                      "process_id": "array_element",
                      "arguments": {
                        "index": {
                          "from_node": "6"
                        },
                        "data": {
                          "from_parameter": "context"
                        }
                      }
                    },
                    "4": {
                      "process_id": "subtract",
                      "arguments": {
                        "x": {
                          "from_parameter": "index"
                        },
                        "y": 1
                      }
                    },
                    "6": {
                      "process_id": "add",
                      "arguments": {
                        "x": {
                          "from_parameter": "index"
                        },
                        "y": 1
                      }
                    },
                    "7": {
                      "process_id": "lt",
                      "arguments": {
                        "x": {
                          "from_node": "4"
                        },
                        "y": 0
                      }
                    },
                    "9": {
                      "process_id": "count",
                      "arguments": {
                        "data": {
                          "from_parameter": "context"
                        },
                        "condition": true
                      }
                    },
                    "10": {
                      "process_id": "gte",
                      "arguments": {
                        "x": {
                          "from_node": "6"
                        },
                        "y": {
                          "from_node": "9"
                        }
                      }
                    },
                    "11": {
                      "process_id": "if",
                      "arguments": {
                        "value": {
                          "from_node": "10"
                        },
                        "accept": {
                          "from_node": "3"
                        }
                      }
                    },
                    "12": {
                      "process_id": "if",
                      "arguments": {
                        "value": {
                          "from_node": "7"
                        },
                        "accept": {
                          "from_node": "1"
                        }
                      }
                    },
                    "16": {
                      "process_id": "array_create",
                      "arguments": {
                        "data": [
                          {
                            "from_node": "12"
                          },
                          {
                            "from_parameter": "x"
                          },
                          {
                            "from_node": "11"
                          }
                        ],
                        "repeat": 1
                      }
                    },
                    "17": {
                      "process_id": "mean",
                      "arguments": {
                        "data": {
                          "from_node": "16"
                        }
                      },
                      "result": true
                    }
                  }
                }
              },
              "result": true
            }
          }
        },
        "data": {
          "from_parameter": "data"
        }
      },
      "result": true
    }
  },
  "parameters": [
    {
      "schema": {
        "type": "object",
        "subtype": "raster-cube",
        "title": "Raster data cube",
        "description": "A raster data cube, an image collection stored at the back-end. Different back-ends have different internal representations for this data structure."
      },
      "name": "data"
    }
  ]
}

Results in:

# Import required packages
import openeo
from openeo.processes import process

# Connect to the back-end
connection = openeo.connect("https://openeo.cloud")
# ToDo: Here you need to authenticate with authenticate_basic() or authenticate_OIDC()

# Set the metadata for the process
# parameters: [{"schema": {"type": "object", "subtype": "raster-cube", "title": "Raster data cube", "description": "A raster data cube, an image collection stored at the back-end. Different back-ends have different internal representations for this data structure.", "default": None}, "name": "data"}]

# ToDo: Here you need to set values for the parameters
data = None

def fn1(data, context = None):
    def fn1(x, index, label = None, context = None):
        datacube4 = process("subtract", x = index, y = 1)
        datacube6 = process("add", x = index, y = 1)
        datacube9 = process("count", data = context, condition = True)
        datacube1 = process("array_element", index = datacube4, data = context)
        datacube7 = process("lt", x = datacube4, y = 0)
        datacube3 = process("array_element", index = datacube6, data = context)
        datacube10 = process("gte", x = datacube6, y = datacube9)
        datacube12 = process("if", value = datacube7, accept = datacube1)
        datacube11 = process("if", value = datacube10, accept = datacube3)
        datacube16 = process("array_create", data = [datacube12, x, datacube11], repeat = 1)
        datacube17 = process("mean", data = datacube16)
        return datacube17

    datacube1 = process("array_apply", context = data, data = data, process = fn1)
    return datacube1

datacube1 = connection.datacube_from_process("apply_dimension", dimension = "t", process = fn1, data = data)

# The process can be executed synchronously (see below), as batch job or as web service now
result = connection.execute(datacube1)

The names are duplicated and functions should not be nested.

m-mohr commented 2 years ago

Function nesting is fine in all languages, even Python. So will not fix this. The name generation has been fixed though.