def decorator()

in aws_codeseeder/codeseeder.py [0:0]


    def decorator(func: Callable[..., Any]) -> _classes.RemoteFunctionFn:
        stack_name = cfn.get_stack_name(seedkit_name=seedkit_name)
        stack_exists, stack_outputs = cfn.does_stack_exist(stack_name=stack_name)
        if not stack_exists:
            raise ValueError(f"Seedkit/Stack named {seedkit_name} is not yet deployed")
        if seedkit_name not in SEEDKIT_REGISTRY:
            SEEDKIT_REGISTRY[seedkit_name] = _classes.RegistryEntry(stack_outputs=stack_outputs)

        fn_module = function_module if function_module else func.__module__
        fn_name = function_name if function_name else func.__name__
        fn_id = f"{fn_module}:{fn_name}"

        registry_entry = SEEDKIT_REGISTRY[seedkit_name]
        config_object = registry_entry.config_object

        python_modules = decorator.python_modules  # type: ignore
        local_modules = decorator.local_modules  # type: ignore
        requirements_files = decorator.requirements_files  # type: ignore
        codebuild_image = decorator.codebuild_image  # type: ignore
        codebuild_role = decorator.codebuild_role  # type: ignore
        codebuild_environment_type = decorator.codebuild_environment_type  # type: ignore
        codebuild_compute_type = decorator.codebuild_compute_type  # type: ignore
        install_commands = decorator.install_commands  # type: ignore
        pre_build_commands = decorator.pre_build_commands  # type: ignore
        build_commands = decorator.build_commands  # type: ignore
        post_build_commands = decorator.post_build_commands  # type: ignore
        dirs = decorator.dirs  # type: ignore
        files = decorator.files  # type: ignore
        env_vars = decorator.env_vars  # type: ignore

        if not registry_entry.configured:
            if registry_entry.config_function:
                registry_entry.config_function(configuration=config_object)

                LOGGER.info("Seedkit Configuration Complete")
            registry_entry.configured = True

        # update modules and requirements after configuration
        python_modules = config_object.python_modules + python_modules
        local_modules = {**cast(Mapping[str, str], config_object.local_modules), **local_modules}
        requirements_files = {**cast(Mapping[str, str], config_object.requirements_files), **requirements_files}
        codebuild_image = codebuild_image if codebuild_image else config_object.codebuild_image
        codebuild_role = codebuild_role if codebuild_role else config_object.codebuild_role
        codebuild_environment_type = (
            codebuild_environment_type if codebuild_environment_type else config_object.codebuild_environment_type
        )
        codebuild_compute_type = (
            codebuild_compute_type if codebuild_compute_type else config_object.codebuild_compute_type
        )
        install_commands = config_object.install_commands + install_commands
        pre_build_commands = config_object.pre_build_commands + pre_build_commands
        build_commands = config_object.build_commands + build_commands
        post_build_commands = config_object.post_build_commands + post_build_commands
        dirs = {**cast(Mapping[str, str], config_object.dirs), **dirs}
        files = {**cast(Mapping[str, str], config_object.files), **files}
        env_vars = {**cast(Mapping[str, str], config_object.env_vars), **env_vars}

        LOGGER.debug("MODULE_IMPORTER: %s", MODULE_IMPORTER)
        LOGGER.debug("EXECUTING_REMOTELY: %s", EXECUTING_REMOTELY)

        if not EXECUTING_REMOTELY:
            if any([not os.path.isdir(p) for p in cast(Dict[str, str], local_modules).values()]):
                raise ValueError(f"One or more local modules could not be resolved: {local_modules}")
            if any([not os.path.isfile(p) for p in cast(Dict[str, str], requirements_files).values()]):
                raise ValueError(f"One or more requirements files could not be resolved: {requirements_files}")
            if any([not os.path.isdir(p) for p in cast(Dict[str, str], dirs).values()]):
                raise ValueError(f"One or more dirs could not be resolved: {dirs}")
            if any([not os.path.isfile(p) for p in cast(Dict[str, str], files).values()]):
                raise ValueError(f"One or more files could not be resolved: {files}")

        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            if EXECUTING_REMOTELY:
                # Exectute the module
                return func(*args, **kwargs)
            else:
                # Bundle and execute remotely in codebuild
                LOGGER.info("Beginning Remote Execution: %s", fn_id)
                fn_args = {"fn_id": fn_id, "args": args, "kwargs": kwargs}
                LOGGER.debug("fn_args: %s", fn_args)
                registry_entry = SEEDKIT_REGISTRY[seedkit_name]
                stack_outputs = registry_entry.stack_outputs

                cmds_install = [
                    "python3 -m venv ~/.venv",
                    ". ~/.venv/bin/activate",
                    "cd ${CODEBUILD_SRC_DIR}/bundle",
                    f"pip install aws-codeseeder~={__version__}",
                ]
                if requirements_files:
                    cmds_install += [f"pip install -r requirements-{f}" for f in requirements_files.keys()]
                if local_modules:
                    cmds_install += [f"pip install {m}/" for m in local_modules.keys()]
                if python_modules:
                    cmds_install.append(f"pip install {' '.join(python_modules)}")

                dirs_tuples = [(v, k) for k, v in local_modules.items()] + [(v, k) for k, v in dirs.items()]
                files_tuples = [(v, f"requirements-{k}") for k, v in requirements_files.items()] + [
                    (v, f"{k}") for k, v in files.items()
                ]

                bundle_zip = _bundle.generate_bundle(
                    fn_args=fn_args, dirs=dirs_tuples, files=files_tuples, bundle_id=bundle_id
                )
                buildspec = codebuild.generate_spec(
                    stack_outputs=cast(Dict[str, str], stack_outputs),
                    cmds_install=cmds_install + install_commands,
                    cmds_pre=[
                        ". ~/.venv/bin/activate",
                        "cd ${CODEBUILD_SRC_DIR}/bundle",
                    ]
                    + pre_build_commands,
                    cmds_build=[
                        ". ~/.venv/bin/activate",
                        "cd ${CODEBUILD_SRC_DIR}/bundle",
                        "codeseeder execute --args-file fn_args.json --debug",
                    ]
                    + build_commands,
                    cmds_post=[
                        ". ~/.venv/bin/activate",
                        "cd ${CODEBUILD_SRC_DIR}/bundle",
                    ]
                    + post_build_commands,
                )

                overrides = {}
                if codebuild_image:
                    overrides["imageOverride"] = codebuild_image
                if codebuild_role:
                    overrides["serviceRoleOverride"] = codebuild_role
                if codebuild_environment_type:
                    overrides["environmentTypeOverride"] = codebuild_environment_type
                if codebuild_compute_type:
                    overrides["computeTypeOverride"] = codebuild_compute_type
                if env_vars:
                    overrides["environmentVariablesOverride"] = [
                        {"name": k, "value": v, "type": "PLAINTEXT"} for k, v in env_vars.items()
                    ]

                _remote.run(
                    stack_outputs=cast(Dict[str, str], stack_outputs),
                    bundle_path=bundle_zip,
                    buildspec=buildspec,
                    timeout=timeout if timeout else config_object.timeout if config_object.timeout else 30,
                    codebuild_log_callback=codebuild_log_callback,
                    overrides=overrides if overrides != {} else None,
                )

        registry_entry.remote_functions[fn_id] = wrapper
        return wrapper