Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-lambda-python: does command_hooks even work? #25203

Closed
rbailey-godaddy opened this issue Apr 20, 2023 · 7 comments
Closed

aws-lambda-python: does command_hooks even work? #25203

rbailey-godaddy opened this issue Apr 20, 2023 · 7 comments
Labels
@aws-cdk/aws-lambda-python closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. documentation This is a problem with documentation. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@rbailey-godaddy
Copy link

Describe the bug

See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-python-alpha-readme.html#command-hooks where this example is provided:

const entry = '/path/to/function';
new python.PythonFunction(this, 'function', {
  entry,
  runtime: Runtime.PYTHON_3_8,
  bundling: {
    commandHooks: {
      // run tests
      beforeBundling(inputDir: string): string[] {
        return ['pytest'];
      },
      afterBundling(inputDir: string): string[] {
        return ['pylint'];
      },
      // ...
    },
  },
});

I cannot find any example of equivalent code in python, or any statement by anybody claiming to have successfully defined such hooks.

My VSCode tool tips tell me that in this context:

        lambda_common_py310_layer = lambda_python_alpha.PythonLayerVersion(
            self.stack,
            "lambda-common-py310",
            entry="foo",
            bundling=lambda_python_alpha.BundlingOptions(
                command_hooks=what_goes_here,
            ),
            compatible_runtimes=[lambda_.Runtime.PYTHON_3_10],
        )

I should be providing something of type ICommandHooks, but the constructor of that type does not provide any parameters,

If I attempt to define my own class derived from ICommandHooks and replace the after_bundling() and before_bundling() methods, synthesis fails with:

TypeError: Don't know how to convert object to JSON: <stacks.base_stack.BaseStack.__init__.<locals>.MagicHooks object at 0x7f256efcc690>

Expected Behavior

I expect:

  1. The (python) documentation includes a (python) example of correct usage of this parameter
  2. It actually works

Current Behavior

Here is the full trace:

$ cdk synthesize cirruscan-base
Traceback (most recent call last):
  File "/home/sbailey/GitHub/CirrusScan/app.py", line 47, in <module>
    base = BaseStack(
           ^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/stacks/base_stack.py", line 363, in __init__
    lambda_common_py310_layer = lambda_python_alpha.PythonLayerVersion(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 112, in __call__
    inst = super().__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/aws_cdk/aws_lambda_python_alpha/__init__.py", line 1883, in __init__
    jsii.create(self.__class__, self, [scope, id, props])
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/jsii/_kernel/__init__.py", line 334, in create
    response = self.provider.create(
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 363, in create
    return self._process.send(request, CreateResponse)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 322, in send
    data = json.dumps(req_dict, default=jdefault).encode("utf8")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "/usr/lib/python3.11/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "/home/sbailey/GitHub/CirrusScan/.venv/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 149, in jdefault
    raise TypeError("Don't know how to convert object to JSON: %r" % obj)
TypeError: Don't know how to convert object to JSON: <stacks.base_stack.BaseStack.__init__.<locals>.MagicHooks object at 0x7f256efcc690>

Subprocess exited with error 1

The MagicHooks object is an instance of my derived class (see below)

Reproduction Steps

        class MagicHooks(lambda_python_alpha.ICommandHooks):
            def after_bundling(self, input_dir, output_dir):
                return []

            def before_bundling(self, input_dir, output_dir):
                return [
                    (
                        "poetry export -f requirements.txt --output requirements.txt"
                        " --without-hashes --only=common && "
                        "rm pyproject.toml poetry.lock"
                    )
                ]

        lambda_common_py310_layer = lambda_python_alpha.PythonLayerVersion(
            self.stack,
            "lambda-common-py310",
            entry="common",  # so common is a subdirectory,
            bundling=lambda_python_alpha.BundlingOptions(
                # We only want some of the dependencies; do the generation ourselves
                # so resolver knows what to do. See this reference:
                # https://pypi.org/project/aws-cdk.aws-lambda-python-alpha/
                command_hooks=MagicHooks(),
            ),
            compatible_runtimes=[lambda_.Runtime.PYTHON_3_10],
        )

Possible Solution

I suspect this is a documentation problem, but I am TypeScript-illiterate and at a loss regarding how to restate the given TypeScript example in native python.

Additional Information/Context

No response

CDK CLI Version

2.72.1 (build ddbfac7)

Framework Version

No response

Node.js Version

I don't know how to figure this out

OS

Debian Linux 12.0

Language

Python

Language Version

3.11.2 targeting 3.10

Other information

See #23330 where I believe this support was introduced.

@rbailey-godaddy rbailey-godaddy added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 20, 2023
@rbailey-godaddy
Copy link
Author

I am still fumbling through this, but it appears the solution is that the interface guidance at https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html must be followed, and defining my MagicHooks this way:

        @jsii.implements(lambda_python_alpha.ICommandHooks)
        class MagicHooks:
            def after_bundling(self, input_dir: str, output_dir: str) -> List[str]:
                return []

            def before_bundling(self, input_dir: str, output_dir: str) -> List[str]:
                return [
                    (
                        "poetry export -f requirements.txt --output requirements.txt"
                        " --without-hashes --only=common"
                    )
                ]

Will synthesize successfully. At least after I fix my other logic errors that result in the generated script failing LOL...

@pahud pahud removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 20, 2023
@pahud
Copy link
Contributor

pahud commented Apr 20, 2023

Yeah thank you for pointing it out 👍

@pahud pahud added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Apr 20, 2023
@rbailey-godaddy
Copy link
Author

I successfully coerced my build into working and this indeed was the key step.

@peterwoodworth
Copy link
Contributor

Seems like a documentation issue then?

@peterwoodworth peterwoodworth added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. documentation This is a problem with documentation. labels Apr 21, 2023
@github-actions
Copy link

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added closing-soon This issue will automatically close in 4 days unless further comments are made. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Apr 24, 2023
@bestickley
Copy link

This issue should be re-opened and the docs fixed. The docs here show invalid Python code :/

@adam-mah
Copy link

adam-mah commented Jun 15, 2024

This needs to be reopened, the documentation is beyond understandable
https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_lambda_nodejs/ICommandHooks.html

I managed to get it working like this as I was attempting to tackle Apple Silicon esbuild for sharp module.. (Didn't find alternative solution)

@jsii.implements(lambda_nodejs.ICommandHooks)
class CustomHooks:
    def before_bundling(self, input_dir: str, output_dir: str):
        return []

    def after_bundling(self, input_dir: str, output_dir: str):
        return [
            f"cd {output_dir}",
            "npm uninstall sharp",
            "npm install --arch=x86 --platform=linux sharp",
        ]

    def before_install(self, input_dir: str, output_dir: str):
        return []

And then use command_hooks=CustomHooks() in BundlingOptions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-lambda-python closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. documentation This is a problem with documentation. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

5 participants