diff --git a/include/mg_procedure.h b/include/mg_procedure.h index 5d2527e81..b4a9f7592 100644 --- a/include/mg_procedure.h +++ b/include/mg_procedure.h @@ -1559,7 +1559,7 @@ enum mgp_error mgp_func_add_opt_arg(struct mgp_func *func, const char *name, str typedef void (*mgp_func_cb)(struct mgp_list *, struct mgp_func_context *, struct mgp_func_result *, struct mgp_memory *); -/// Register a Memgraph magic function +/// Register a Memgraph magic function. /// /// The `name` must be a sequence of digits, underscores, lowercase and /// uppercase Latin letters. The name must begin with a non-digit character. diff --git a/include/mgp.py b/include/mgp.py index 7b9d2dcb9..73b71d610 100644 --- a/include/mgp.py +++ b/include/mgp.py @@ -1179,16 +1179,15 @@ def read_proc(func: typing.Callable[..., Record]): """ Register `func` as a read-only procedure of the current module. - `read_proc` is meant to be used as a decorator function to register module - procedures. The registered `func` needs to be a callable which optionally - takes `ProcCtx` as the first argument. Other arguments of `func` will be - bound to values passed in the cypherQuery. The full signature of `func` - needs to be annotated with types. The return type must be - `Record(field_name=type, ...)` and the procedure must produce either a - complete Record or None. To mark a field as deprecated, use - `Record(field_name=Deprecated(type), ...)`. Multiple records can be - produced by returning an iterable of them. Registering generator functions - is currently not supported. + The decorator `read_proc` is meant to be used to register module procedures. + The registered `func` needs to be a callable which optionally takes + `ProcCtx` as its first argument. Other arguments of `func` will be bound to + values passed in the cypherQuery. The full signature of `func` needs to be + annotated with types. The return type must be `Record(field_name=type, ...)` + and the procedure must produce either a complete Record or None. To mark a + field as deprecated, use `Record(field_name=Deprecated(type), ...)`. + Multiple records can be produced by returning an iterable of them. + Registering generator functions is currently not supported. Example usage. @@ -1222,16 +1221,16 @@ def write_proc(func: typing.Callable[..., Record]): """ Register `func` as a writeable procedure of the current module. - `write_proc` is meant to be used as a decorator function to register module + The decorator `write_proc` is meant to be used to register module procedures. The registered `func` needs to be a callable which optionally takes `ProcCtx` as the first argument. Other arguments of `func` will be bound to values passed in the cypherQuery. The full signature of `func` needs to be annotated with types. The return type must be `Record(field_name=type, ...)` and the procedure must produce either a complete Record or None. To mark a field as deprecated, use - `Record(field_name=Deprecated(type), ...)`. Multiple records can be - produced by returning an iterable of them. Registering generator functions - is currently not supported. + `Record(field_name=Deprecated(type), ...)`. Multiple records can be produced + by returning an iterable of them. Registering generator functions is + currently not supported. Example usage. @@ -1459,8 +1458,9 @@ def transformation(func: typing.Callable[..., Record]): class FuncCtx: """Context of a function being executed. - Access to a FuncCtx is only valid during a single execution of a transformation. - You should not globally store a FuncCtx instance. + Access to a FuncCtx is only valid during a single execution of a function in + a query. You should not globally store a FuncCtx instance. The graph object + within the FuncCtx is not mutable. """ __slots__ = "_graph" @@ -1475,6 +1475,45 @@ class FuncCtx: def function(func: typing.Callable): + """ + Register `func` as a user-defined function in the current module. + + The decorator `function` is meant to be used to register module functions. + The registered `func` needs to be a callable which optionally takes + `FuncCtx` as its first argument. Other arguments of `func` will be bound to + values passed in the Cypher query. Only the funcion arguments need to be + annotated with types. The return type doesn't need to be specified, but it + has to be supported by `mgp.Any`. Registering generator functions is + currently not supported. + + Example usage. + + ``` + import mgp + @mgp.function + def func_example(context: mgp.FuncCtx, + required_arg: str, + optional_arg: mgp.Nullable[str] = None + ): + return_args = [required_arg] + if optional_arg is not None: + return_args.append(optional_arg) + # Return any kind of result supported by mgp.Any + return return_args + ``` + + The example function above returns a list of provided arguments: + * `required_arg` is always present and its value is the first argument of + the function. + * `optional_arg` is present if the second argument of the function is not + `null`. + Any errors can be reported by raising an Exception. + + The function can be invoked in Cypher using the following calls: + RETURN example.func_example("first argument", "second_argument"); + RETURN example.func_example("first argument"); + Naturally, you may pass in different arguments. + """ raise_if_does_not_meet_requirements(func) register_func = _mgp.Module.add_function sig = inspect.signature(func)