-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat: Add python support to cdk init #2130
Changes from 4 commits
c6bfc0a
269f1fd
8f23fa7
713f4a2
406d846
23b413c
55c5639
46de258
9d30dcc
85ccb5b
f36ae06
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.swp | ||
package-lock.json | ||
__pycache__ | ||
.pytest_cache | ||
.env |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
|
||
# Welcome to your CDK Python project! | ||
|
||
You should explore the contents of this template. It demonstrates a CDK app with two instances of | ||
a stack (`HelloStack`) which also uses a user-defined construct (`HelloConstruct`). | ||
|
||
The `cdk.json` file tells the CDK Toolkit how to execute your app. It uses a script called `app.sh` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we don't have an app.sh script here (which is a good thing). |
||
to do that. | ||
|
||
This project is set up like a standard Python project. The initialization process also creates | ||
a virtualenv within this project, stored under the .env directory. | ||
|
||
After the init process completes, you can use the following steps to get your project set up. | ||
|
||
``` | ||
$ source .env/bin/activate | ||
$ pip install -r requirements.txt | ||
$ python setup.py develop | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
``` | ||
|
||
At this point you can now synthesize the CloudFormation template for this code. | ||
|
||
``` | ||
$ cdk synth | ||
``` | ||
|
||
You can now begin exploring the source code, contained in the hello directory. | ||
There is also a very trivial test included that can be run like this: | ||
|
||
``` | ||
$ pytest | ||
``` | ||
|
||
garnaat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
To add additional dependencies, for example other CDK libraries, just add to | ||
your requirements.txt file and rerun the `pip install -r requirements.txt` | ||
command. | ||
|
||
# Useful commands | ||
|
||
* `cdk ls` list all stacks in the app | ||
* `cdk synth` emits the synthesized CloudFormation template | ||
* `cdk deploy` deploy this stack to your default AWS account/region | ||
* `cdk diff` compare deployed stack with current state | ||
* `cdk docs` open CDK documentation | ||
|
||
Enjoy! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"app": "python3 hello/hello_stack.py" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this include running via the venv? Isn't that a better experience than requiring users to have pre-actived their shell and THEN running There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's a good idea. We should be able to just point to the python3 executable in the virtualenv. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The EXE on Windows (for 3.7 at least as I just installed it last week) is just python. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This gets ugly. If we are using a virtualenv that has been created using Python3 then there is no real need to say We could try Maybe this is an argument against trying to create the virtualenv during the init process. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is possible to actually have the app entrypoint an executable file that takes care of all these details, so eventually {
"app": "bin/my-awesome-app"
} |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from aws_cdk import ( | ||
aws_iam as iam, | ||
aws_s3 as s3, | ||
cdk, | ||
) | ||
|
||
|
||
class HelloConstruct(cdk.Construct): | ||
|
||
@property | ||
def buckets(self): | ||
return tuple(self._buckets) | ||
|
||
def __init__(self, scope: cdk.Construct, id: str, num_buckets: int) -> None: | ||
super().__init__(scope, id) | ||
self._buckets = [] | ||
for i in range(0, num_buckets): | ||
self._buckets.append(s3.Bucket(self, f"Bucket-{i}")) | ||
|
||
def grant_read(self, principal: iam.IPrincipal): | ||
for b in self.buckets: | ||
b.grant_read(principal, "*") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from aws_cdk import ( | ||
aws_iam as iam, | ||
aws_sqs as sqs, | ||
aws_sns as sns, | ||
cdk | ||
) | ||
|
||
from hello_construct import HelloConstruct | ||
|
||
class MyStack(cdk.Stack): | ||
|
||
def __init__(self, app: cdk.App, id: str) -> None: | ||
super().__init__(app, id) | ||
|
||
queue = sqs.Queue( | ||
garnaat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self, | ||
"MyFirstQueue", | ||
visibility_timeout_sec=300, | ||
) | ||
|
||
topic = sns.Topic( | ||
self, | ||
"MyFirstTopic", | ||
display_name="My First Topic" | ||
) | ||
|
||
topic.subscribe_queue(queue) | ||
|
||
hello = HelloConstruct(self, "foobar", num_buckets=4) | ||
user = iam.User(self, "MyUser") | ||
garnaat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
hello.grant_read(user) | ||
|
||
|
||
app = cdk.App() | ||
garnaat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
MyStack(app, "hello-cdk-1") | ||
MyStack(app, "hello-cdk-2") | ||
|
||
app.run() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
aws-cdk.cdk | ||
aws-cdk.aws_iam | ||
aws-cdk.aws_sqs | ||
aws-cdk.aws_sns | ||
aws-cdk.aws_s3 | ||
pytest |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import json | ||
import setuptools | ||
|
||
|
||
with open("README.md") as fp: | ||
long_description = fp.read() | ||
|
||
|
||
setuptools.setup( | ||
name="hello", | ||
version="0.0.1", | ||
|
||
description="A sample CDK Python app", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
|
||
author="author", | ||
|
||
package_dir={"": "hello"}, | ||
packages=setuptools.find_packages(where="hello"), | ||
|
||
install_requires=[ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense in python-land to have this duplicated with requirements.txt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Many packages use both but I have simplified this to put the requirements in the |
||
"aws-cdk.cdk", | ||
"aws-cdk.aws_iam", | ||
"aws-cdk.aws_sqs", | ||
"aws-cdk.aws_sns", | ||
"aws-cdk.aws_s3", | ||
], | ||
|
||
python_requires=">=3.6", | ||
|
||
classifiers=[ | ||
"Development Status :: 4 - Beta", | ||
|
||
"Intended Audience :: Developers", | ||
|
||
"License :: OSI Approved :: Apache Software License", | ||
|
||
"Programming Language :: JavaScript", | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Programming Language :: Python :: 3.6", | ||
"Programming Language :: Python :: 3.7", | ||
"Programming Language :: Python :: 3.8", | ||
|
||
"Topic :: Software Development :: Code Generators", | ||
"Topic :: Utilities", | ||
|
||
"Typing :: Typed", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import unittest | ||
|
||
from aws_cdk import cdk | ||
|
||
from hello.hello_construct import HelloConstruct | ||
|
||
class TestHelloConstruct(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.app = cdk.App() | ||
self.stack = cdk.Stack(self.app, "TestStack") | ||
|
||
def test_num_buckets(self): | ||
num_buckets = 10 | ||
hello = HelloConstruct(self.stack, "Test1", num_buckets) | ||
assert len(hello.buckets) == num_buckets |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,8 @@ async function postInstall(language: string, canUseNetwork: boolean) { | |
return await postInstallTypescript(canUseNetwork); | ||
case 'java': | ||
return await postInstallJava(canUseNetwork); | ||
case 'python': | ||
return await postInstallPython(canUseNetwork); | ||
} | ||
} | ||
|
||
|
@@ -260,6 +262,20 @@ async function postInstallJava(canUseNetwork: boolean) { | |
await execute('mvn', 'package'); | ||
} | ||
|
||
async function postInstallPython(canUseNetwork: boolean) { | ||
if (!canUseNetwork) { | ||
print(`Please run ${colors.green('python -m venv .env')}!`); | ||
return; | ||
} | ||
|
||
print(`Executing ${colors.green('python -m venv .env')}`); | ||
try { | ||
await execute('python3', '-m venv', '.env'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to also do the |
||
} catch (e) { | ||
throw new Error(`${colors.green('python3 -m venv .env')} failed: ` + e.message); | ||
} | ||
} | ||
|
||
/** | ||
* @param dir a directory to be checked | ||
* @returns true if ``dir`` is within a git repository. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention python version used.