(python): Allow for Props classes to be passed into construct constructors
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 267
- Avg merge
- 1d 25m
- Merged PRs (30d)
- 14
Description
In other languages, the properties for an L2 construct are encapsulated in a Props class, and passed into the constructor of that class.
For example, to create a lambda [Function](https://docs.aws.amazon.com/cdk/api/latest/typescript/api/aws-lambda/function.html#constructors) you pass in an instance of [FunctionProps](https://docs.aws.amazon.com/cdk/api/latest/typescript/api/aws-lambda/functionprops.html#aws_lambda_FunctionProps).
However for Python, [the constructor for Function](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_lambda/Function.html) takes all the properties as named parameters. In the generated source code, an instance of [FunctionProps](https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_lambda/FunctionProps.html) is constructed from those named parameters. However it is not possible to use an instance of FunctionProps to construct a Function.
Allowing for props to be provided either using the current method, or by providing an instance of the Props class would unlock some use cases.
### Use Case
My use case is that I'm trying to build a library of standard constructs for my team's use. In particular, I am creating standard Cloudwatch definitions for use across our applications.
I want our alarms to be generated based on the attributes of the constructs being monitored. For example, for Lambda's, I want an alarm that fires if execution durations are reaching 90% of the handler timeout. For Elasticsearch domains, I want to know the EBS volume size so I can know when disk space is less than 5% of the volume size.
The actual CDK constructs themselves, aws_lambda.Function, aws_elasticsearch.Domain and so on, are not suitable for this because they do not expose all their properties to be publicly read.
The Props classes would be ideal for this. I could configure my CDK construct with an instance of a Props class, and then also pass that into my custom constructs.
I could use this solution today with another language; this limitation only exists in Python.
### Proposed Solution
Because the Python classes are generated, it shouldn't be too difficult to add an overload in a backwards compatible fashion. Simply generate an additional keyword argument called `props` for every CDK L2 construct, and allow construction either using the existing keyword argument, or by providing a Props class to props. I see usage looking like:
```
lambda_function_props = aws_lambda.FunctionProps(
handler="index.handler",
runtime=aws_lambda.Runtime.PYTHON_3_9,
code=aws_lambda.Code.asset("lambdas/module"),
)
lambda_function = aws_lambda.Function(
scope=self,
id="ElasticsearchIndexManagerFunction",
props=lambda_function_props,
)
```
Which would then allow my reuse of the properties elsewhere.
```
lambda_alarming = CustomLambdaAlarmingConstruct(
scope=self,
id="CustomLambdaAlarmingConstruct",
lambda_function_props = lambda_function_props,
alarm_topic= alarm_topic,
)
```
### Other
The one potential issue I see here is that there'd need to be no conflicts with the `props` keyword within the Props classes; hopefully that's a reserved word as `scope` and `id` clearly must be.
* [ ] :wave: I may be able to implement this feature request
* [ ] :warning: This feature might incur a breaking change
---
This is a :rocket: Feature Request
Contributor guide
Research direction
Start by tracing how jsii generates Python constructors for L2 constructs such as Function and FunctionProps. Check how the proposed props keyword would coexist with existing named parameters and Props fields. Done means generated Python constructors accept either the current parameters or a Props instance without breaking existing usage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, typescript
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100