├── .changes ├── 0.1.0.json ├── 0.10.0.json ├── 0.10.1.json ├── 0.2.0.json ├── 0.3.0.json ├── 0.4.0.json ├── 0.5.0.json ├── 0.5.1.json ├── 0.6.0.json ├── 0.7.0.json ├── 0.8.0.json ├── 0.8.1.json ├── 0.8.2.json ├── 0.9.0.json ├── 1.0.0.json ├── 1.0.0b1.json ├── 1.0.0b2.json ├── 1.0.1.json ├── 1.0.2.json ├── 1.0.3.json ├── 1.0.4.json ├── 1.1.0.json ├── 1.1.1.json ├── 1.10.0.json ├── 1.11.0.json ├── 1.11.1.json ├── 1.12.0.json ├── 1.13.0.json ├── 1.13.1.json ├── 1.14.0.json ├── 1.14.1.json ├── 1.15.0.json ├── 1.15.1.json ├── 1.16.0.json ├── 1.17.0.json ├── 1.18.0.json ├── 1.18.1.json ├── 1.19.0.json ├── 1.2.0.json ├── 1.2.1.json ├── 1.2.2.json ├── 1.2.3.json ├── 1.20.0.json ├── 1.20.1.json ├── 1.21.0.json ├── 1.21.1.json ├── 1.21.2.json ├── 1.21.3.json ├── 1.21.4.json ├── 1.21.5.json ├── 1.21.6.json ├── 1.21.7.json ├── 1.21.8.json ├── 1.21.9.json ├── 1.22.0.json ├── 1.22.1.json ├── 1.22.2.json ├── 1.22.3.json ├── 1.22.4.json ├── 1.23.0.json ├── 1.24.0.json ├── 1.24.1.json ├── 1.24.2.json ├── 1.25.0.json ├── 1.26.0.json ├── 1.26.1.json ├── 1.26.2.json ├── 1.26.3.json ├── 1.26.4.json ├── 1.26.5.json ├── 1.26.6.json ├── 1.27.0.json ├── 1.27.1.json ├── 1.27.2.json ├── 1.27.3.json ├── 1.28.0.json ├── 1.29.0.json ├── 1.3.0.json ├── 1.30.0.json ├── 1.31.0.json ├── 1.31.1.json ├── 1.31.2.json ├── 1.31.3.json ├── 1.31.4.json ├── 1.32.0.json ├── 1.4.0.json ├── 1.5.0.json ├── 1.6.0.json ├── 1.6.1.json ├── 1.6.2.json ├── 1.7.0.json ├── 1.8.0.json ├── 1.9.0.json ├── 1.9.1.json └── templates │ └── changelog ├── .coveragerc ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── run-tests.yml │ └── stale-issue.yml ├── .gitignore ├── .pylintrc ├── .python-version ├── CHANGELOG.md ├── CODE_OF_CONDUCT.rst ├── CONTRIBUTING.rst ├── LICENSE ├── MANIFEST.in ├── Makefile ├── NOTICE ├── README.rst ├── chalice ├── __init__.py ├── analyzer.py ├── api │ └── __init__.py ├── app.py ├── awsclient.py ├── cdk │ ├── __init__.py │ └── construct.py ├── cli │ ├── __init__.py │ ├── factory.py │ ├── filewatch │ │ ├── __init__.py │ │ ├── eventbased.py │ │ └── stat.py │ ├── newproj.py │ └── reloader.py ├── compat.py ├── config.py ├── constants.py ├── deploy │ ├── __init__.py │ ├── appgraph.py │ ├── deployer.py │ ├── executor.py │ ├── models.py │ ├── packager.py │ ├── planner.py │ ├── swagger.py │ ├── sweeper.py │ └── validate.py ├── invoke.py ├── local.py ├── logs.py ├── package.py ├── pipeline.py ├── policies-extra.json ├── policies.json ├── policy.py ├── py.typed ├── templates │ ├── 0000-rest-api │ │ ├── .chalice │ │ │ └── config.json │ │ ├── .gitignore │ │ ├── app.py │ │ ├── chalicelib │ │ │ └── __init__.py │ │ ├── metadata.json │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── test_app.py │ ├── 0002-s3-event-handler │ │ ├── .chalice │ │ │ └── config.json │ │ ├── .gitignore │ │ ├── app.py │ │ ├── chalicelib │ │ │ └── __init__.py │ │ ├── metadata.json │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── test_app.py │ ├── 0007-lambda-only │ │ ├── .chalice │ │ │ └── config.json │ │ ├── .gitignore │ │ ├── app.py │ │ ├── chalicelib │ │ │ └── __init__.py │ │ ├── metadata.json │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── test_app.py │ ├── 0009-legacy │ │ ├── .chalice │ │ │ └── config.json │ │ ├── .gitignore │ │ ├── app.py │ │ ├── metadata.json │ │ └── requirements.txt │ └── 6001-cdk-ddb │ │ ├── README.rst │ │ ├── infrastructure │ │ ├── app.py │ │ ├── cdk.json │ │ ├── requirements.txt │ │ └── stacks │ │ │ ├── __init__.py │ │ │ └── chaliceapp.py │ │ ├── metadata.json │ │ ├── requirements.txt │ │ └── runtime │ │ ├── .chalice │ │ └── config.json │ │ ├── .gitignore │ │ ├── app.py │ │ └── requirements.txt ├── test.py ├── utils.py └── vendored │ ├── __init__.py │ └── botocore │ ├── __init__.py │ └── regions.py ├── docs ├── Makefile └── source │ ├── _static │ ├── custom.css │ └── fonts │ │ └── open-sans │ │ ├── fonts │ │ ├── OpenSans-Bold-webfont.eot │ │ ├── OpenSans-Bold-webfont.svg │ │ ├── OpenSans-Bold-webfont.ttf │ │ ├── OpenSans-Bold-webfont.woff │ │ ├── OpenSans-BoldItalic-webfont.eot │ │ ├── OpenSans-BoldItalic-webfont.svg │ │ ├── OpenSans-BoldItalic-webfont.ttf │ │ ├── OpenSans-BoldItalic-webfont.woff │ │ ├── OpenSans-ExtraBold-webfont.eot │ │ ├── OpenSans-ExtraBold-webfont.svg │ │ ├── OpenSans-ExtraBold-webfont.ttf │ │ ├── OpenSans-ExtraBold-webfont.woff │ │ ├── OpenSans-ExtraBoldItalic-webfont.eot │ │ ├── OpenSans-ExtraBoldItalic-webfont.svg │ │ ├── OpenSans-ExtraBoldItalic-webfont.ttf │ │ ├── OpenSans-ExtraBoldItalic-webfont.woff │ │ ├── OpenSans-Italic-webfont.eot │ │ ├── OpenSans-Italic-webfont.svg │ │ ├── OpenSans-Italic-webfont.ttf │ │ ├── OpenSans-Italic-webfont.woff │ │ ├── OpenSans-Light-webfont.eot │ │ ├── OpenSans-Light-webfont.svg │ │ ├── OpenSans-Light-webfont.ttf │ │ ├── OpenSans-Light-webfont.woff │ │ ├── OpenSans-LightItalic-webfont.eot │ │ ├── OpenSans-LightItalic-webfont.svg │ │ ├── OpenSans-LightItalic-webfont.ttf │ │ ├── OpenSans-LightItalic-webfont.woff │ │ ├── OpenSans-Regular-webfont.eot │ │ ├── OpenSans-Regular-webfont.svg │ │ ├── OpenSans-Regular-webfont.ttf │ │ ├── OpenSans-Regular-webfont.woff │ │ ├── OpenSans-Semibold-webfont.eot │ │ ├── OpenSans-Semibold-webfont.svg │ │ ├── OpenSans-Semibold-webfont.ttf │ │ ├── OpenSans-Semibold-webfont.woff │ │ ├── OpenSans-SemiboldItalic-webfont.eot │ │ ├── OpenSans-SemiboldItalic-webfont.svg │ │ ├── OpenSans-SemiboldItalic-webfont.ttf │ │ └── OpenSans-SemiboldItalic-webfont.woff │ │ └── stylesheet.css │ ├── _templates │ └── layout.html │ ├── api.rst │ ├── chalicedocs.py │ ├── conf.py │ ├── faq.rst │ ├── img │ ├── auto-layer.png │ ├── chalice-logo-icon-whitespace.png │ ├── chalice-logo-whitespace.png │ └── no-auto-layer.png │ ├── index.rst │ ├── main.rst │ ├── quickstart.rst │ ├── samples │ ├── index.rst │ ├── media-query │ │ ├── code │ │ │ ├── .chalice │ │ │ │ ├── config.json │ │ │ │ └── policy-dev.json │ │ │ ├── app.py │ │ │ ├── chalicelib │ │ │ │ ├── __init__.py │ │ │ │ ├── db.py │ │ │ │ └── rekognition.py │ │ │ ├── recordresources.py │ │ │ ├── requirements.txt │ │ │ └── resources.json │ │ ├── docs │ │ │ └── assets │ │ │ │ ├── appexample.jpg │ │ │ │ └── architecture.png │ │ └── index.rst │ └── todo-app │ │ ├── code │ │ ├── .chalice │ │ │ ├── config.json │ │ │ └── policy-dev.json │ │ ├── .gitignore │ │ ├── app.py │ │ ├── chalicelib │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ └── db.py │ │ ├── create-resources.py │ │ ├── requirements-dev.txt │ │ ├── requirements.txt │ │ ├── tests │ │ │ ├── __init__.py │ │ │ └── test_db.py │ │ └── users.py │ │ ├── docs │ │ └── assets │ │ │ └── architecture.jpg │ │ └── index.rst │ ├── theme │ └── smithy │ │ ├── globaltoc.html │ │ ├── landing.html │ │ ├── layout.html │ │ ├── static │ │ ├── asciinema-player.css │ │ ├── asciinema-player.js │ │ ├── bootstrap-reboot.css │ │ ├── casts │ │ │ ├── chalice-quickstart-old.cast │ │ │ └── chalice-quickstart.cast │ │ ├── custom-tabs.css │ │ ├── default.css_t │ │ ├── favicon.png │ │ └── img │ │ │ ├── chalice-logo-icon-small.png │ │ │ ├── chalice-logo-icon-whitespace.png │ │ │ ├── chalice-logo-whitespace.png │ │ │ ├── coding.png │ │ │ ├── maintenance.png │ │ │ ├── programming.png │ │ │ └── speed.svg │ │ └── theme.conf │ ├── topics │ ├── authorizers.rst │ ├── blueprints.rst │ ├── cd.rst │ ├── cfn.rst │ ├── configfile.rst │ ├── domainname.rst │ ├── events.rst │ ├── experimental.rst │ ├── index.rst │ ├── logging.rst │ ├── middleware.rst │ ├── multifile.rst │ ├── packaging.rst │ ├── purelambda.rst │ ├── pyversion.rst │ ├── routing.rst │ ├── sdks.rst │ ├── stages.rst │ ├── testing.rst │ ├── tf.rst │ ├── views.rst │ └── websockets.rst │ ├── tutorials │ ├── basicrestapi.rst │ ├── cdk.rst │ ├── customdomain.rst │ ├── events.rst │ ├── index.rst │ ├── wschat.rst │ └── wsecho.rst │ └── upgrading.rst ├── requirements-dev.in ├── requirements-dev.txt ├── requirements-test.in ├── requirements-test.txt ├── scripts ├── gh-page-docs └── release ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── aws ├── __init__.py ├── conftest.py ├── test_features.py ├── test_websockets.py ├── testapp │ ├── .chalice │ │ └── config.json │ ├── app-redeploy.py │ ├── app.py │ ├── chalicelib │ │ └── __init__.py │ └── requirements.txt └── testwebsocketapp │ ├── .chalice │ └── config.json │ ├── .gitignore │ ├── app-redeploy.py │ ├── app.py │ └── requirements.txt ├── conftest.py ├── functional ├── __init__.py ├── api │ ├── __init__.py │ └── test_package.py ├── basicapp │ ├── .chalice │ │ └── config.json │ ├── .gitignore │ ├── app.py │ └── requirements.txt ├── cdk │ ├── __init__.py │ └── test_construct.py ├── cli │ ├── __init__.py │ ├── test_cli.py │ ├── test_factory.py │ └── test_reloader.py ├── conftest.py ├── envapp │ ├── .chalice │ │ └── config.json │ ├── .gitignore │ ├── app.py │ └── requirements.txt ├── test_awsclient.py ├── test_deployer.py ├── test_local.py ├── test_package.py └── test_utils.py ├── integration ├── __init__.py ├── conftest.py ├── test_cli.py └── test_package.py ├── plugins ├── codelinter.py └── testlinter.py └── unit ├── __init__.py ├── cli ├── __init__.py ├── filewatch │ ├── test_eventbased.py │ └── test_stat.py ├── test_cli.py └── test_newproj.py ├── conftest.py ├── deploy ├── __init__.py ├── test_appgraph.py ├── test_deployer.py ├── test_executor.py ├── test_models.py ├── test_packager.py ├── test_planner.py ├── test_swagger.py └── test_validate.py ├── test_analyzer.py ├── test_app.py ├── test_awsclient.py ├── test_config.py ├── test_invoke.py ├── test_local.py ├── test_logs.py ├── test_package.py ├── test_pipeline.py ├── test_policy.py ├── test_test.py ├── test_utils.py └── vendored ├── __init__.py └── botocore ├── __init__.py └── test_regions.py /.changes/0.1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Require ``virtualenv`` as a package dependency. (#33)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "CLI", 11 | "description": "Add ``--profile`` option when creating a new project (#28)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Add support for more error codes exceptions (#34)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Improve error validation when routes containing a\ntrailing ``/`` char (#65)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "rest-api", 26 | "description": "Validate duplicate route entries (#79)", 27 | "type": "enhancement" 28 | }, 29 | { 30 | "category": "policy", 31 | "description": "Ignore lambda expressions in policy analyzer (#74)", 32 | "type": "enhancement" 33 | }, 34 | { 35 | "category": "rest-api", 36 | "description": "Print original error traceback in debug mode (#50)", 37 | "type": "enhancement" 38 | }, 39 | { 40 | "category": "rest-api", 41 | "description": "Add support for authenticate routes (#14)", 42 | "type": "feature" 43 | }, 44 | { 45 | "category": "policy", 46 | "description": "Add ability to disable IAM role management (#61)", 47 | "type": "feature" 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /.changes/0.10.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "deployment", 6 | "description": "Fix issue where provided ``iam_role_arn`` was not respected on\nredeployments of chalice applications and in the CloudFormation template\ngenerated by ``chalice package`` (#339)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "config", 11 | "description": "Fix ``autogen_policy`` in config being ignored (#367)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Add support for view functions that share the same view url but\ndiffer by HTTP method (#81)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "deployment", 21 | "description": "Improve deployment error messages for deployment packages that are\ntoo large (#246, #330, #380)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "rest-api", 26 | "description": "Add support for built-in authorizers (#356)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/0.10.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "deployment", 6 | "description": "Fix deployment issue for projects deployed with versions\nprior to 0.10.0 (#387)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "policy", 11 | "description": "Fix crash in analyzer when encountering genexprs and listcomps (#263)", 12 | "type": "bugfix" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/0.2.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Add support for input content types besides ``application/json`` (#96)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Allow ``ChaliceViewErrors`` to propagate, so that API Gateway\ncan properly map HTTP status codes in non debug mode (#113)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "deployment", 16 | "description": "Add windows compatibility (#31)", 17 | "type": "enhancement" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/0.3.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Fix bug with case insensitive headers (#129)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "CORS", 11 | "description": "Add initial support for CORS (#133)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "deployment", 16 | "description": "Only add API gateway permissions if needed (#48)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "policy", 21 | "description": "Fix error when dict comprehension is encountered during policy generation (#131)", 22 | "type": "bugfix" 23 | }, 24 | { 25 | "category": "CLI", 26 | "description": "Add ``--version`` and ``--debug`` options to the chalice CLI", 27 | "type": "enhancement" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/0.4.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "deployment", 6 | "description": "Fix issue where role name to arn lookup was failing due to lack of pagination (#139)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Raise errors when unknown kwargs are provided to ``app.route(...)`` (#144)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "config", 16 | "description": "Raise validation error when configuring CORS and an OPTIONS method (#142)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Add support for multi-file applications (#21)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "local", 26 | "description": "Add support for ``chalice local``, which runs a local HTTP server for testing (#22)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/0.5.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "logging", 6 | "description": "Add default application logger (#149)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "local", 11 | "description": "Return 405 when method is not supported when running\n``chalice local`` (#159)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "SDK", 16 | "description": "Add path params as requestParameters so they can be used\nin generated SDKs as well as cache keys (#163)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Map cognito user pool claims as part of request context (#165)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "CLI", 26 | "description": "Add ``chalice url`` command to print the deployed URL (#169)", 27 | "type": "feature" 28 | }, 29 | { 30 | "category": "deployment", 31 | "description": "Bump up retry limit on initial function creation to 30 seconds (#172)", 32 | "type": "enhancement" 33 | }, 34 | { 35 | "category": "local", 36 | "description": "Add support for ``DELETE`` and ``PATCH`` in ``chalice local`` (#167)", 37 | "type": "feature" 38 | }, 39 | { 40 | "category": "CLI", 41 | "description": "Add ``chalice generate-sdk`` command (#178)", 42 | "type": "feature" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /.changes/0.5.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "local", 6 | "description": "Add support for serializing decimals in ``chalice local`` (#187)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "local", 11 | "description": "Add stdout handler for root logger when using ``chalice local`` (#186)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "local", 16 | "description": "Map query string parameters when using ``chalice local`` (#184)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Support Content-Type with a charset (#180)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "deployment", 26 | "description": "Fix not all resources being retrieved due to pagination (#188)", 27 | "type": "bugfix" 28 | }, 29 | { 30 | "category": "deployment", 31 | "description": "Fix issue where root resource was not being correctly retrieved (#205)", 32 | "type": "bugfix" 33 | }, 34 | { 35 | "category": "deployment", 36 | "description": "Handle case where local policy does not exist\n(`29 `__)", 37 | "type": "bugfix" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /.changes/0.6.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "summary": "Check out the `upgrade notes for 0.6.0\n`__\nfor more detailed information about changes in this release.\n\n", 4 | "changes": [ 5 | { 6 | "category": "local", 7 | "description": "Add port parameter to local command (#220)", 8 | "type": "feature" 9 | }, 10 | { 11 | "category": "packaging", 12 | "description": "Add support for binary vendored packages (#182, #106, #42)", 13 | "type": "feature" 14 | }, 15 | { 16 | "category": "rest-api", 17 | "description": "Add support for customizing the returned HTTP response (#240, #218, #110, #30, #226)", 18 | "type": "feature" 19 | }, 20 | { 21 | "category": "packaging", 22 | "description": "Always inject latest runtime to allow for chalice upgrades (#245)", 23 | "type": "enhancement" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.changes/0.7.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CLI", 6 | "description": "Add ``chalice package`` command. This will\ncreate a SAM template and Lambda deployment package that\ncan be subsequently deployed by AWS CloudFormation. (#258)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "CLI", 11 | "description": "Add a ``--stage-name`` argument for creating chalice stages.\nA chalice stage is a completely separate set of AWS resources.\nAs a result, most configuration values can also be specified\nper chalice stage. (#264, #270)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "policy", 16 | "description": "Add support for ``iam_role_file``, which allows you to\nspecify the file location of an IAM policy to use for your app (#272)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "config", 21 | "description": "Add support for setting environment variables in your app (#273)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "CI-CD", 26 | "description": "Add a ``generate-pipeline`` command (#277)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/0.8.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "python", 6 | "description": "Add support for python3! (#296)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "packaging", 11 | "description": "Fix swagger generation when using ``api_key_required=True`` (#279)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "CI-CD", 16 | "description": "Fix ``generate-pipeline`` to install requirements file before packaging (#295)", 17 | "type": "bugfix" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/0.8.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "deployment", 6 | "description": "Alway overwrite existing API Gateway Rest API on updates (#305)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "CORS", 11 | "description": "Added more granular support for CORS (#311)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "local", 16 | "description": "Fix duplicate content type header in local model (#311)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Fix content type validation when charset is provided (#306)", 22 | "type": "bugfix" 23 | }, 24 | { 25 | "category": "rest-api", 26 | "description": "Add back custom authorizer support (#322)", 27 | "type": "enhancement" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/0.8.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CLI", 6 | "description": "Fix issue where ``--api-gateway-stage`` was being\nignored (#325)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "CLI", 11 | "description": "Add ``chalice delete`` command (#40)", 12 | "type": "feature" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/0.9.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Add support for ``IAM`` authorizer (#334)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "config", 11 | "description": "Add support for configuring ``lambda_timeout``, ``lambda_memory_size``,\nand ``tags`` in your AWS Lambda function (#347)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "packaging", 16 | "description": "Fix vendor directory contents not being importable locally (#350)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Add support for binary payloads (#348)", 22 | "type": "feature" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.0.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Change default API Gateway stage name to ``api`` (#431)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "local", 11 | "description": "Add support for ``CORSConfig`` in ``chalice local`` (#436)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "logging", 16 | "description": "Propagate ``DEBUG`` log level when setting ``app.debug`` (#386)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Add support for wildcard routes and HTTP methods in ``AuthResponse`` (#403)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "policy", 26 | "description": "Fix bug when analyzing list comprehensions (#412)", 27 | "type": "bugfix" 28 | }, 29 | { 30 | "category": "local", 31 | "description": "Update ``chalice local`` to use HTTP 1.1 (#448)", 32 | "type": "enhancement" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.changes/1.0.0b1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "summary": "Please read the `upgrade notes for 1.0.0b1\n`__\nfor more detailed information about upgrading to this release.\n\nNote: to install this beta version of chalice you must specify\n``pip install 'chalice>=1.0.0b1,<2.0.0'`` or\nuse the ``--pre`` flag for pip: ``pip install --pre chalice``.\n\n", 4 | "changes": [ 5 | { 6 | "category": "rest-api", 7 | "description": "Fix unicode responses being quoted in python 2.7 (#262)", 8 | "type": "bugfix" 9 | }, 10 | { 11 | "category": "event-source", 12 | "description": "Add support for scheduled events (#390)", 13 | "type": "feature" 14 | }, 15 | { 16 | "category": "event-source", 17 | "description": "Add support for pure lambda functions (#390)", 18 | "type": "feature" 19 | }, 20 | { 21 | "category": "packaging", 22 | "description": "Add support for wheel packaging. (#249)", 23 | "type": "feature" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.changes/1.0.0b2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "summary": "Please read the `upgrade notes for 1.0.0b2\n`__\nfor more detailed information about upgrading to this release.\n\nNote: to install this beta version of chalice you must specify\n``pip install 'chalice>=1.0.0b2,<2.0.0'`` or\nuse the ``--pre`` flag for pip: ``pip install --pre chalice``.\n", 4 | "changes": [ 5 | { 6 | "category": "local", 7 | "description": "Set env vars from config in ``chalice local`` (#396)", 8 | "type": "enhancement" 9 | }, 10 | { 11 | "category": "packaging", 12 | "description": "Fix edge case when building packages with optional c extensions (#421)", 13 | "type": "bugfix" 14 | }, 15 | { 16 | "category": "policy", 17 | "description": "Remove legacy ``policy.json`` file support. Policy files must\nuse the stage name, e.g. ``policy-dev.json`` (#430)", 18 | "type": "enhancement" 19 | }, 20 | { 21 | "category": "deployment", 22 | "description": "Fix issue where IAM role policies were updated twice on redeploys (#428)", 23 | "type": "bugfix" 24 | }, 25 | { 26 | "category": "rest-api", 27 | "description": "Validate route path is not an empty string (#432)", 28 | "type": "enhancement" 29 | }, 30 | { 31 | "category": "rest-api", 32 | "description": "Change route code to invoke view function with kwargs instead of\npositional args (#429)", 33 | "type": "enhancement" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.changes/1.0.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Only use alphanumeric characters for event names in SAM template (#450)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "config", 11 | "description": "Print useful error message when config.json is invalid (#458)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Fix api gateway stage being set incorrectly in non-default chalice stage\n(`#$70 `__)", 17 | "type": "bugfix" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.0.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Fix issue where requestParameters were not being mapped\ncorrectly resulting in invalid generated javascript SDKs (#498)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Fix issue where ``api_gateway_stage`` was being\nignored when set in the ``config.json`` file (#495)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Fix bug where ``raw_body`` would raise an exception if no HTTP\nbody was provided (#503)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "CLI", 21 | "description": "Fix bug where exit codes were not properly being propagated during packaging (#500)", 22 | "type": "bugfix" 23 | }, 24 | { 25 | "category": "local", 26 | "description": "Add support for Builtin Authorizers in local mode (#404)", 27 | "type": "feature" 28 | }, 29 | { 30 | "category": "packaging", 31 | "description": "Fix environment variables being passed to subprocess while packaging (#501)", 32 | "type": "bugfix" 33 | }, 34 | { 35 | "category": "rest-api", 36 | "description": "Allow view to require API keys as well as authorization (#473)", 37 | "type": "enhancement" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /.changes/1.0.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Fix issue with some packages with `-` or `.` in their distribution name (#555)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Fix issue where chalice local returned a 403 for successful OPTIONS requests (#554)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "local", 16 | "description": "Fix issue with chalice local mode causing http clients to hang on responses\nwith no body (#525)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "local", 21 | "description": "Add ``--stage`` parameter to ``chalice local`` (#545)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "policy", 26 | "description": "Fix issue with analyzer that followed recursive functions infinitely (#531)", 27 | "type": "bugfix" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.0.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Fix issue deploying some packages in Windows with utf-8 characters (#560)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "packaging", 11 | "description": "Add support for custom authorizers with ``chalice package`` (#580)", 12 | "type": "feature" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Default to ``None`` in local mode when no query parameters\nare provided (#593)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "local", 11 | "description": "Add support for binding a custom address for local dev server (#596)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Fix local mode handling of routes with trailing slashes (#582)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "config", 21 | "description": "Scale ``lambda_timeout`` parameter correctly in local mode (#579)", 22 | "type": "bugfix" 23 | }, 24 | { 25 | "category": "CI-CD", 26 | "description": "Add ``--codebuild-image`` to the ``generate-pipeline`` command (#609)", 27 | "type": "feature" 28 | }, 29 | { 30 | "category": "CI-CD", 31 | "description": "Add ``--source`` and ``--buildspec-file`` to the\n``generate-pipeline`` command (#609)", 32 | "type": "feature" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.changes/1.1.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CLI", 6 | "description": "Add ``--connection-timeout`` to the ``deploy`` command (#344)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "policy", 11 | "description": "Fix IAM role creation issue (#565)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "local", 16 | "description": "Fix `chalice local` handling of browser requests (#565)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "policy", 21 | "description": "Support async/await syntax in automatic policy generation (#565)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "packaging", 26 | "description": "Support additional PyPi package formats (.tar.bz2) (#720)", 27 | "type": "enhancement" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.10.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "websocket", 6 | "description": "Add experimental support for websockets (#1017)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "API Gateway Endpoint Type Configuration (#1160)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "API Gateway Resource Policy Configuration (#1160)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "packaging", 21 | "description": "Add --merge-template option to package command (#1195)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "packaging", 26 | "description": "Add support for packaging via terraform (#1129)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.11.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "config", 6 | "description": "Add support for stage independent lambda configuration (#1162)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "event-source", 11 | "description": "Add support for subscribing to CloudWatch Events (#1126)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "event-source", 16 | "description": "Add a ``description`` argument to CloudWatch schedule events (#1155)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Fix deployment of API Gateway resource policies (#1220)", 22 | "type": "bugfix" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.11.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "blueprint", 6 | "description": "Fix mouting blueprints with root routes (#1230)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Add support for multi-value headers responses (#1205)", 12 | "type": "feature" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.12.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CLI", 6 | "description": "Add ``generate-models`` command (#1245)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "websocket", 11 | "description": "Add ``close`` and ``info`` commands to websocket api (#1259)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "dependencies", 16 | "description": "Bump upper bound on PIP to ``<19.4`` (#1273, #1272)", 17 | "type": "enhancement" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.13.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "logs", 6 | "description": "Fix error for ``chalice logs`` when a Lambda function\nhas not been invoked (#1252)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "CORS", 11 | "description": "Add global CORS configuration (#70)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "packaging", 16 | "description": "Fix packaging simplejson (#1304)", 17 | "type": "bugfix" 18 | }, 19 | { 20 | "category": "python", 21 | "description": "Add support for Python 3.8 (#1315)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "authorizer", 26 | "description": "Add support for invocation role in custom authorizer (#1303)", 27 | "type": "feature" 28 | }, 29 | { 30 | "category": "packaging", 31 | "description": "Fix packaging on case-sensitive filesystems (#1356)", 32 | "type": "bugfix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.changes/1.13.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "local", 7 | "description": "Add support for multiValueHeaders in local mode (#1381)." 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "local", 12 | "description": "Make ``current_request`` thread safe in local mode (#759)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "local", 17 | "description": "Add support for cognito in local mode (#1377)." 18 | }, 19 | { 20 | "type": "bugfix", 21 | "category": "packaging", 22 | "description": "Fix terraform generation when injecting custom domains (#1237)" 23 | }, 24 | { 25 | "type": "enhancement", 26 | "category": "packaging", 27 | "description": "Ensure repeatable zip file generation (#1114)." 28 | }, 29 | { 30 | "type": "bugfix", 31 | "category": "CORS", 32 | "description": "Fix CORS request when returning compressed binary types (#1336)" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.changes/1.14.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "packaging", 7 | "description": "Fix pandas packaging regression (#1398)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "CLI", 12 | "description": "Add ``dev plan/appgraph`` commands (#1396)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "SQS", 17 | "description": "Validate queue name is used and not queue URL or ARN (#1388)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.14.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "pip", 7 | "description": "Update pip version range to 20.1." 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.15.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "blueprints", 7 | "description": "Mark blueprints as an accepted API (#1250)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "package", 12 | "description": "Add ability to generate and merge yaml CloudFormation templates (#1425)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "terraform", 17 | "description": "Allow generated terraform template to be used as a terraform module (#1300)" 18 | }, 19 | { 20 | "type": "feature", 21 | "category": "logs", 22 | "description": "Add support for tailing logs (#4)." 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.15.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "packaging", 7 | "description": "Fix setup.py dependencies where the wheel package was not being installed (#1435)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.16.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "local", 7 | "description": "Avoid error from cognito client credentials in local authorizer (#1447)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "package", 12 | "description": "Traverse symlinks to directories when packaging the vendor directory (#583)." 13 | }, 14 | { 15 | "type": "feature", 16 | "category": "DomainName", 17 | "description": "Add support for custom domain names to REST/WebSocket APIs (#1194)" 18 | }, 19 | { 20 | "type": "feature", 21 | "category": "auth", 22 | "description": "Add support for oauth scopes on routes (#1444)." 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.17.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Testing", 7 | "description": "Add Chalice test client (#1468)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "regions", 12 | "description": "Add support for non `aws` partitions including aws-cn and aws-us-gov (#792)." 13 | }, 14 | { 15 | "type": "bugfix", 16 | "category": "dependencies", 17 | "description": "Fix error when using old versions of click by requiring >=7" 18 | }, 19 | { 20 | "type": "bugfix", 21 | "category": "local", 22 | "description": "Fix local mode builtin authorizer not stripping query string from URL (#1470)" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.18.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Packaging", 7 | "description": "Add support for automatic layer creation (#1485, #1001)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.18.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Packaging", 7 | "description": "Add fallback to retrieve name/version from sdist (#1486)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Analyzer", 12 | "description": "Handle symbols with multiple (shadowed) namespaces (#1494)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.19.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Pipeline", 7 | "description": "Add a new v2 template for the deployment pipeline CloudFormation template (#1506)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.2.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "summary": "This release features a rewrite of the core deployment\ncode used in Chalice. This is a backwards compatible change\nfor users, but you may see changes to the autogenerated\nfiles Chalice creates.\nPlease read the `upgrade notes for 1.2.0\n`__\nfor more detailed information about upgrading to this release.\n\n", 4 | "changes": [ 5 | { 6 | "category": "rest-api", 7 | "description": "Print out full stack trace when an error occurs (#711)", 8 | "type": "enhancement" 9 | }, 10 | { 11 | "category": "rest-api", 12 | "description": "Add ``image/jpeg`` as a default binary content type (#707)", 13 | "type": "enhancement" 14 | }, 15 | { 16 | "category": "event-source", 17 | "description": "Add support for AWS Lambda only projects (#162, #640)", 18 | "type": "feature" 19 | }, 20 | { 21 | "category": "policy", 22 | "description": "Fix inconsistent IAM role generation with pure lambdas (#685)", 23 | "type": "bugfix" 24 | }, 25 | { 26 | "category": "deployment", 27 | "description": "Rewrite Chalice deployer to more easily support additional AWS resources (#604)", 28 | "type": "enhancement" 29 | }, 30 | { 31 | "category": "packaging", 32 | "description": "Update the ``chalice package`` command to support\npure lambda functions and scheduled events. (#772)", 33 | "type": "feature" 34 | }, 35 | { 36 | "category": "packaging", 37 | "description": "Fix packager edge case normalizing sdist names (#778)", 38 | "type": "bugfix" 39 | }, 40 | { 41 | "category": "packaging", 42 | "description": "Fix SQLAlchemy packaging (#778)", 43 | "type": "bugfix" 44 | }, 45 | { 46 | "category": "packaging", 47 | "description": "Fix packaging abi3, wheels this fixes cryptography 2.2.x packaging (#764)", 48 | "type": "bugfix" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /.changes/1.2.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Add CORS headers to error response (#715)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "local", 11 | "description": "Fix parsing empty query strings in local mode (#767)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "packaging", 16 | "description": "Fix regression in ``chalice package`` when using role arns (#793)", 17 | "type": "bugfix" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.2.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Fix package command not correctly setting environment variables (#795)", 7 | "type": "bugfix" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.2.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "dependency", 6 | "description": "Add support for pip 10 (#808)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "policy", 11 | "description": "Update ``policies.json`` file (#817)", 12 | "type": "enhancement" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.20.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Blueprints", 7 | "description": "Add `current_app` property to Blueprints (#1094)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "CLI", 12 | "description": "Set `AWS_CHALICE_CLI_MODE` env var whenever a Chalice CLI command is run (#1200)" 13 | }, 14 | { 15 | "type": "feature", 16 | "category": "Middleware", 17 | "description": "Add support for middleware (#1509)" 18 | }, 19 | { 20 | "type": "feature", 21 | "category": "X-Ray", 22 | "description": "Add support for AWS X-Ray (#464)" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.20.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Blueprints", 7 | "description": "Preserve docstring in blueprints (#1525)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Binary", 12 | "description": "Support returning native python types when using `*/*` for binary types (#1501)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.21.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Blueprints", 7 | "description": "Fix regression when invoking Lambda functions from blueprints (#1535)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "Events", 12 | "description": "Add support for Kinesis and DynamoDB event handlers (#987)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.21.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Websockets", 7 | "description": "Fix custom domain name configuration for websockets (#1531)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Local", 12 | "description": "Add support for multiple actions in builtin auth in local mode (#1527)" 13 | }, 14 | { 15 | "type": "bugfix", 16 | "category": "Websocket", 17 | "description": "Fix websocket client configuration when using a custom domain (#1503)" 18 | }, 19 | { 20 | "type": "bugfix", 21 | "category": "Local", 22 | "description": "Fix CORs handling in local mode (#761)" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.21.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Terraform", 7 | "description": "Fix issue with wildcard partition names in s3 event handlers (#1508)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Auth", 12 | "description": "Fix special case processing for root URL auth (#1271)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "Middleware", 17 | "description": "Add support for HTTP middleware catching exceptions (#1541)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.21.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Test", 7 | "description": "Add test client methods for generating sample kinesis events" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Config", 12 | "description": "Validate env var values are strings (#1543)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.21.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Local", 7 | "description": "Allow custom Chalice class in local mode (#1502)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Layers", 12 | "description": "Ensure single reference to managed layer (#1563)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.21.5.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Config", 7 | "description": "Fix config validation for env vars on py27 (#1573)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Pip", 12 | "description": "Bump pip version contraint (#1590)" 13 | }, 14 | { 15 | "type": "bugfix", 16 | "category": "REST", 17 | "description": "Add Allow header with list of allowed methods when returning 405 error (#1583)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.21.6.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Packaging", 7 | "description": "Increase upper bound for AWS provider in Terraform to 3.x (#1596)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Packaging", 12 | "description": "Add support for manylinux2014 wheels (#1551)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.21.7.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Terraform", 7 | "description": "Map custom domain outputs in Terraform packaging (#1601)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.21.8.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Authorizers", 7 | "description": "Add support for custom headers in built-in authorizers (#1613)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.21.9.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Dependencies", 7 | "description": "Bump attr version constraint (#1620)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.22.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "CDK", 7 | "description": "Add built-in support for the AWS CDK (#1622)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.22.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Pip", 7 | "description": "Bump pip version range to latest version 21.x (#1630)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "IAM", 12 | "description": "Improve client call collection when generation policies (#692)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.22.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Blueprint", 7 | "description": "Add log property to blueprint" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Pipeline", 12 | "description": "Fix build command in pipeline generation (#1653)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "Dependencies", 17 | "description": "Change enum-compat dependency to enum34 with version restrictions (#1667)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.22.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Terraform", 7 | "description": "Bump Terraform version to include 0.14" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Typing", 12 | "description": "Fix type definitions in app.pyi (#1676)" 13 | }, 14 | { 15 | "type": "bugfix", 16 | "category": "Terraform", 17 | "description": "Use references instead of function names in Terraform packaging (#1558)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.22.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Types", 7 | "description": "Add missing types to app.pyi stub file (#1701)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Custom Domain", 12 | "description": "Fix custom domain generation when using the CDK (#1640)" 13 | }, 14 | { 15 | "type": "bugfix", 16 | "category": "Packaging", 17 | "description": "Special cases pyrsistent packaging (#1696)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.23.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Deploy", 7 | "description": "Wait for function state to be active when deploying" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "SQS", 12 | "description": "Add queue_arn parameter to enable CDK integration with SQS event handler (#1681)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.24.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python2.7", 7 | "description": "Remove support for Python 2.7 (#1766)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Terraform", 12 | "description": "Update Terraform packaging to support version 1.0 (#1757)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "Typing", 17 | "description": "Add missing WebsocketEvent type information (#1746)" 18 | }, 19 | { 20 | "type": "enhancement", 21 | "category": "S3 events", 22 | "description": "Add source account to Lambda permissions when configuring S3 events (#1635)" 23 | }, 24 | { 25 | "type": "enhancement", 26 | "category": "Packaging", 27 | "description": "Add support for Terraform v0.15 (#1725)" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.24.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "GovCloud", 7 | "description": "Fix partition error when updating API Gateway in GovCloud region (#1770)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.24.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Dependencies", 7 | "description": "Bump attrs dependency to latest version (#1786)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Auth", 12 | "description": "Fix ARN parsing when generating a builtin AuthResponse (#1775)" 13 | }, 14 | { 15 | "type": "enhancement", 16 | "category": "CLI", 17 | "description": "Upgrade Click dependency to support v8.0.0 (#1729)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.25.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python", 7 | "description": "Add support for Python 3.9 (#1787)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.26.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Websockets", 7 | "description": "Add support for setting the Websocket protocol from the connect handler (#1768)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "SQS", 12 | "description": "Added MaximumBatchingWindowInSeconds to SQS event handler (#1778)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.26.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Dependencies", 7 | "description": "Bump pip dependency to latest released version (#1817)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Tests", 12 | "description": "Don't include tests package in .whl file (#1814)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.26.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Dependencies", 7 | "description": "Update pyyaml to 6.x (#1830)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "Websocket", 12 | "description": "Correctly configure websocket endpoint in the aws-cn partition (#1820)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.26.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Errors", 7 | "description": "Remove redundant error code in error message string (#1339)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "VPC", 12 | "description": "Associate VPC endpoint with Rest API (#1449)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.26.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Terraform", 7 | "description": "Use updated keywords for providing provider version constraints (#1717)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.26.5.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Terraform", 7 | "description": "Remove template provider in favor of locals (#1869)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Terraform", 12 | "description": "Bump Terraform version to suppose 1.1.x (#1868)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.26.6.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "pip", 7 | "description": "Fix RuntimeError with pip v22.x (#1887)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.27.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Local", 7 | "description": "Set a default timeout when creating the local LambdaContext instance (#1896)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "CDK", 12 | "description": "Add support for CDK v2 (#1742)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.27.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Pip", 7 | "description": "Bump pip version range to latest version <22.2 (#1924)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Websockets", 12 | "description": "Add support for WebSockets API Terraform packaging (#1670)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.27.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Terraform", 7 | "description": "Update aws provider constraint to allow versions 4.x (#1951)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "event-source", 12 | "description": "Add attribute for message attributes in SNSEvent and generated test events (#1934)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.27.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "bugfix", 6 | "category": "Versioning", 7 | "description": "Fix version string updates used in the release process (#1971)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.28.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Terraform", 7 | "description": "Update required terraform version to support 1.3 (#2014)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Pip", 12 | "description": "Bump pip version range to latest version <22.3 (#2016)" 13 | }, 14 | { 15 | "type": "feature", 16 | "category": "Config", 17 | "description": "Add support for `log_retention_in_days` (#943)" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.29.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python", 7 | "description": "Add support for Python 3.10 (#2037)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Pip", 12 | "description": "Bump pip version range to latest version <23.2 (#2034)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.3.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "config", 6 | "description": "Add support for Lambdas in a VPC (#413, #837, #673)", 7 | "type": "feature" 8 | }, 9 | { 10 | "category": "packaging", 11 | "description": "Add support for packaging local directories (#653)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "local", 16 | "description": "Add support for automatically reloading the local\ndev server when files are modified (#316, #846, #706)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "logging", 21 | "description": "Add support for viewing cloudwatch logs of all\nlambda functions (#841, #849)", 22 | "type": "enhancement" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.changes/1.30.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python", 7 | "description": "Add support for Python 3.11 (#2053)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Pip", 12 | "description": "Update version dependency on pip (#2080)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.31.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "1.0", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python", 7 | "description": "Add support for Python 3.12 (#2086)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "Python", 12 | "description": "Drop support for Python 3.7 (#2095)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.31.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "pip", 7 | "description": "Update pip version to allow 24.0 (#2092)" 8 | }, 9 | { 10 | "type": "bugfix", 11 | "category": "tar", 12 | "description": "Validate tar extraction does not escape destination dir (#1990)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.31.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "SQS", 7 | "description": "Add configuration option for MaximumConcurrency for SQS event source (#2104)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.31.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Pip", 7 | "description": "Update pip to the latest version (<24.4)" 8 | }, 9 | { 10 | "type": "enhancement", 11 | "category": "CLI", 12 | "description": "Remove distutils warning when packaging/deploying apps (#2123)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.31.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "type": "enhancement", 6 | "category": "Pip", 7 | "description": "Update pip to the latest version (<25.1)" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.32.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "type": "feature", 6 | "category": "Python", 7 | "description": "Add support for Python 3.13 (#2137)" 8 | }, 9 | { 10 | "type": "feature", 11 | "category": "Python", 12 | "description": "Drop support for Python 3.8 (#2138)" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.4.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CI-CD", 6 | "description": "Add support for generating python 3.6 pipelines (#858)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "event-source", 11 | "description": "Add support for connecting lambda functions to S3 events (#855)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "event-source", 16 | "description": "Add support for connecting lambda functions to SNS message (#488)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "local", 21 | "description": "Make ``watchdog`` an optional dependency and add a built in\n``stat()`` based file poller (#867)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "event-source", 26 | "description": "Add support for connecting lambda functions to an SQS queue (#884)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.5.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "policy", 6 | "description": "Add support for S3 upload_file/download_file in\npolicy generator (#889)", 7 | "type": "feature" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.6.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "CLI", 6 | "description": "Add ``chalice invoke`` command (#900)", 7 | "type": "feature" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/1.6.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "local", 6 | "description": "Fix local mode issue with unicode responses and Content-Length (#910)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "dev", 11 | "description": "Fix issue with ``requirements-dev.txt`` not setting up a working\ndev environment (#920)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "dependencies", 16 | "description": "Add support for pip 18 (#910)", 17 | "type": "enhancement" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.changes/1.6.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "dependencies", 6 | "description": "Add support for pip 18.2 (#991)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "logging", 11 | "description": "Add more detailed debug logs to the packager. (#934)", 12 | "type": "enhancement" 13 | }, 14 | { 15 | "category": "python", 16 | "description": "Add support for python3.7 (#992)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "rest-api", 21 | "description": "Support bytes for the application/json binary type (#988)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "rest-api", 26 | "description": "Use more compact JSON representation by default for dicts (#958)", 27 | "type": "enhancement" 28 | }, 29 | { 30 | "category": "logging", 31 | "description": "Log internal exceptions as errors (#254)", 32 | "type": "enhancement" 33 | }, 34 | { 35 | "category": "rest-api", 36 | "description": "Generate swagger documentation from docstrings (#574)", 37 | "type": "feature" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /.changes/1.7.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Fix packaging multiple local directories as dependencies (#1047)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "event-source", 11 | "description": "Add support for passing SNS ARNs to ``on_sns_message`` (#1048)", 12 | "type": "feature" 13 | }, 14 | { 15 | "category": "blueprint", 16 | "description": "Add support for Blueprints (#1023)", 17 | "type": "feature" 18 | }, 19 | { 20 | "category": "config", 21 | "description": "Add support for opting-in to experimental features (#1053)", 22 | "type": "feature" 23 | }, 24 | { 25 | "category": "event-source", 26 | "description": "Provide Lambda context in event object (#856)", 27 | "type": "feature" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.changes/1.8.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "packaging", 6 | "description": "Fall back to pure python version of yaml parser\nwhen unable to compile C bindings for PyYAML (#1074)", 7 | "type": "bugfix" 8 | }, 9 | { 10 | "category": "packaging", 11 | "description": "Add support for Lambda layers. (#1001)", 12 | "type": "feature" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.changes/1.9.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "dependencies", 6 | "description": "Update PIP to support up to 19.1.x (#1104)", 7 | "type": "enhancement" 8 | }, 9 | { 10 | "category": "rest-api", 11 | "description": "Fix handling of more complex Accept headers for binary\ncontent types (#1078)", 12 | "type": "bugfix" 13 | }, 14 | { 15 | "category": "rest-api", 16 | "description": "Raise TypeError when trying to serialize an unserializable\ntype (#1100)", 17 | "type": "enhancement" 18 | }, 19 | { 20 | "category": "policy", 21 | "description": "Update ``policies.json`` file (#1110)", 22 | "type": "enhancement" 23 | }, 24 | { 25 | "category": "rest-api", 26 | "description": "Support repeating values in the query string (#1131)", 27 | "type": "feature" 28 | }, 29 | { 30 | "category": "packaging", 31 | "description": "Add layer support to chalice package (#1130)", 32 | "type": "feature" 33 | }, 34 | { 35 | "category": "rest-api", 36 | "description": "Fix bug with route ``name`` kwarg raising a ``TypeError`` (#1112)", 37 | "type": "bugfix" 38 | }, 39 | { 40 | "category": "logging", 41 | "description": "Change exceptions to always be logged at the ERROR level (#969)", 42 | "type": "enhancement" 43 | }, 44 | { 45 | "category": "CLI", 46 | "description": "Fix bug handling exceptions during ``chalice invoke`` on\nPython 3.7 (#1139)", 47 | "type": "bugfix" 48 | }, 49 | { 50 | "category": "rest-api", 51 | "description": "Add support for API Gateway compression (#672)", 52 | "type": "bugfix" 53 | }, 54 | { 55 | "category": "packaging", 56 | "description": "Add support for both relative and absolute paths for\n``--package-dir`` (#940)", 57 | "type": "enhancement" 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /.changes/1.9.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema-version": "0.2", 3 | "changes": [ 4 | { 5 | "category": "rest-api", 6 | "description": "Make MultiDict mutable (#1158)", 7 | "type": "enhancement" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.changes/templates/changelog: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | {% for release, changes in releases %} 4 | ## {{ release }} 5 | {% if changes.summary %} 6 | {{ changes.summary -}} 7 | {% endif %} 8 | {% for change in changes.changes %} 9 | * {{ change.type }}:{{ change.category }}:{{ change.description -}} 10 | {% endfor %} 11 | {% endfor %} 12 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | [report] 4 | exclude_lines = 5 | raise NotImplementedError.* 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: pip 4 | directory: "/." 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 10 9 | allow: 10 | - dependency-name: pip 11 | - dependency-name: click 12 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: Run PR Checks 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - "feature/**" 7 | pull_request: 8 | branches: 9 | - master 10 | - "feature/**" 11 | jobs: 12 | prcheck: 13 | runs-on: ${{ matrix.os }} 14 | env: 15 | HYPOTHESIS_PROFILE: ci 16 | CHALICE_TEST_EXTENDED_PACKAGING: true 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest, macos-latest] 20 | python-version: [3.9, '3.10', 3.11, 3.12, 3.13] 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: actions/setup-python@v2 24 | name: Set up Python ${{ matrix.python-version }} 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Install dependencies 28 | run: | 29 | make install-dev-deps 30 | - name: Run PRCheck 31 | run: make prcheck 32 | cdktests: 33 | runs-on: ubuntu-latest 34 | strategy: 35 | matrix: 36 | python-version: [3.9, '3.10', 3.11, 3.12, 3.13] 37 | steps: 38 | - uses: actions/checkout@v2 39 | - uses: actions/setup-node@v2 40 | with: 41 | node-version: '14' 42 | - uses: actions/setup-python@v2 43 | name: Set up Python ${{ matrix.python-version }} 44 | with: 45 | python-version: ${{ matrix.python-version }} 46 | - name: Install CDK 47 | run: npm install -g aws-cdk 48 | - name: Install dependencies 49 | run: | 50 | pip install -r requirements-test.txt --upgrade --upgrade-strategy eager -e .[cdkv2] 51 | - name: Run CDK tests 52 | run: python -m pytest tests/functional/cdk 53 | # Chalice works on windows, but there's some differences between 54 | # the GitHub actions windows environment and our windows dev 55 | # laptops that are causing certain tests to fail. Once these 56 | # are fixed we can also test on windows but for now we have to 57 | # disable these. 58 | # tests-windows: 59 | # runs-on: windows-latest 60 | # strategy: 61 | # matrix: 62 | # # In windows where you have to explicitly install 63 | # # python, it's unlikely users are going to install 64 | # # python 2.7 which is no longer supported so we're 65 | # # only testing python3 on windows. 66 | # python-version: [3.6, 3.7, 3.8, 3.9] 67 | # steps: 68 | # - uses: actions/checkout@v2 69 | # - uses: actions/setup-python@v2 70 | # name: Set up Python ${{ matrix.python-version }} 71 | # with: 72 | # python-version: ${{ matrix.python-version }} 73 | # - name: Install dependencies 74 | # run: | 75 | # pip install -r requirements-dev.txt 76 | # pip install -e . 77 | # - name: Run PRCheck 78 | # run: python -m pytest tests/unit tests/functional tests/integration 79 | -------------------------------------------------------------------------------- /.github/workflows/stale-issue.yml: -------------------------------------------------------------------------------- 1 | name: "Close stale issues" 2 | 3 | on: 4 | schedule: 5 | - cron: "*/60 * * * *" 6 | 7 | jobs: 8 | cleanup: 9 | runs-on: ubuntu-latest 10 | name: Stale issue job 11 | steps: 12 | - uses: aws-actions/stale-issue-cleanup@v4 13 | with: 14 | issue-types: issues 15 | ancient-issue-message: "" 16 | stale-issue-message: > 17 | Greetings! It looks like this issue hasn’t been active in longer than 18 | five days. We encourage you to check if this is still an issue in the latest 19 | release. In the absence of more information, we will be closing this issue 20 | soon. If you find that this is still a problem, please feel free to provide a 21 | comment or upvote with a reaction on the initial post to prevent automatic 22 | closure. If the issue is already closed, please feel free to open a new one. 23 | 24 | # These labels are required 25 | stale-issue-label: closing-soon 26 | exempt-issue-labels: bug, feature-request 27 | response-requested-label: response-requested 28 | 29 | # Don't set closed-for-staleness label to skip closing very old issues 30 | # regardless of label 31 | closed-for-staleness-label: closed-for-staleness 32 | 33 | # Issue timing 34 | days-before-stale: 10 35 | days-before-close: 4 36 | days-before-ancient: 2190 37 | 38 | # If you don't want to mark a issue as being ancient based on a 39 | # threshold of "upvotes", you can set this here. An "upvote" is 40 | # the total number of +1, heart, hooray, and rocket reactions 41 | # on an issue. 42 | minimum-upvotes-to-exempt: 2 43 | 44 | repo-token: ${{ secrets.GITHUB_TOKEN }} 45 | loglevel: DEBUG 46 | # Set dry-run to true to not perform label or close actions. 47 | dry-run: false 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | sample/ 2 | .cache 3 | venv 4 | docs/build/ 5 | .idea 6 | __pycache__/ 7 | .coverage 8 | chalice.egg-info/ 9 | .hypothesis/ 10 | .pytest_cache/ 11 | .mypy_cache/ 12 | *.pyc 13 | .vscode 14 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.7 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Code of Conduct 3 | =============== 4 | 5 | 6 | This project has adopted the 7 | `Amazon Open Source Code of Conduct `__. 8 | For more information see the 9 | `Code of Conduct FAQ `__ 10 | or contact opensource-codeofconduct@amazon.com with any additional 11 | questions or comments. 12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include CONTRIBUTING.rst 2 | include CHANGELOG.md 3 | include LICENSE 4 | include NOTICE 5 | include README.rst 6 | recursive-include chalice *.json 7 | 8 | recursive-exclude * __pycache__ 9 | recursive-exclude * *.py[co] 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Eventually I'll add: 2 | # py.test --cov chalice --cov-report term-missing --cov-fail-under 95 tests/ 3 | # which will fail if tests are under 95% 4 | TESTS=tests/unit tests/functional tests/integration 5 | 6 | check: 7 | ###### FLAKE8 ##### 8 | # No unused imports, no undefined vars, 9 | flake8 --ignore=E731,W503,W504 --exclude chalice/__init__.py,chalice/compat.py,chalice/vendored/botocore/regions.py --max-complexity 10 chalice/ 10 | flake8 --ignore=E731,W503,W504,F401 --max-complexity 10 chalice/compat.py 11 | flake8 tests/unit/ tests/functional/ tests/integration tests/aws 12 | # 13 | # Proper docstring conventions according to pep257 14 | # 15 | # 16 | pydocstyle --add-ignore=D100,D101,D102,D103,D104,D105,D107,D204,D301 --match='(?!(test_|regions)).*\.py' chalice/ 17 | 18 | pylint: 19 | ###### PYLINT ###### 20 | pylint --rcfile .pylintrc chalice 21 | # Run our custom linter on test code. 22 | pylint --disable=I,E,W,R,C,F --enable C9999,C9998 tests/ 23 | 24 | test: 25 | py.test -v $(TESTS) 26 | 27 | typecheck: 28 | mypy --ignore-missing-imports --follow-imports=skip -p chalice --disallow-untyped-defs --strict-optional --warn-no-return 29 | 30 | coverage: 31 | py.test --cov chalice --cov-report term-missing $(TESTS) 32 | 33 | coverage-unit: 34 | py.test --cov chalice --cov-report term-missing tests/unit 35 | 36 | htmlcov: 37 | py.test --cov chalice --cov-report html $(TESTS) 38 | rm -rf /tmp/htmlcov && mv htmlcov /tmp/ 39 | open /tmp/htmlcov/index.html 40 | 41 | doccheck: 42 | ##### DOC8 ###### 43 | # Correct rst formatting for documentation 44 | # 45 | # TODO: Remove doc8 46 | ## 47 | doc8 docs/source --ignore-path docs/source/topics/multifile.rst 48 | # 49 | # 50 | # Verify we have no broken external links 51 | # as well as no undefined internal references. 52 | $(MAKE) -C docs linkcheck 53 | # Verify we can build the docs. The 54 | # treat warnings as errors flag is enabled 55 | # so any sphinx-build warnings will fail the build. 56 | $(MAKE) -C docs html 57 | 58 | prcheck: check pylint coverage doccheck typecheck 59 | 60 | install-dev-deps: 61 | pip install -r requirements-dev.txt --upgrade --upgrade-strategy eager -e . 62 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | chalice 2 | Copyright 2015 James Saryerwinnie. All Rights Reserved. 3 | -------------------------------------------------------------------------------- /chalice/__init__.py: -------------------------------------------------------------------------------- 1 | from chalice.app import Chalice, Blueprint 2 | from chalice.app import ( 3 | ChaliceViewError, BadRequestError, UnauthorizedError, ForbiddenError, 4 | NotFoundError, ConflictError, TooManyRequestsError, Response, CORSConfig, 5 | CustomAuthorizer, CognitoUserPoolAuthorizer, IAMAuthorizer, 6 | UnprocessableEntityError, WebsocketDisconnectedError, 7 | AuthResponse, AuthRoute, Cron, Rate, __version__ as chalice_version, 8 | ConvertToMiddleware, ChaliceUnhandledError 9 | ) 10 | # We're reassigning version here to keep mypy happy. 11 | __version__ = chalice_version 12 | -------------------------------------------------------------------------------- /chalice/api/__init__.py: -------------------------------------------------------------------------------- 1 | """Control plane APIs for programatically building/deploying Chalice apps. 2 | 3 | The eventual goal is to expose this as a public API that other tools can use 4 | in their own integrations with Chalice, but this will need time for the APIs 5 | to mature so for the time being this is an internal-only API. 6 | """ 7 | import os 8 | from typing import Optional, Dict, Any 9 | from chalice.cli.factory import CLIFactory 10 | 11 | 12 | def package_app(project_dir: str, 13 | output_dir: str, 14 | stage: str, 15 | chalice_config: Optional[Dict[str, Any]] = None, 16 | package_format: str = 'cloudformation', 17 | template_format: str = 'json') -> None: 18 | factory = CLIFactory(project_dir, environ=os.environ) 19 | if chalice_config is None: 20 | chalice_config = {} 21 | config = factory.create_config_obj( 22 | stage, user_provided_params=chalice_config) 23 | options = factory.create_package_options() 24 | packager = factory.create_app_packager(config, options, 25 | package_format=package_format, 26 | template_format=template_format) 27 | packager.package_app(config, output_dir, stage) 28 | -------------------------------------------------------------------------------- /chalice/cdk/__init__.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | try: 3 | from chalice.cdk.construct import Chalice 4 | except ImportError: 5 | warnings.warn('Unable to import the Chalice CDK construct due to missing ' 6 | 'dependencies.\nYou can install these by running ' 7 | "'pip install \"chalice[cdk]\"'") 8 | 9 | 10 | __all__ = ['Chalice'] 11 | -------------------------------------------------------------------------------- /chalice/cli/filewatch/__init__.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from typing import Callable, Optional, Type # noqa 4 | from chalice.local import HTTPServerThread # noqa 5 | 6 | 7 | RESTART_REQUEST_RC = 3 8 | 9 | 10 | class FileWatcher(object): 11 | """Base class for watching files for changes.""" 12 | 13 | def watch_for_file_changes(self, root_dir, callback): 14 | # type: (str, Callable[[], None]) -> None 15 | """Recursively watch directory for changes. 16 | 17 | When a changed file is detected, the provided callback 18 | is immediately invoked and the current scan stops. 19 | 20 | """ 21 | raise NotImplementedError("watch_for_file_changes") 22 | 23 | 24 | class WorkerProcess(object): 25 | """Worker that runs the chalice dev server.""" 26 | def __init__(self, http_thread): 27 | # type: (HTTPServerThread) -> None 28 | self._http_thread = http_thread 29 | self._restart_event = threading.Event() 30 | 31 | def main(self, project_dir, timeout=None): 32 | # type: (str, Optional[int]) -> int 33 | self._http_thread.start() 34 | self._start_file_watcher(project_dir) 35 | if self._restart_event.wait(timeout): 36 | self._http_thread.shutdown() 37 | return RESTART_REQUEST_RC 38 | return 0 39 | 40 | def _start_file_watcher(self, project_dir): 41 | # type: (str) -> None 42 | raise NotImplementedError("_start_file_watcher") 43 | -------------------------------------------------------------------------------- /chalice/cli/filewatch/eventbased.py: -------------------------------------------------------------------------------- 1 | import threading # noqa 2 | 3 | from typing import Callable, Optional # noqa 4 | import watchdog.observers # pylint: disable=import-error 5 | from watchdog import events # pylint: disable=import-error 6 | 7 | from chalice.cli.filewatch import FileWatcher, WorkerProcess 8 | 9 | 10 | class WatchdogWorkerProcess(WorkerProcess): 11 | """Worker that runs the chalice dev server.""" 12 | 13 | def _start_file_watcher(self, project_dir): 14 | # type: (str) -> None 15 | restart_callback = WatchdogRestarter(self._restart_event) 16 | watcher = WatchdogFileWatcher() 17 | watcher.watch_for_file_changes( 18 | project_dir, restart_callback) 19 | 20 | 21 | class WatchdogFileWatcher(FileWatcher): 22 | def watch_for_file_changes(self, root_dir, callback): 23 | # type: (str, Callable[[], None]) -> None 24 | observer = watchdog.observers.Observer() 25 | observer.schedule(callback, root_dir, recursive=True) 26 | observer.start() 27 | 28 | 29 | class WatchdogRestarter(events.FileSystemEventHandler): 30 | 31 | def __init__(self, restart_event): 32 | # type: (threading.Event) -> None 33 | # The reason we're using threading 34 | self.restart_event = restart_event 35 | 36 | def on_any_event(self, event): 37 | # type: (events.FileSystemEvent) -> None 38 | # If we modify a file we'll get a FileModifiedEvent 39 | # as well as a DirectoryModifiedEvent. 40 | # We only care about reloading is a file is modified. 41 | if event.is_directory: 42 | return 43 | self() 44 | 45 | def __call__(self): 46 | # type: () -> None 47 | self.restart_event.set() 48 | -------------------------------------------------------------------------------- /chalice/cli/filewatch/stat.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import threading 3 | import time 4 | 5 | from typing import Callable, Dict, Optional, Iterator # noqa 6 | 7 | from chalice.cli.filewatch import FileWatcher, WorkerProcess 8 | from chalice.utils import OSUtils 9 | 10 | 11 | LOGGER = logging.getLogger(__name__) 12 | 13 | 14 | class StatWorkerProcess(WorkerProcess): 15 | def _start_file_watcher(self, project_dir): 16 | # type: (str) -> None 17 | watcher = StatFileWatcher() 18 | watcher.watch_for_file_changes(project_dir, self._on_file_change) 19 | 20 | def _on_file_change(self): 21 | # type: () -> None 22 | self._restart_event.set() 23 | 24 | 25 | class StatFileWatcher(FileWatcher): 26 | POLL_INTERVAL = 1 27 | 28 | def __init__(self, osutils=None): 29 | # type: (Optional[OSUtils]) -> None 30 | self._mtime_cache = {} # type: Dict[str, float] 31 | self._shutdown_event = threading.Event() 32 | self._thread = None # type: Optional[threading.Thread] 33 | if osutils is None: 34 | osutils = OSUtils() 35 | self._osutils = osutils 36 | 37 | def watch_for_file_changes(self, root_dir, callback): 38 | # type: (str, Callable[[], None]) -> None 39 | t = threading.Thread(target=self.poll_for_changes_until_shutdown, 40 | args=(root_dir, callback)) 41 | t.daemon = True 42 | t.start() 43 | self._thread = t 44 | LOGGER.debug("Stat file watching: %s, with callback: %s", 45 | root_dir, callback) 46 | 47 | def poll_for_changes_until_shutdown(self, root_dir, callback): 48 | # type: (str, Callable[[], None]) -> None 49 | self._seed_mtime_cache(root_dir) 50 | while not self._shutdown_event.is_set(): 51 | self._single_pass_poll(root_dir, callback) 52 | time.sleep(self.POLL_INTERVAL) 53 | 54 | def _seed_mtime_cache(self, root_dir): 55 | # type: (str) -> None 56 | for rootdir, _, filenames in self._osutils.walk(root_dir): 57 | for filename in filenames: 58 | path = self._osutils.joinpath(rootdir, filename) 59 | self._mtime_cache[path] = self._osutils.mtime(path) 60 | 61 | def _single_pass_poll(self, root_dir, callback): 62 | # type: (str, Callable[[], None]) -> None 63 | new_mtimes = {} # type: Dict[str, float] 64 | for path in self._recursive_walk_files(root_dir): 65 | if self._is_changed_file(path, new_mtimes): 66 | callback() 67 | return 68 | if new_mtimes != self._mtime_cache: 69 | # Files were removed. 70 | LOGGER.debug("Files removed, triggering restart.") 71 | self._mtime_cache = new_mtimes 72 | callback() 73 | return 74 | 75 | def _is_changed_file(self, path, new_mtimes): 76 | # type: (str, Dict[str, float]) -> bool 77 | last_mtime = self._mtime_cache.get(path) 78 | if last_mtime is None: 79 | LOGGER.debug("File added: %s, triggering restart.", path) 80 | return True 81 | try: 82 | new_mtime = self._osutils.mtime(path) 83 | if new_mtime > last_mtime: 84 | LOGGER.debug("File updated: %s, triggering restart.", path) 85 | return True 86 | new_mtimes[path] = new_mtime 87 | return False 88 | except (OSError, IOError): 89 | return False 90 | 91 | def _recursive_walk_files(self, root_dir): 92 | # type: (str) -> Iterator[str] 93 | for rootdir, _, filenames in self._osutils.walk(root_dir): 94 | for filename in filenames: 95 | path = self._osutils.joinpath(rootdir, filename) 96 | yield path 97 | -------------------------------------------------------------------------------- /chalice/deploy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/deploy/__init__.py -------------------------------------------------------------------------------- /chalice/policies-extra.json: -------------------------------------------------------------------------------- 1 | { 2 | "s3": { 3 | "upload_file": ["s3:PutObject", "s3:AbortMultipartUpload"], 4 | "upload_fileobj": ["s3:PutObject", "s3: AbortMultipartUpload"], 5 | "download_file": ["s3:GetObject"], 6 | "download_fileobj": ["s3:GetObject"], 7 | "copy": ["s3:PutObject", "s3:AbortMultipartUpload"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chalice/py.typed: -------------------------------------------------------------------------------- 1 | # Marker file for PEP 561. This package provides inline type annotations. 2 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "{{app_name}}", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/app.py: -------------------------------------------------------------------------------- 1 | from chalice import Chalice 2 | 3 | app = Chalice(app_name='{{app_name}}') 4 | 5 | 6 | @app.route('/') 7 | def index(): 8 | return {'hello': 'world'} 9 | 10 | 11 | # The view function above will return {"hello": "world"} 12 | # whenever you make an HTTP GET request to '/'. 13 | # 14 | # Here are a few more examples: 15 | # 16 | # @app.route('/hello/{name}') 17 | # def hello_name(name): 18 | # # '/hello/james' -> {"hello": "james"} 19 | # return {'hello': name} 20 | # 21 | # @app.route('/users', methods=['POST']) 22 | # def create_user(): 23 | # # This is the JSON body the user sent in their POST request. 24 | # user_as_json = app.current_request.json_body 25 | # # We'll echo the json body back to the user in a 'user' key. 26 | # return {'user': user_as_json} 27 | # 28 | # See the README documentation for more examples. 29 | # 30 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/chalicelib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0000-rest-api/chalicelib/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/metadata.json: -------------------------------------------------------------------------------- 1 | {"description": "REST API"} 2 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | chalice=={{chalice_version}} 2 | pytest 3 | -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0000-rest-api/requirements.txt -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0000-rest-api/tests/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0000-rest-api/tests/test_app.py: -------------------------------------------------------------------------------- 1 | from chalice.test import Client 2 | from app import app 3 | 4 | 5 | def test_index(): 6 | with Client(app) as client: 7 | response = client.http.get('/') 8 | assert response.json_body == {'hello': 'world'} 9 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "{{app_name}}", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from chalice import Chalice 4 | 5 | app = Chalice(app_name='{{app_name}}') 6 | app.debug = True 7 | 8 | 9 | # Set the value of APP_BUCKET_NAME in the .chalice/config.json file. 10 | S3_BUCKET = os.environ.get('APP_BUCKET_NAME', '') 11 | 12 | 13 | @app.on_s3_event(bucket=S3_BUCKET, events=['s3:ObjectCreated:*']) 14 | def s3_handler(event): 15 | app.log.debug("Received event for bucket: %s, key: %s", 16 | event.bucket, event.key) 17 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/chalicelib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0002-s3-event-handler/chalicelib/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/metadata.json: -------------------------------------------------------------------------------- 1 | {"description": "S3 Event Handler"} 2 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | chalice 2 | pytest 3 | -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0002-s3-event-handler/requirements.txt -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0002-s3-event-handler/tests/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0002-s3-event-handler/tests/test_app.py: -------------------------------------------------------------------------------- 1 | from chalice.test import Client 2 | from app import app 3 | 4 | 5 | def test_s3_handler(): 6 | with Client(app) as client: 7 | event = client.events.generate_s3_event( 8 | bucket='mybucket', key='mykey') 9 | client.lambda_.invoke('s3_handler', event) 10 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "{{app_name}}", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/app.py: -------------------------------------------------------------------------------- 1 | from chalice import Chalice 2 | 3 | app = Chalice(app_name='{{app_name}}') 4 | 5 | 6 | @app.lambda_function() 7 | def first_function(event, context): 8 | return {'hello': 'world'} 9 | 10 | 11 | @app.lambda_function() 12 | def second_function(event, context): 13 | return {'hello': 'world2'} 14 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/chalicelib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0007-lambda-only/chalicelib/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/metadata.json: -------------------------------------------------------------------------------- 1 | {"description": "Lambda Functions only"} 2 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | chalice 2 | pytest 3 | -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0007-lambda-only/requirements.txt -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0007-lambda-only/tests/__init__.py -------------------------------------------------------------------------------- /chalice/templates/0007-lambda-only/tests/test_app.py: -------------------------------------------------------------------------------- 1 | from chalice.test import Client 2 | from app import app 3 | 4 | 5 | def test_index(): 6 | with Client(app) as client: 7 | response = client.lambda_.invoke('first_function', {}) 8 | assert response.payload == {'hello': 'world'} 9 | -------------------------------------------------------------------------------- /chalice/templates/0009-legacy/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "{{app_name}}", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chalice/templates/0009-legacy/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /chalice/templates/0009-legacy/app.py: -------------------------------------------------------------------------------- 1 | from chalice import Chalice 2 | 3 | app = Chalice(app_name='{{app_name}}') 4 | 5 | 6 | @app.route('/') 7 | def index(): 8 | return {'hello': 'world'} 9 | 10 | 11 | # The view function above will return {"hello": "world"} 12 | # whenever you make an HTTP GET request to '/'. 13 | # 14 | # Here are a few more examples: 15 | # 16 | # @app.route('/hello/{name}') 17 | # def hello_name(name): 18 | # # '/hello/james' -> {"hello": "james"} 19 | # return {'hello': name} 20 | # 21 | # @app.route('/users', methods=['POST']) 22 | # def create_user(): 23 | # # This is the JSON body the user sent in their POST request. 24 | # user_as_json = app.current_request.json_body 25 | # # We'll echo the json body back to the user in a 'user' key. 26 | # return {'user': user_as_json} 27 | # 28 | # See the README documentation for more examples. 29 | # 30 | -------------------------------------------------------------------------------- /chalice/templates/0009-legacy/metadata.json: -------------------------------------------------------------------------------- 1 | {"description": "Legacy REST API Template"} 2 | -------------------------------------------------------------------------------- /chalice/templates/0009-legacy/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/0009-legacy/requirements.txt -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/README.rst: -------------------------------------------------------------------------------- 1 | REST API backed by Amazon DynamoDB 2 | ================================== 3 | 4 | This template provides a REST API that's backed by an Amazon DynamoDB table. 5 | This application is deployed using the AWS CDK. 6 | 7 | For more information, see the `Deploying with the AWS CDK 8 | `__ tutorial. 9 | 10 | 11 | Quickstart 12 | ---------- 13 | 14 | First, you'll need to install the AWS CDK if you haven't already. 15 | The CDK requires Node.js and npm to run. 16 | See the `Getting started with the AWS CDK 17 | `__ for 18 | more details. 19 | 20 | :: 21 | 22 | $ npm install -g aws-cdk 23 | 24 | Next you'll need to install the requirements for the project. 25 | 26 | :: 27 | 28 | $ pip install -r requirements.txt 29 | 30 | There's also separate requirements files in the ``infrastructure`` 31 | and ``runtime`` directories if you'd prefer to have separate virtual 32 | environments for your CDK and Chalice app. 33 | 34 | To deploy the application, ``cd`` to the ``infrastructure`` directory. 35 | If this is you're first time using the CDK you'll need to bootstrap 36 | your environment. 37 | 38 | :: 39 | 40 | $ cdk bootstrap 41 | 42 | Then you can deploy your application using the CDK. 43 | 44 | :: 45 | 46 | $ cdk deploy 47 | 48 | 49 | Project layout 50 | -------------- 51 | 52 | This project template combines a CDK application and a Chalice application. 53 | These correspond to the ``infrastructure`` and ``runtime`` directory 54 | respectively. To run any CDK CLI commands, ensure you're in the 55 | ``infrastructure`` directory, and to run any Chalice CLI commands ensure 56 | you're in the ``runtime`` directory. 57 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/infrastructure/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | try: 3 | from aws_cdk import core as cdk 4 | except ImportError: 5 | import aws_cdk as cdk 6 | from stacks.chaliceapp import ChaliceApp 7 | 8 | app = cdk.App() 9 | ChaliceApp(app, '{{app_name}}') 10 | 11 | app.synth() 12 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/infrastructure/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "context": { 4 | "aws-cdk:enableDiffNoFail": "true", 5 | "@aws-cdk/core:stackRelativeExports": "true" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/infrastructure/requirements.txt: -------------------------------------------------------------------------------- 1 | aws-cdk-lib>2.0,<3.0 2 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/infrastructure/stacks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/templates/6001-cdk-ddb/infrastructure/stacks/__init__.py -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/infrastructure/stacks/chaliceapp.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from aws_cdk import aws_dynamodb as dynamodb 4 | 5 | try: 6 | from aws_cdk import core as cdk 7 | except ImportError: 8 | import aws_cdk as cdk 9 | 10 | from chalice.cdk import Chalice 11 | 12 | 13 | RUNTIME_SOURCE_DIR = os.path.join( 14 | os.path.dirname(os.path.dirname(__file__)), os.pardir, 'runtime') 15 | 16 | 17 | class ChaliceApp(cdk.Stack): 18 | 19 | def __init__(self, scope, id, **kwargs): 20 | super().__init__(scope, id, **kwargs) 21 | self.dynamodb_table = self._create_ddb_table() 22 | self.chalice = Chalice( 23 | self, 'ChaliceApp', source_dir=RUNTIME_SOURCE_DIR, 24 | stage_config={ 25 | 'environment_variables': { 26 | 'APP_TABLE_NAME': self.dynamodb_table.table_name 27 | } 28 | } 29 | ) 30 | self.dynamodb_table.grant_read_write_data( 31 | self.chalice.get_role('DefaultRole') 32 | ) 33 | 34 | def _create_ddb_table(self): 35 | dynamodb_table = dynamodb.Table( 36 | self, 'AppTable', 37 | partition_key=dynamodb.Attribute( 38 | name='PK', type=dynamodb.AttributeType.STRING), 39 | sort_key=dynamodb.Attribute( 40 | name='SK', type=dynamodb.AttributeType.STRING 41 | ), 42 | removal_policy=cdk.RemovalPolicy.DESTROY) 43 | cdk.CfnOutput(self, 'AppTableName', 44 | value=dynamodb_table.table_name) 45 | return dynamodb_table 46 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/metadata.json: -------------------------------------------------------------------------------- 1 | {"description": "[CDK] Rest API with a DynamoDB table"} 2 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/requirements.txt: -------------------------------------------------------------------------------- 1 | -r infrastructure/requirements.txt 2 | -r runtime/requirements.txt 3 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/runtime/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "{{app_name}}", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api", 7 | "lambda_functions": { 8 | "api_handler": { 9 | "environment_variables": { 10 | "APP_TABLE_NAME": "" 11 | } 12 | } 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/runtime/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import boto3 3 | from chalice import Chalice 4 | 5 | 6 | app = Chalice(app_name='{{app_name}}') 7 | dynamodb = boto3.resource('dynamodb') 8 | dynamodb_table = dynamodb.Table(os.environ.get('APP_TABLE_NAME', '')) 9 | 10 | 11 | @app.route('/users', methods=['POST']) 12 | def create_user(): 13 | request = app.current_request.json_body 14 | item = { 15 | 'PK': 'User#%s' % request['username'], 16 | 'SK': 'Profile#%s' % request['username'], 17 | } 18 | item.update(request) 19 | dynamodb_table.put_item(Item=item) 20 | return {} 21 | 22 | 23 | @app.route('/users/{username}', methods=['GET']) 24 | def get_user(username): 25 | key = { 26 | 'PK': 'User#%s' % username, 27 | 'SK': 'Profile#%s' % username, 28 | } 29 | item = dynamodb_table.get_item(Key=key)['Item'] 30 | del item['PK'] 31 | del item['SK'] 32 | return item 33 | -------------------------------------------------------------------------------- /chalice/templates/6001-cdk-ddb/runtime/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3<2.0.0 2 | -------------------------------------------------------------------------------- /chalice/vendored/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/vendored/__init__.py -------------------------------------------------------------------------------- /chalice/vendored/botocore/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/chalice/vendored/botocore/__init__.py -------------------------------------------------------------------------------- /docs/source/_static/custom.css: -------------------------------------------------------------------------------- 1 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 200%; } 2 | 3 | div.highlight-python { 4 | border-width: 0 0 0 2px; 5 | border-style: solid; 6 | border-color: #84ad98; 7 | } 8 | 9 | div.highlight-default { 10 | border-width: 0 0 0 2px; 11 | border-style: solid; 12 | border-color: #a9a9a9; 13 | } 14 | 15 | a.reference { 16 | border-bottom: 0.5px dotted #faa; 17 | } 18 | -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBold-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-ExtraBoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-Semibold-webfont.woff -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/_static/fonts/open-sans/fonts/OpenSans-SemiboldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {%- extends "!layout.html" %} 2 | 3 | {%- block extrahead %} 4 | 5 | 6 | {{ super() }} 7 | {% endblock %} 8 | 9 | -------------------------------------------------------------------------------- /docs/source/faq.rst: -------------------------------------------------------------------------------- 1 | Frequently Asked Questions 2 | ========================== 3 | 4 | **Q: What is AWS Chalice?** 5 | 6 | AWS Chalice is a framework for writing serverless apps in python. 7 | It consists of a CLI, a declarative python API for connecting 8 | events to AWS Lambda functions, and a runtime component that 9 | provides APIs accessible to your Lambda functions. 10 | 11 | **Q: Why should I use AWS Chalice?** 12 | 13 | Chalice is designed for a seamless getting started experience 14 | that can get you up and running quickly. It handles all the 15 | boilerplate and low level details of creating a serverless 16 | application, allowing you to focus on the business logic 17 | of your application. It also provides deep integration with 18 | various AWS services allowing you to take advantage of the 19 | features available in each service. 20 | 21 | **Q: How does Chalice compare to AWS SAM and the AWS CDK?** 22 | 23 | Chalice is designed to work together with AWS SAM. 24 | SAM focus on provisioning the resources needed 25 | for your application, and not necessarily on the application code 26 | itself. Chalice provides a set of APIs to help you write your 27 | application code, including a routing layer for REST and Websocket 28 | APIs, and decorators to connect various AWS event sources to 29 | Lambda functions. It then can integrate with AWS SAM by offloading 30 | the deployment to AWS CloudFormation. 31 | 32 | **Q: How does Chalice compare to other similiar frameworks?** 33 | 34 | The biggest difference between Chalice and other frameworks is that Chalice 35 | is focused on using a familiar, decorator-based API to write serverless 36 | python applications that run on AWS Lambda. Its goal is to make writing and 37 | deploying these types of applications as simple as possible specifically for 38 | Python developers. It was designed from the ground up to run in a 39 | serverless environment. 40 | 41 | To achieve this goal, it has to make certain tradeoffs. Chalice makes 42 | assumptions about how applications will be deployed, and it has restrictions on 43 | how an application can be structured. The feature set is purposefully small. 44 | -------------------------------------------------------------------------------- /docs/source/img/auto-layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/img/auto-layer.png -------------------------------------------------------------------------------- /docs/source/img/chalice-logo-icon-whitespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/img/chalice-logo-icon-whitespace.png -------------------------------------------------------------------------------- /docs/source/img/chalice-logo-whitespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/img/chalice-logo-whitespace.png -------------------------------------------------------------------------------- /docs/source/img/no-auto-layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/img/no-auto-layer.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Documentation 2 | ============= 3 | 4 | 5 | Getting Started 6 | --------------- 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | quickstart 12 | 13 | 14 | Tutorials 15 | --------- 16 | 17 | .. toctree:: 18 | :maxdepth: 2 19 | 20 | tutorials/index 21 | 22 | 23 | Topics 24 | ------ 25 | 26 | .. toctree:: 27 | :maxdepth: 2 28 | 29 | topics/index 30 | 31 | 32 | API Reference 33 | ------------- 34 | 35 | .. toctree:: 36 | :maxdepth: 2 37 | 38 | api 39 | 40 | 41 | Sample Apps 42 | ----------- 43 | 44 | .. toctree:: 45 | :maxdepth: 2 46 | 47 | samples/index 48 | 49 | 50 | Upgrade Notes 51 | ------------- 52 | 53 | .. toctree:: 54 | :maxdepth: 2 55 | 56 | upgrading 57 | 58 | 59 | FAQ 60 | --- 61 | 62 | .. toctree:: 63 | :maxdepth: 1 64 | 65 | faq 66 | 67 | 68 | Indices and tables 69 | ================== 70 | 71 | * :ref:`genindex` 72 | * :ref:`search` 73 | -------------------------------------------------------------------------------- /docs/source/main.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. include:: ./index.rst 4 | -------------------------------------------------------------------------------- /docs/source/quickstart.rst: -------------------------------------------------------------------------------- 1 | Quickstart 2 | ========== 3 | 4 | .. include:: ../../README.rst 5 | :start-after: quick-start-begin 6 | :end-before: quick-start-end 7 | 8 | Cleaning Up 9 | ----------- 10 | 11 | If you're done experimenting with Chalice and you'd like to cleanup, you can 12 | use the ``chalice delete`` command, and Chalice will delete all the resources 13 | it created when running the ``chalice deploy`` command. 14 | 15 | :: 16 | 17 | $ chalice delete 18 | Deleting Rest API: abcd4kwyl4 19 | Deleting function aws:arn:lambda:region:123456789:helloworld-dev 20 | Deleting IAM Role helloworld-dev 21 | 22 | 23 | Next Steps 24 | ---------- 25 | 26 | At this point, there are several tutorials you can follow based on what 27 | you're interested in: 28 | 29 | * :doc:`Creating REST APIs ` - Dive into more detail on 30 | how to create a REST API using Chalice. We'll explore URL parameters, error 31 | messages, content types, CORs, and more. 32 | * :doc:`Event Sources ` - In this tutorial, we'll focus on 33 | difference event sources you can connect with a Lambda function other than a 34 | REST API with Amazon API Gateway. 35 | * :doc:`Websockets ` - In this tutorial, we'll show you 36 | how to create a websocket API and create a sample chat application. 37 | 38 | You can also jump into specific :doc:`topic guides `. These are 39 | more detailed than the tutorials, and provide more reference style 40 | documentation on specific features of Chalice. 41 | 42 | And finally, you can look at the :doc:`API Reference ` for detailed API 43 | documentation for Chalice. This is useful if you know exactly what feature 44 | you're using but need to lookup a specific parameter name or return value. 45 | -------------------------------------------------------------------------------- /docs/source/samples/index.rst: -------------------------------------------------------------------------------- 1 | Sample Applications 2 | =================== 3 | 4 | Below are a collection of Chalice sample applications. They 5 | show you how you can write more real-world serverless applications. 6 | The code for all of these sample applications is available in 7 | the `Chalice repository on GitHub 8 | `__. 9 | 10 | For each of these sample apps, we'll cover what is does, 11 | the architecture of the app, how to deploy and test the app, 12 | and we'll walk through the key parts of the application code. 13 | 14 | :doc:`todo-app/index` 15 | This app is a REST API that manages Todo 16 | items. These items are stored in an Amazon DynamoDB database. 17 | The REST API is protected with JWT auth. We show you how to 18 | implement auth and login with Chalice's :ref:`builtin-authorizers`. 19 | 20 | :doc:`media-query/index` 21 | This app shows how to create an image 22 | processing pipeline that can analyze images and videos to detect 23 | real world objects. The results of this analysis are then 24 | stored in a database and exposed through a queryable REST API. 25 | 26 | 27 | .. toctree:: 28 | :hidden: 29 | :glob: 30 | 31 | ./*/index 32 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "media-query", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api", 7 | "autogen_policy": false 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/.chalice/policy-dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": [ 6 | "logs:CreateLogGroup", 7 | "logs:CreateLogStream", 8 | "logs:PutLogEvents" 9 | ], 10 | "Resource": "arn:aws:logs:*:*:*", 11 | "Effect": "Allow" 12 | }, 13 | { 14 | "Action": [ 15 | "dynamodb:PutItem", 16 | "dynamodb:DeleteItem", 17 | "dynamodb:UpdateItem", 18 | "dynamodb:GetItem", 19 | "dynamodb:Scan", 20 | "dynamodb:Query" 21 | ], 22 | "Resource": [ 23 | "arn:aws:dynamodb:*:*:table/media-query-*" 24 | ], 25 | "Effect": "Allow" 26 | }, 27 | { 28 | "Action": [ 29 | "rekognition:DetectLabels", 30 | "rekognition:StartLabelDetection", 31 | "rekognition:GetLabelDetection" 32 | ], 33 | "Resource": "*", 34 | "Effect": "Allow" 35 | }, 36 | { 37 | "Action": [ 38 | "s3:GetObject" 39 | ], 40 | "Resource": "arn:aws:s3:::media-query*", 41 | "Effect": "Allow" 42 | }, 43 | { 44 | "Action": [ 45 | "iam:PassRole" 46 | ], 47 | "Resource": "arn:aws:iam::*:role/media-query-*", 48 | "Effect": "Allow" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/app.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import boto3 5 | from chalice import Chalice 6 | from chalice import NotFoundError 7 | from chalicelib import db 8 | from chalicelib import rekognition 9 | 10 | app = Chalice(app_name='media-query') 11 | 12 | _MEDIA_DB = None 13 | _REKOGNITION_CLIENT = None 14 | _SUPPORTED_IMAGE_EXTENSIONS = ( 15 | '.jpg', 16 | '.png', 17 | ) 18 | _SUPPORTED_VIDEO_EXTENSIONS = ( 19 | '.mp4', 20 | '.flv', 21 | '.mov', 22 | ) 23 | 24 | 25 | def get_media_db(): 26 | global _MEDIA_DB 27 | if _MEDIA_DB is None: 28 | _MEDIA_DB = db.DynamoMediaDB( 29 | boto3.resource('dynamodb').Table( 30 | os.environ['MEDIA_TABLE_NAME'])) 31 | return _MEDIA_DB 32 | 33 | 34 | def get_rekognition_client(): 35 | global _REKOGNITION_CLIENT 36 | if _REKOGNITION_CLIENT is None: 37 | _REKOGNITION_CLIENT = rekognition.RekognitonClient( 38 | boto3.client('rekognition')) 39 | return _REKOGNITION_CLIENT 40 | 41 | 42 | # Start of Event Handlers. 43 | @app.on_s3_event(bucket=os.environ['MEDIA_BUCKET_NAME'], 44 | events=['s3:ObjectCreated:*']) 45 | def handle_object_created(event): 46 | if _is_image(event.key): 47 | _handle_created_image(bucket=event.bucket, key=event.key) 48 | elif _is_video(event.key): 49 | _handle_created_video(bucket=event.bucket, key=event.key) 50 | 51 | 52 | @app.on_s3_event(bucket=os.environ['MEDIA_BUCKET_NAME'], 53 | events=['s3:ObjectRemoved:*']) 54 | def handle_object_removed(event): 55 | if _is_image(event.key) or _is_video(event.key): 56 | get_media_db().delete_media_file(event.key) 57 | 58 | 59 | @app.on_sns_message(topic=os.environ['VIDEO_TOPIC_NAME']) 60 | def add_video_file(event): 61 | message = json.loads(event.message) 62 | labels = get_rekognition_client().get_video_job_labels(message['JobId']) 63 | get_media_db().add_media_file( 64 | name=message['Video']['S3ObjectName'], 65 | media_type=db.VIDEO_TYPE, 66 | labels=labels) 67 | 68 | 69 | @app.route('/') 70 | def list_media_files(): 71 | params = {} 72 | if app.current_request.query_params: 73 | params = _extract_db_list_params(app.current_request.query_params) 74 | return get_media_db().list_media_files(**params) 75 | 76 | 77 | @app.route('/{name}') 78 | def get_media_file(name): 79 | item = get_media_db().get_media_file(name) 80 | if item is None: 81 | raise NotFoundError('Media file (%s) not found' % name) 82 | return item 83 | # End of Event Handlers. 84 | 85 | 86 | def _extract_db_list_params(query_params): 87 | valid_query_params = [ 88 | 'startswith', 89 | 'media-type', 90 | 'label' 91 | ] 92 | return { 93 | k.replace('-', '_'): v 94 | for k, v in query_params.items() if k in valid_query_params 95 | } 96 | 97 | 98 | def _is_image(key): 99 | return key.endswith(_SUPPORTED_IMAGE_EXTENSIONS) 100 | 101 | 102 | def _handle_created_image(bucket, key): 103 | labels = get_rekognition_client().get_image_labels(bucket=bucket, key=key) 104 | get_media_db().add_media_file(key, media_type=db.IMAGE_TYPE, labels=labels) 105 | 106 | 107 | def _is_video(key): 108 | return key.endswith(_SUPPORTED_VIDEO_EXTENSIONS) 109 | 110 | 111 | def _handle_created_video(bucket, key): 112 | get_rekognition_client().start_video_label_job( 113 | bucket=bucket, key=key, topic_arn=os.environ['VIDEO_TOPIC_ARN'], 114 | role_arn=os.environ['VIDEO_ROLE_ARN'] 115 | ) 116 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/chalicelib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/media-query/code/chalicelib/__init__.py -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/chalicelib/db.py: -------------------------------------------------------------------------------- 1 | from boto3.dynamodb.conditions import Attr 2 | 3 | 4 | IMAGE_TYPE = 'image' 5 | VIDEO_TYPE = 'video' 6 | 7 | 8 | class MediaDB(object): 9 | def list_media_files(self, label=None): 10 | pass 11 | 12 | def add_media_file(self, name, media_type, labels=None): 13 | pass 14 | 15 | def get_media_file(self, name): 16 | pass 17 | 18 | def delete_media_file(self, name): 19 | pass 20 | 21 | 22 | class DynamoMediaDB(MediaDB): 23 | def __init__(self, table_resource): 24 | self._table = table_resource 25 | 26 | def list_media_files(self, startswith=None, media_type=None, label=None): 27 | scan_params = {} 28 | filter_expression = None 29 | if startswith is not None: 30 | filter_expression = self._add_to_filter_expression( 31 | filter_expression, Attr('name').begins_with(startswith) 32 | ) 33 | if media_type is not None: 34 | filter_expression = self._add_to_filter_expression( 35 | filter_expression, Attr('type').eq(media_type) 36 | ) 37 | if label is not None: 38 | filter_expression = self._add_to_filter_expression( 39 | filter_expression, Attr('labels').contains(label) 40 | ) 41 | if filter_expression: 42 | scan_params['FilterExpression'] = filter_expression 43 | response = self._table.scan(**scan_params) 44 | return response['Items'] 45 | 46 | def add_media_file(self, name, media_type, labels=None): 47 | if labels is None: 48 | labels = [] 49 | self._table.put_item( 50 | Item={ 51 | 'name': name, 52 | 'type': media_type, 53 | 'labels': labels, 54 | } 55 | ) 56 | 57 | def get_media_file(self, name): 58 | response = self._table.get_item( 59 | Key={ 60 | 'name': name, 61 | }, 62 | ) 63 | return response.get('Item') 64 | 65 | def delete_media_file(self, name): 66 | self._table.delete_item( 67 | Key={ 68 | 'name': name, 69 | } 70 | ) 71 | 72 | def _add_to_filter_expression(self, expression, condition): 73 | if expression is None: 74 | return condition 75 | return expression & condition 76 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/chalicelib/rekognition.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | 4 | class RekognitonClient(object): 5 | def __init__(self, boto3_client): 6 | self._boto3_client = boto3_client 7 | 8 | def get_image_labels(self, bucket, key): 9 | response = self._boto3_client.detect_labels( 10 | Image={ 11 | 'S3Object': { 12 | 'Bucket': bucket, 13 | 'Name': key 14 | }, 15 | }, 16 | MinConfidence=50.0 17 | ) 18 | return [label['Name'] for label in response['Labels']] 19 | 20 | def start_video_label_job(self, bucket, key, topic_arn, role_arn): 21 | response = self._boto3_client.start_label_detection( 22 | Video={ 23 | 'S3Object': { 24 | 'Bucket': bucket, 25 | 'Name': key 26 | } 27 | }, 28 | ClientRequestToken=str(uuid.uuid4()), 29 | NotificationChannel={ 30 | 'SNSTopicArn': topic_arn, 31 | 'RoleArn': role_arn 32 | }, 33 | MinConfidence=50.0 34 | ) 35 | return response['JobId'] 36 | 37 | def get_video_job_labels(self, job_id): 38 | labels = set() 39 | client_kwargs = { 40 | 'JobId': job_id, 41 | } 42 | response = self._boto3_client.get_label_detection(**client_kwargs) 43 | self._collect_video_labels(labels, response) 44 | while 'NextToken' in response: 45 | client_kwargs['NextToken'] = response['NextToken'] 46 | response = self._boto3_client.get_label_detection(**client_kwargs) 47 | self._collect_video_labels(labels, response) 48 | return list(labels) 49 | 50 | def _collect_video_labels(self, labels, response): 51 | for label in response['Labels']: 52 | label_name = label['Label']['Name'] 53 | labels.add(label_name) 54 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/recordresources.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | import os 4 | 5 | import boto3 6 | from botocore import xform_name 7 | 8 | 9 | def record_as_env_var(stack_name, stage): 10 | cloudformation = boto3.client('cloudformation') 11 | response = cloudformation.describe_stacks( 12 | StackName=stack_name 13 | ) 14 | outputs = response['Stacks'][0]['Outputs'] 15 | with open(os.path.join('.chalice', 'config.json')) as f: 16 | data = json.load(f) 17 | data['stages'].setdefault(stage, {}).setdefault( 18 | 'environment_variables', {} 19 | ) 20 | for output in outputs: 21 | data['stages'][stage]['environment_variables'][ 22 | _to_env_var_name(output['OutputKey'])] = output['OutputValue'] 23 | with open(os.path.join('.chalice', 'config.json'), 'w') as f: 24 | serialized = json.dumps(data, indent=2, separators=(',', ': ')) 25 | f.write(serialized + '\n') 26 | 27 | 28 | def _to_env_var_name(name): 29 | return xform_name(name).upper() 30 | 31 | 32 | def main(): 33 | parser = argparse.ArgumentParser() 34 | parser.add_argument('-s', '--stage', default='dev') 35 | parser.add_argument('--stack-name', required=True) 36 | args = parser.parse_args() 37 | record_as_env_var(stack_name=args.stack_name, stage=args.stage) 38 | 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3<1.15.0 2 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/code/resources.json: -------------------------------------------------------------------------------- 1 | { 2 | "Outputs": { 3 | "MediaBucketName": { 4 | "Value": { 5 | "Ref": "MediaBucket" 6 | } 7 | }, 8 | "MediaTableName": { 9 | "Value": { 10 | "Ref": "MediaTable" 11 | } 12 | }, 13 | "VideoTopicArn": { 14 | "Value": { 15 | "Ref": "VideoTopic" 16 | } 17 | }, 18 | "VideoTopicName": { 19 | "Value": { 20 | "Fn::GetAtt": [ 21 | "VideoTopic", 22 | "TopicName" 23 | ] 24 | } 25 | }, 26 | "VideoRoleArn": { 27 | "Value": { 28 | "Fn::GetAtt": [ 29 | "VideoRole", 30 | "Arn" 31 | ] 32 | } 33 | } 34 | }, 35 | "Resources": { 36 | "MediaBucket": { 37 | "Type": "AWS::S3::Bucket" 38 | }, 39 | "MediaTable": { 40 | "Properties": { 41 | "AttributeDefinitions": [ 42 | { 43 | "AttributeName": "name", 44 | "AttributeType": "S" 45 | } 46 | ], 47 | "KeySchema": [ 48 | { 49 | "AttributeName": "name", 50 | "KeyType": "HASH" 51 | } 52 | ], 53 | "ProvisionedThroughput": { 54 | "ReadCapacityUnits": 5, 55 | "WriteCapacityUnits": 5 56 | } 57 | }, 58 | "Type": "AWS::DynamoDB::Table" 59 | }, 60 | "VideoTopic": { 61 | "Type": "AWS::SNS::Topic" 62 | }, 63 | "VideoRole": { 64 | "Properties": { 65 | "AssumeRolePolicyDocument": { 66 | "Statement": [ 67 | { 68 | "Effect": "Allow", 69 | "Action": [ 70 | "sts:AssumeRole" 71 | ], 72 | "Principal": { 73 | "Service": [ 74 | "rekognition.amazonaws.com" 75 | ] 76 | } 77 | } 78 | ] 79 | }, 80 | "Policies": [ 81 | { 82 | "PolicyName": "RekognitionPublish", 83 | "PolicyDocument": { 84 | "Statement": [ 85 | { 86 | "Effect": "Allow", 87 | "Action": [ 88 | "sns:Publish" 89 | ], 90 | "Resource": [ 91 | { 92 | "Ref": "VideoTopic" 93 | } 94 | ] 95 | } 96 | ] 97 | } 98 | } 99 | ] 100 | }, 101 | "Type": "AWS::IAM::Role" 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /docs/source/samples/media-query/docs/assets/appexample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/media-query/docs/assets/appexample.jpg -------------------------------------------------------------------------------- /docs/source/samples/media-query/docs/assets/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/media-query/docs/assets/architecture.png -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stages": { 3 | "dev": { 4 | "autogen_policy": false, 5 | "api_gateway_stage": "api" 6 | } 7 | }, 8 | "version": "2.0", 9 | "app_name": "mytodo" 10 | } 11 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/.chalice/policy-dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": [ 6 | "logs:CreateLogGroup", 7 | "logs:CreateLogStream", 8 | "logs:PutLogEvents" 9 | ], 10 | "Resource": "arn:aws:logs:*:*:*", 11 | "Effect": "Allow" 12 | }, 13 | { 14 | "Action": [ 15 | "dynamodb:PutItem", 16 | "dynamodb:DeleteItem", 17 | "dynamodb:UpdateItem", 18 | "dynamodb:GetItem", 19 | "dynamodb:Scan", 20 | "dynamodb:Query" 21 | ], 22 | "Resource": [ 23 | "arn:aws:dynamodb:*:*:table/todo-app-*", 24 | "arn:aws:dynamodb:*:*:table/users-app-*" 25 | ], 26 | "Effect": "Allow" 27 | }, 28 | { 29 | "Action": [ 30 | "ssm:GetParameter" 31 | ], 32 | "Resource": [ 33 | "arn:aws:ssm:*:*:parameter/todo-sample-app/auth-key" 34 | ], 35 | "Effect": "Allow" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import base64 3 | 4 | import boto3 5 | from chalice import Chalice, AuthResponse 6 | from chalicelib import auth, db 7 | 8 | 9 | app = Chalice(app_name='mytodo') 10 | app.debug = True 11 | _DB = None 12 | _USER_DB = None 13 | _AUTH_KEY = None 14 | _SSM_AUTH_KEY_NAME = '/todo-sample-app/auth-key' 15 | 16 | 17 | @app.route('/login', methods=['POST']) 18 | def login(): 19 | body = app.current_request.json_body 20 | record = get_users_db().get_item( 21 | Key={'username': body['username']})['Item'] 22 | jwt_token = auth.get_jwt_token( 23 | body['username'], body['password'], record, get_auth_key()) 24 | return {'token': jwt_token} 25 | 26 | 27 | @app.authorizer() 28 | def jwt_auth(auth_request): 29 | token = auth_request.token 30 | decoded = auth.decode_jwt_token(token, get_auth_key()) 31 | return AuthResponse(routes=['*'], principal_id=decoded['sub']) 32 | 33 | 34 | def get_auth_key(): 35 | global _AUTH_KEY 36 | if _AUTH_KEY is None: 37 | base64_key = boto3.client('ssm').get_parameter( 38 | Name=_SSM_AUTH_KEY_NAME, 39 | WithDecryption=True 40 | )['Parameter']['Value'] 41 | _AUTH_KEY = base64.b64decode(base64_key) 42 | return _AUTH_KEY 43 | 44 | 45 | def get_users_db(): 46 | global _USER_DB 47 | if _USER_DB is None: 48 | _USER_DB = boto3.resource('dynamodb').Table( 49 | os.environ['USERS_TABLE_NAME']) 50 | return _USER_DB 51 | 52 | 53 | def get_app_db(): 54 | global _DB 55 | if _DB is None: 56 | _DB = db.DynamoDBTodo( 57 | boto3.resource('dynamodb').Table( 58 | os.environ['APP_TABLE_NAME']) 59 | ) 60 | return _DB 61 | 62 | 63 | def get_authorized_username(current_request): 64 | return current_request.context['authorizer']['principalId'] 65 | 66 | 67 | @app.route('/todos', methods=['GET'], authorizer=jwt_auth) 68 | def list_todos(): 69 | username = get_authorized_username(app.current_request) 70 | return get_app_db().list_items(username=username) 71 | 72 | 73 | @app.route('/todos', methods=['POST'], authorizer=jwt_auth) 74 | def create_todo(): 75 | body = app.current_request.json_body 76 | username = get_authorized_username(app.current_request) 77 | return get_app_db().add_item( 78 | username=username, 79 | description=body['description'], 80 | metadata=body.get('metadata'), 81 | ) 82 | 83 | 84 | @app.route('/todos/{uid}', methods=['GET'], authorizer=jwt_auth) 85 | def get_todo(uid): 86 | username = get_authorized_username(app.current_request) 87 | return get_app_db().get_item(uid, username=username) 88 | 89 | 90 | @app.route('/todos/{uid}', methods=['PUT'], authorizer=jwt_auth) 91 | def update_todo(uid): 92 | body = app.current_request.json_body 93 | username = get_authorized_username(app.current_request) 94 | get_app_db().update_item( 95 | uid, 96 | description=body.get('description'), 97 | state=body.get('state'), 98 | metadata=body.get('metadata'), 99 | username=username) 100 | 101 | 102 | @app.route('/todos/{uid}', methods=['DELETE'], authorizer=jwt_auth) 103 | def delete_todo(uid): 104 | username = get_authorized_username(app.current_request) 105 | return get_app_db().delete_item(uid, username=username) 106 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/chalicelib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/todo-app/code/chalicelib/__init__.py -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/chalicelib/auth.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import hmac 3 | import datetime 4 | from uuid import uuid4 5 | 6 | import jwt 7 | from chalice import UnauthorizedError 8 | 9 | 10 | def get_jwt_token(username, password, record, secret): 11 | actual = hashlib.pbkdf2_hmac( 12 | record['hash'], 13 | password.encode('utf-8'), 14 | record['salt'].value, 15 | int(record['rounds']) 16 | ) 17 | expected = record['hashed'].value 18 | if hmac.compare_digest(actual, expected): 19 | now = datetime.datetime.utcnow() 20 | unique_id = str(uuid4()) 21 | payload = { 22 | 'sub': username, 23 | 'iat': now, 24 | 'nbf': now, 25 | 'jti': unique_id, 26 | # NOTE: We can also add 'exp' if we want tokens to expire. 27 | } 28 | return jwt.encode(payload, secret, algorithm='HS256') 29 | raise UnauthorizedError('Invalid password') 30 | 31 | 32 | def decode_jwt_token(token, secret): 33 | return jwt.decode(token, secret, algorithms=['HS256']) 34 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | chalice==1.29.0 2 | pytest==7.4.0 3 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.27.0 2 | botocore==1.30.0 3 | PyJWT==2.7.0 4 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/todo-app/code/tests/__init__.py -------------------------------------------------------------------------------- /docs/source/samples/todo-app/code/users.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import getpass 4 | import argparse 5 | import hashlib 6 | import hmac 7 | import base64 8 | 9 | import boto3 10 | from boto3.dynamodb.types import Binary 11 | 12 | 13 | def get_table_name(stage): 14 | # We might want to user the chalice modules to 15 | # load the config. For now we'll just load it directly. 16 | with open(os.path.join('.chalice', 'config.json')) as f: 17 | data = json.load(f) 18 | return data['stages'][stage]['environment_variables']['USERS_TABLE_NAME'] 19 | 20 | 21 | def create_user(stage): 22 | table_name = get_table_name(stage) 23 | table = boto3.resource('dynamodb').Table(table_name) 24 | username = input('Username: ').strip() 25 | password = getpass.getpass('Password: ').strip() 26 | password_fields = encode_password(password) 27 | item = { 28 | 'username': username, 29 | 'hash': password_fields['hash'], 30 | 'salt': Binary(password_fields['salt']), 31 | 'rounds': password_fields['rounds'], 32 | 'hashed': Binary(password_fields['hashed']), 33 | } 34 | table.put_item(Item=item) 35 | 36 | 37 | def encode_password(password, salt=None): 38 | if salt is None: 39 | salt = os.urandom(32) 40 | rounds = 100000 41 | hashed = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), 42 | salt, rounds) 43 | return { 44 | 'hash': 'sha256', 45 | 'salt': salt, 46 | 'rounds': rounds, 47 | 'hashed': hashed, 48 | } 49 | 50 | 51 | def list_users(stage): 52 | table_name = get_table_name(stage) 53 | table = boto3.resource('dynamodb').Table(table_name) 54 | for item in table.scan()['Items']: 55 | print(item['username']) 56 | 57 | 58 | def get_user(username, stage): 59 | table_name = get_table_name(stage) 60 | table = boto3.resource('dynamodb').Table(table_name) 61 | user_record = table.get_item(Key={'username': username}).get('Item') 62 | if user_record is not None: 63 | print(f"Entry for user: {username}") 64 | for key, value in user_record.items(): 65 | if isinstance(value, Binary): 66 | value = base64.b64encode(value.value).decode() 67 | print(f" {key:10}: {value}") 68 | 69 | 70 | def test_password(stage): 71 | username = input('Username: ').strip() 72 | password = getpass.getpass('Password: ').strip() 73 | table_name = get_table_name(stage) 74 | table = boto3.resource('dynamodb').Table(table_name) 75 | item = table.get_item(Key={'username': username})['Item'] 76 | encoded = encode_password(password, salt=item['salt'].value) 77 | if hmac.compare_digest(encoded['hashed'], item['hashed'].value): 78 | print("Password verified.") 79 | else: 80 | print("Password verification failed.") 81 | 82 | 83 | def main(): 84 | parser = argparse.ArgumentParser() 85 | parser.add_argument('-c', '--create-user', action='store_true') 86 | parser.add_argument('-t', '--test-password', action='store_true') 87 | parser.add_argument('-g', '--get-user') 88 | parser.add_argument('-s', '--stage', default='dev') 89 | parser.add_argument('-l', '--list-users', action='store_true') 90 | args = parser.parse_args() 91 | if args.create_user: 92 | create_user(args.stage) 93 | elif args.list_users: 94 | list_users(args.stage) 95 | elif args.test_password: 96 | test_password(args.stage) 97 | elif args.get_user is not None: 98 | get_user(args.get_user, args.stage) 99 | 100 | 101 | if __name__ == '__main__': 102 | main() 103 | -------------------------------------------------------------------------------- /docs/source/samples/todo-app/docs/assets/architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/samples/todo-app/docs/assets/architecture.jpg -------------------------------------------------------------------------------- /docs/source/theme/smithy/globaltoc.html: -------------------------------------------------------------------------------- 1 | {# 2 | basic/globaltoc.html 3 | ~~~~~~~~~~~~~~~~~~~~ 4 | #} 5 | 8 | -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/custom-tabs.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Add overrides to how tabs are styled to make them less visually 3 | * obstrusive. Note, however, that this might need to be looked at in 4 | * the future if we ever want to use non-code-tabs. 5 | */ 6 | 7 | /* No need for margin below code samples when in a tab. */ 8 | .code-tab pre { 9 | margin-bottom: 0; 10 | } 11 | 12 | .sphinx-tabs { 13 | margin-top: 1rem; 14 | } 15 | 16 | /* Code tabs should encompass the entire tab. */ 17 | .code-tab.tab { 18 | padding: 0 !important; 19 | } 20 | 21 | .ui.tabular.menu { 22 | border: none; 23 | } 24 | 25 | .ui.tabular.menu .item { 26 | font-size: 0.8em; 27 | font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace; 28 | text-transform: lowercase; 29 | border: none !important; 30 | } 31 | 32 | .ui.attached.segment.code-tab { 33 | border: none !important; 34 | } 35 | 36 | /* Remove code tab headings and use the same color as code backgrounds */ 37 | .ui.tabular.menu .active.item { 38 | border: none !important; 39 | background-color: inherit; 40 | text-decoration: underline; 41 | font-weight: normal; 42 | } 43 | -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/favicon.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/chalice-logo-icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/chalice-logo-icon-small.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/chalice-logo-icon-whitespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/chalice-logo-icon-whitespace.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/chalice-logo-whitespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/chalice-logo-whitespace.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/coding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/coding.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/maintenance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/maintenance.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/programming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/docs/source/theme/smithy/static/img/programming.png -------------------------------------------------------------------------------- /docs/source/theme/smithy/static/img/speed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/source/theme/smithy/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = default.css 4 | 5 | [options] 6 | primary = #232f3E 7 | dark_primary = #232f3E 8 | medium_primary = #232f3E 9 | light_primary = #2BBA9C 10 | 11 | medium_accent = #2BBA9C 12 | dark_accent = #283D3B 13 | site_background = #fff 14 | link_color = #00818e; 15 | regular_font = -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol' 16 | code_font = "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace 17 | ga_id = 18 | -------------------------------------------------------------------------------- /docs/source/topics/experimental.rst: -------------------------------------------------------------------------------- 1 | Experimental APIs 2 | ================= 3 | 4 | Chalice maintains backwards compatibility for all features that appear in this 5 | documentation. Any Chalice application using version 1.x will continue to work 6 | for all future versions of 1.x. 7 | 8 | We also believe that Chalice has a lot of potential for new ideas and APIs, 9 | many of which will take several iterations to get right. We may implement a 10 | new idea and need to make changes based on customer usage and feedback. This 11 | may include backwards incompatible changes all the way up to the removal of 12 | a feature. 13 | 14 | To accommodate these new features, Chalice has support for experimental APIs, 15 | which are features that are added to Chalice on a provisional basis. Because 16 | these features may include backwards incompatible changes, you must explicitly 17 | opt-in to using these features. This makes it clear that you are using an 18 | experimental feature that may change. 19 | 20 | Opting-in to Experimental APIs 21 | ------------------------------ 22 | 23 | Each experimental feature in chalice has a name associated with it. To opt-in 24 | to an experimental API, you must have the feature name to the 25 | ``experimental_feature_flags`` attribute on your ``app`` object. 26 | This attribute's type is a set of strings. 27 | 28 | .. code-block:: python 29 | 30 | from chalice import Chalice 31 | 32 | app = Chalice('myapp') 33 | app.experimental_feature_flags.update([ 34 | 'MYFEATURE1', 35 | 'MYFEATURE2', 36 | ]) 37 | 38 | 39 | If you use an experimental API without opting-in, you will receive 40 | a message whenever you run a Chalice CLI command. The error message 41 | tells you which feature flags you need to add:: 42 | 43 | $ chalice deploy 44 | You are using experimental features without explicitly opting in. 45 | Experimental features do not guarantee backwards compatibility and may be removed in the future. 46 | If you still like to use these experimental features, you can opt-in by adding this to your app.py file: 47 | 48 | app.experimental_feature_flags.update([ 49 | 'FEATURE_FLAG_NAME' 50 | ]) 51 | 52 | 53 | See https://aws.github.io/chalice/topics/experimental.rst for more details. 54 | 55 | The feature flag only happens when running CLI commands. There are no runtime 56 | checks for experimental features once your application is deployed. 57 | 58 | 59 | List of Experimental APIs 60 | ------------------------- 61 | 62 | In the table below, the "Feature Flag Name" column is the value you 63 | must add to the ``app.experimental_feature_flags`` attribute. 64 | The status of an experimental API can be: 65 | 66 | * ``Trial`` - You must explicitly opt-in to use this feature. 67 | * ``Accepted`` - This feature has graduated from an experimental 68 | feature to a fully supported, backwards compatible feature in Chalice. 69 | Accepted features still appear in the table for auditing purposes. 70 | * ``Rejected`` - This feature has been removed. 71 | 72 | 73 | .. list-table:: Experimental APIs 74 | :header-rows: 1 75 | 76 | * - Feature 77 | - Feature Flag Name 78 | - Version Added 79 | - Version Finalized 80 | - Status 81 | - GitHub Issue(s) 82 | * - :doc:`blueprints` 83 | - ``BLUEPRINTS`` 84 | - 1.7.0 85 | - 1.15.0 86 | - Accepted 87 | - `#1023 `__, 88 | `#651 `__ 89 | * - :doc:`websockets` 90 | - ``WEBSOCKETS`` 91 | - 1.10.0 92 | - n/a 93 | - Trial 94 | - `#1041 `__, 95 | `#1017 `__ 96 | 97 | 98 | See the `original discussion `__ 99 | for more background information and alternative proposals. 100 | -------------------------------------------------------------------------------- /docs/source/topics/index.rst: -------------------------------------------------------------------------------- 1 | Topics 2 | ====== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | routing 8 | views 9 | configfile 10 | multifile 11 | logging 12 | sdks 13 | stages 14 | packaging 15 | pyversion 16 | cfn 17 | tf 18 | authorizers 19 | events 20 | purelambda 21 | blueprints 22 | websockets 23 | cd 24 | domainname 25 | experimental 26 | testing 27 | middleware 28 | -------------------------------------------------------------------------------- /docs/source/topics/multifile.rst: -------------------------------------------------------------------------------- 1 | Multifile Support 2 | ================= 3 | 4 | The ``app.py`` file contains all of your view functions and route 5 | information, but you don't have to keep all of your application 6 | code in your ``app.py`` file. 7 | 8 | As your application grows, you may reach out a point where you'd 9 | prefer to structure your application in multiple files. 10 | You can create a ``chalicelib/`` directory, and anything 11 | in that directory is recursively included in the deployment 12 | package. This means that you can have files besides just 13 | ``.py`` files in ``chalicelib/``, including ``.json`` files 14 | for config, or any kind of binary assets. 15 | 16 | Let's take a look at a few examples. 17 | 18 | Consider the following app directory structure layout:: 19 | 20 | . 21 | ├── app.py 22 | ├── chalicelib 23 | │   └── __init__.py 24 | └── requirements.txt 25 | 26 | Where ``chalicelib/__init__.py`` contains: 27 | 28 | .. code-block:: python 29 | 30 | MESSAGE = 'world' 31 | 32 | 33 | and the ``app.py`` file contains: 34 | 35 | .. code-block:: python 36 | :linenos: 37 | :emphasize-lines: 2 38 | 39 | from chalice import Chalice 40 | from chalicelib import MESSAGE 41 | 42 | app = Chalice(app_name="multifile") 43 | 44 | @app.route("/") 45 | def index(): 46 | return {"hello": MESSAGE} 47 | 48 | 49 | Note in line 2 we're importing the ``MESSAGE`` variable from 50 | the ``chalicelib`` package, which is a top level directory 51 | in our project. We've created a ``chalicelib/__init__.py`` 52 | file which turns the ``chalicelib`` directory into a python 53 | package. 54 | 55 | We can also use this directory to store config data. Consider 56 | this app structure layout:: 57 | 58 | 59 | . 60 | ├── app.py 61 | ├── chalicelib 62 | │   └── config.json 63 | └── requirements.txt 64 | 65 | 66 | With ``chalicelib/config.json`` containing:: 67 | 68 | {"message": "world"} 69 | 70 | 71 | In our ``app.py`` code, we can load and use our config file: 72 | 73 | .. code-block:: python 74 | :linenos: 75 | 76 | import os 77 | import json 78 | 79 | from chalice import Chalice 80 | 81 | app = Chalice(app_name="multifile") 82 | 83 | filename = os.path.join( 84 | os.path.dirname(__file__), 'chalicelib', 'config.json') 85 | with open(filename) as f: 86 | config = json.load(f) 87 | 88 | @app.route("/") 89 | def index(): 90 | # We can access ``config`` here if we want. 91 | return {"hello": config['message']} 92 | -------------------------------------------------------------------------------- /docs/source/topics/purelambda.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Pure Lambda Functions 3 | ===================== 4 | 5 | 6 | Chalice provides abstractions over AWS Lambda functions, including: 7 | 8 | * An API handler that coordinates with API Gateway for creating rest APIs. 9 | * A custom authorizer that allows you to integrate custom auth logic in your 10 | rest API. 11 | * A scheduled event that includes managing the CloudWatch Event rules, targets, 12 | and permissions. 13 | 14 | However, chalice also supports managing pure Lambda functions that don't have 15 | any abstractions built on top. This is useful if you want to create a Lambda 16 | function for something that's not supported by chalice or if you just want to 17 | create Lambda functions but don't want to manage handling dependencies and 18 | deployments yourself. 19 | 20 | In order to do this, you can use the :meth:`Chalice.lambda_function` decorator 21 | to denote that this python function is a pure lambda function that should 22 | be invoked as is, without any input or output mapping. When you use 23 | this function, you must provide a function that maps to the same function 24 | signature expected by AWS Lambda as `defined here`_. 25 | 26 | Let's look at an example. 27 | 28 | .. code-block:: python 29 | 30 | app = chalice.Chalice(app_name='foo') 31 | 32 | @app.route('/') 33 | def index(): 34 | return {'hello': 'world'} 35 | 36 | @app.lambda_function() 37 | def custom_lambda_function(event, context): 38 | # Anything you want here. 39 | return {} 40 | 41 | @app.lambda_function(name='MyFunction') 42 | def other_lambda_function(event, context): 43 | # Anything you want here. 44 | return {} 45 | 46 | In this example, we've updated the starter hello world app with 47 | two extra Lambda functions. When you run ``chalice deploy`` Chalice will create 48 | three Lambda functions. The first lambda function is for the API handler 49 | used by API gateway. The second and third lambda functions will be pure lambda 50 | functions. These two additional lambda functions won't be hooked up to anything. 51 | You'll need to manage connecting them to any additional AWS Resources on your 52 | own. 53 | 54 | 55 | .. _defined here: https://docs.aws.amazon.com/lambda/latest/dg/python-programming-model-handler-types.html 56 | -------------------------------------------------------------------------------- /docs/source/topics/pyversion.rst: -------------------------------------------------------------------------------- 1 | Python Version Support 2 | ====================== 3 | 4 | Chalice supports all versions of python supported by AWS Lambda, which is 5 | currently Python 3.6 and greater. You can see the list of 6 | supported python versions for Lambda in their 7 | `docs `__. 8 | 9 | Chalice will automatically pick which version of python to use for Lambda 10 | based on the major version of python you are using. You don't have to 11 | explicitly configure which version of python you want to use. For example:: 12 | 13 | $ python --version 14 | Python 3.6.1 15 | $ chalice new-project test-versions 16 | $ cd test-versions 17 | $ chalice package test-package 18 | $ grep -C 3 python test-package/sam.json 19 | "APIHandler": { 20 | "Type": "AWS::Serverless::Function", 21 | "Properties": { 22 | "Runtime": "python3.6", 23 | "Handler": "app.app", 24 | "CodeUri": "./deployment.zip", 25 | "Events": { 26 | 27 | # Similarly, if we were to run "chalice deploy" we'd 28 | # use python3.6 for the runtime. 29 | $ chalice --debug deploy 30 | Initiating first time deployment... 31 | Deploying to: dev 32 | ... 33 | "Runtime":"python3.6" 34 | ... 35 | https://rest-api-id.execute-api.us-west-2.amazonaws.com/api/ 36 | 37 | 38 | In the example above, we're using python 3.6.1 so chalice automatically 39 | selects the ``python3.6`` runtime for lambda. If we were using python 3.9.6, 40 | chalice would automatically select ``python3.9`` as the runtime. 41 | 42 | Chalice will emit a warning if the minor version does not match a python 43 | version supported by Lambda. Chalice will select the closest Lambda version 44 | in this scenario, as shown in the table below. 45 | 46 | We strongly encourage you to develop your application using the same 47 | major/minor version of python you plan on using on AWS Lambda. 48 | 49 | 50 | Changing Python Runtime Versions 51 | ================================ 52 | 53 | The version of the python runtime to use in AWS Lambda can be reconfigured 54 | whenever you deploy your chalice app. This allows you to migrate to newer 55 | Python versions in AWS Lambda by creating a new virtual environment that uses 56 | python3. For example, suppose you have an existing chalice app that uses 57 | Python 3.6 :: 58 | 59 | $ python --version 60 | Python 3.6.1 61 | $ chalice deploy 62 | ... 63 | https://endpoint/api 64 | 65 | To upgrade the application to use Python 3.9, create a python3 virtual 66 | environment and redeploy. 67 | 68 | :: 69 | 70 | $ deactivate 71 | $ python3 -m venv /tmp/venv3 72 | $ source /tmp/venv3/bin/activate 73 | $ python --version 74 | Python 3.9.6 75 | $ chalice deploy 76 | ... 77 | -------------------------------------------------------------------------------- /docs/source/topics/routing.rst: -------------------------------------------------------------------------------- 1 | Routing 2 | ======= 3 | 4 | The :meth:`Chalice.route` method is used to construct which routes 5 | you want to create for your API. The concept is the same 6 | mechanism used by `Flask `__ and 7 | `bottle `__. 8 | You decorate a function with ``@app.route(...)``, and whenever 9 | a user requests that URL, the function you've decorated is called. 10 | For example, suppose you deployed this app: 11 | 12 | .. code-block:: python 13 | 14 | from chalice import Chalice 15 | 16 | app = Chalice(app_name='helloworld') 17 | 18 | 19 | @app.route('/') 20 | def index(): 21 | return {'view': 'index'} 22 | 23 | @app.route('/a') 24 | def a(): 25 | return {'view': 'a'} 26 | 27 | @app.route('/b') 28 | def b(): 29 | return {'view': 'b'} 30 | 31 | 32 | If you go to ``https://endpoint/``, the ``index()`` function would be called. 33 | If you went to ``https://endpoint/a`` and ``https://endpoint/b``, then the 34 | ``a()`` and ``b()`` function would be called, respectively. 35 | 36 | .. note:: 37 | 38 | Do not end your route paths with a trailing slash. If you do this, the 39 | ``chalice deploy`` command will raise a validation error. 40 | 41 | 42 | You can also create a route that captures part of the URL. This captured value 43 | will then be passed in as arguments to your view function: 44 | 45 | 46 | .. code-block:: python 47 | 48 | from chalice import Chalice 49 | 50 | app = Chalice(app_name='helloworld') 51 | 52 | 53 | @app.route('/users/{name}') 54 | def users(name): 55 | return {'name': name} 56 | 57 | 58 | If you then go to ``https://endpoint/users/james``, then the view function 59 | will be called as: ``users('james')``. The parameters are passed as 60 | keyword parameters based on the name as they appear in the URL. The argument 61 | names for the view function must match the name of the captured 62 | argument: 63 | 64 | 65 | .. code-block:: python 66 | 67 | from chalice import Chalice 68 | 69 | app = Chalice(app_name='helloworld') 70 | 71 | 72 | @app.route('/a/{first}/b/{second}') 73 | def users(first, second): 74 | return {'first': first, 'second': second} 75 | 76 | 77 | Other Request Metadata 78 | ---------------------- 79 | 80 | The route path can only contain ``[a-zA-Z0-9._-]`` chars and curly braces for 81 | parts of the URL you want to capture. You do not need to model other parts of 82 | the request you want to capture, including headers and query strings. Within 83 | a view function, you can introspect the current request using the 84 | :attr:`app.current_request ` attribute. This also 85 | means you cannot control the routing based on query strings or headers. 86 | Here's an example for accessing query string data in a view function: 87 | 88 | .. code-block:: python 89 | 90 | from chalice import Chalice 91 | 92 | app = Chalice(app_name='helloworld') 93 | 94 | 95 | @app.route('/users/{name}') 96 | def users(name): 97 | result = {'name': name} 98 | if app.current_request.query_params.get('include-greeting') == 'true': 99 | result['greeting'] = 'Hello, %s' % name 100 | return result 101 | 102 | In the function above, if the user provides a ``?include-greeting=true`` in the 103 | HTTP request, then an additional ``greeting`` key will be returned:: 104 | 105 | $ http https://endpoint/api/users/bob 106 | 107 | { 108 | "name": "bob" 109 | } 110 | 111 | $ http https://endpoint/api/users/bob?include-greeting=true 112 | 113 | { 114 | "greeting": "Hello, bob", 115 | "name": "bob" 116 | } 117 | -------------------------------------------------------------------------------- /docs/source/topics/stages.rst: -------------------------------------------------------------------------------- 1 | Chalice Stages 2 | ============== 3 | 4 | Chalice has the concept of stages, which are completely 5 | separate sets of AWS resources. When you first create a chalice 6 | project and run commands such as ``chalice deploy`` and ``chalice url``, 7 | you don't have to specify any stage values or stage configuration. 8 | This is because chalice will use a stage named ``dev`` by default. 9 | 10 | You may eventually want to have multiple stages of your application. A 11 | common configuration would be to have a ``dev``, ``beta`` and ``prod`` 12 | stage. A ``dev`` stage would be used by developers to test out new 13 | features. Completed features would be deployed to ``beta``, and the 14 | ``prod`` stage would be used for serving production traffic. 15 | 16 | Chalice can help you manage this. 17 | 18 | To create a new chalice stage, specify the ``--stage`` argument. 19 | If the stage does not exist yet, it will be created for you:: 20 | 21 | $ chalice deploy --stage prod 22 | 23 | By creating a new chalice stage, a new API Gateway rest API, Lambda 24 | function, and potentially (depending on config settings) a new IAM role 25 | will be created for you. 26 | 27 | 28 | Example 29 | ------- 30 | 31 | Let's say we have a new app:: 32 | 33 | $ chalice new-project myapp 34 | $ cd myapp 35 | $ chalice deploy 36 | ... 37 | https://mmnkdi.execute-api.us-west-2.amazonaws.com/api/ 38 | 39 | We've just created our first stage, ``dev``. We can iterate on our 40 | application and continue to run ``chalice deploy`` to deploy our code 41 | to the ``dev`` stage. Let's say we want to now create a ``prod`` stage. 42 | To do this, we can run:: 43 | 44 | $ chalice deploy --stage prod 45 | ... 46 | https://wk9fhx.execute-api.us-west-2.amazonaws.com/api/ 47 | 48 | We now have two completely separate rest APIs:: 49 | 50 | $ chalice url --stage dev 51 | https://mmnkdi.execute-api.us-west-2.amazonaws.com/api/ 52 | 53 | $ chalice url --stage prod 54 | https://wk9fhx.execute-api.us-west-2.amazonaws.com/api/ 55 | 56 | Additionally, we can see all our deployed values by looking 57 | at the ``.chalice/deployed/dev.json`` or ``.chalice/deployed/prod.json`` files:: 58 | 59 | $ cat .chalice/deployed/dev.json 60 | { 61 | "resources": [ 62 | { 63 | "name": "api_handler", 64 | "resource_type": "lambda_function", 65 | "lambda_arn": "arn:aws:lambda:...:function:myapp-dev" 66 | }, 67 | { 68 | "name": "rest_api", 69 | "resource_type": "rest_api", 70 | "rest_api_id": "wk9fhx", 71 | "rest_api_url": "https://wk9fhx.execute-api.us-west-2.amazonaws.com/api/" 72 | } 73 | ], 74 | "schema_version": "2.0", 75 | "backend": "api" 76 | } 77 | 78 | $ cat .chalice/deployed/prod.json 79 | { 80 | "resources": [ 81 | { 82 | "name": "api_handler", 83 | "resource_type": "lambda_function", 84 | "lambda_arn": "arn:aws:lambda:...:function:myapp-prod" 85 | }, 86 | { 87 | "name": "rest_api", 88 | "resource_type": "rest_api", 89 | "rest_api_id": "mmnkdi", 90 | "rest_api_url": "https://mmnkdi.execute-api.us-west-2.amazonaws.com/api/" 91 | } 92 | ], 93 | "schema_version": "2.0", 94 | "backend": "api" 95 | } 96 | -------------------------------------------------------------------------------- /docs/source/tutorials/index.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ========= 3 | 4 | These step-by-step tutorials show you how to use various features of Chalice. 5 | These are perfect if you're new to Chalice and want to learn what Chalice can 6 | do. If you want more complete, real-world examples, you can check out 7 | our :doc:`../samples/index`. 8 | 9 | Rest API Tutorials 10 | ------------------ 11 | 12 | :doc:`basicrestapi` 13 | This tutorial walks you through creating a REST API in 14 | Chalice. It covers features such as routing, URL parameters, error handling, 15 | etc. 16 | :doc:`customdomain` 17 | In this tutorial, we show you how to configure 18 | a REST API with your own custom domain name. 19 | 20 | 21 | .. _websocket-tutorial: 22 | 23 | Websocket Tutorials 24 | ------------------- 25 | 26 | 27 | :doc:`wsecho` 28 | Learn the basics of creating websocket APIs in Chalice. This tutorial 29 | creates an echo server that echoes back any message that the client sends to 30 | the websocket server. 31 | :doc:`wschat` 32 | In this more complete example, learn how to create a basic chat application 33 | based on websockets. 34 | 35 | 36 | Event Source Tutorials 37 | ---------------------- 38 | 39 | 40 | :doc:`events` 41 | This tutorial shows you how to create an event handler 42 | that's triggered whenever a message is published to an SNS topic. 43 | 44 | .. toctree:: 45 | :hidden: 46 | :glob: 47 | 48 | * 49 | 50 | AWS CDK Tutorials 51 | ----------------- 52 | 53 | :doc:`cdk` 54 | This tutorial walks you through creating a REST API with a DynamoDB data 55 | store that's deployed using the AWS CDK. It shows you how you can combine 56 | the APIs of Chalice with CDK construct APIs 57 | -------------------------------------------------------------------------------- /requirements-dev.in: -------------------------------------------------------------------------------- 1 | -r requirements-test.in 2 | pylint<4.0.0 3 | doc8<1.0.0 4 | pydocstyle 5 | flake8 6 | Sphinx==4.3.2 7 | docutils 8 | mypy 9 | wheel 10 | pygments 11 | types-six 12 | types-python-dateutil 13 | types-PyYAML 14 | standard-imghdr -------------------------------------------------------------------------------- /requirements-test.in: -------------------------------------------------------------------------------- 1 | pytest 2 | boto3<2.0.0 3 | hypothesis 4 | coverage 5 | websocket-client<2.0.0 6 | pytest-cov 7 | requests 8 | -------------------------------------------------------------------------------- /requirements-test.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile with Python 3.9 3 | # by the following command: 4 | # 5 | # pip-compile --output-file=requirements-test.txt requirements-test.in 6 | # 7 | attrs==23.1.0 8 | # via hypothesis 9 | boto3==1.33.13 10 | # via -r requirements-test.in 11 | botocore==1.33.13 12 | # via 13 | # boto3 14 | # s3transfer 15 | certifi==2023.11.17 16 | # via requests 17 | charset-normalizer==3.3.2 18 | # via requests 19 | coverage[toml]==7.2.7 20 | # via 21 | # -r requirements-test.in 22 | # pytest-cov 23 | exceptiongroup==1.2.0 24 | # via 25 | # hypothesis 26 | # pytest 27 | hypothesis==6.79.4 28 | # via -r requirements-test.in 29 | idna==3.6 30 | # via requests 31 | iniconfig==2.0.0 32 | # via pytest 33 | jmespath==1.0.1 34 | # via 35 | # boto3 36 | # botocore 37 | packaging==23.2 38 | # via pytest 39 | pluggy==1.2.0 40 | # via pytest 41 | pytest==7.4.3 42 | # via 43 | # -r requirements-test.in 44 | # pytest-cov 45 | pytest-cov==4.1.0 46 | # via -r requirements-test.in 47 | python-dateutil==2.8.2 48 | # via botocore 49 | requests==2.31.0 50 | # via -r requirements-test.in 51 | s3transfer==0.8.2 52 | # via boto3 53 | six==1.16.0 54 | # via python-dateutil 55 | sortedcontainers==2.4.0 56 | # via hypothesis 57 | tomli==2.0.1 58 | # via 59 | # coverage 60 | # pytest 61 | urllib3==1.26.18 62 | # via 63 | # botocore 64 | # requests 65 | websocket-client==1.6.1 66 | # via -r requirements-test.in 67 | -------------------------------------------------------------------------------- /scripts/gh-page-docs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run this from the rootdir of the repository: 3 | # 4 | # ./scripts/gh-page-docs 5 | # 6 | # This script will check the docs for errors, render them 7 | # to html, then copy them over to a local (separate) checkout 8 | # of this repo's gh-pages branch. 9 | # Do not run this with a virtualenv activated. This is intended 10 | # to be run in CI systems where you start with system python. 11 | set -e 12 | 13 | CHECKOUT_DIR="/tmp/chalice-gh-doc-build" 14 | VENV_DIR="/tmp/chalice-gh-doc-build-venv37" 15 | 16 | 17 | echo "Setting up environment" 18 | python3 -m venv $VENV_DIR 19 | source "${VENV_DIR}/bin/activate" 20 | echo 21 | echo 22 | which python3 23 | python3 -c "import sys; print(sys.executable)" 24 | which pip3 25 | echo 26 | echo 27 | python3 -m pip install -e . 28 | python3 -m pip install -r requirements-dev.txt 29 | 30 | 31 | # Don't allow docs to be deployed if there's any errors. 32 | echo "Linting docs and checking for errors" 33 | make doccheck 34 | 35 | echo "Building docs" 36 | cd docs 37 | make clean && make html 38 | 39 | echo 40 | echo "Copy docs to local checkout" 41 | rm -rf "${CHECKOUT_DIR}" 42 | git clone https://github.com/aws/chalice.git --branch gh-pages \ 43 | --single-branch ${CHECKOUT_DIR} 44 | rsync -av --delete --exclude '.git' build/html/ ${CHECKOUT_DIR}/ 45 | # Add a .nojekyll file so make sure we don't ignore _static 46 | # paths. 47 | touch ${CHECKOUT_DIR}/.nojekyll 48 | 49 | echo "Commiting docs." 50 | cd ${CHECKOUT_DIR} 51 | git add -A . 52 | git commit -am "Updating generated documentation" 53 | git remote add upstream git@github.com:aws/chalice.git 54 | echo "Docs are available at ${CHECKOUT_DIR}" 55 | # This step is usually handled by the CI system that has access 56 | # to the creds needed to push back to github. 57 | echo "Run 'git push upstream gh-pages' to deploy the docs to github pages" 58 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [mypy] 2 | 3 | [mypy-chalice.vendored.*] 4 | ignore_errors = true 5 | 6 | [mypy-chalice.templates.*] 7 | ignore_errors = true 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from setuptools import setup, find_packages 4 | 5 | 6 | with open('README.rst') as readme_file: 7 | README = readme_file.read() 8 | 9 | 10 | def recursive_include(relative_dir): 11 | all_paths = [] 12 | root_prefix = os.path.join( 13 | os.path.dirname(os.path.abspath(__file__)), 'chalice') 14 | full_path = os.path.join(root_prefix, relative_dir) 15 | for rootdir, _, filenames in os.walk(full_path): 16 | for filename in filenames: 17 | abs_filename = os.path.join(rootdir, filename) 18 | all_paths.append(abs_filename[len(root_prefix) + 1:]) 19 | return all_paths 20 | 21 | 22 | install_requires = [ 23 | 'click>=7,<9.0', 24 | 'botocore>=1.14.0,<2.0.0', 25 | 'six>=1.10.0,<2.0.0', 26 | 'pip>=9,<25.1', 27 | 'jmespath>=0.9.3,<2.0.0', 28 | 'pyyaml>=5.3.1,<7.0.0', 29 | 'inquirer>=3.0.0,<4.0.0', 30 | 'wheel', 31 | 'setuptools' 32 | ] 33 | 34 | setup( 35 | name='chalice', 36 | version='1.32.0', 37 | description="Microframework", 38 | long_description=README, 39 | author="James Saryerwinnie", 40 | author_email='js@jamesls.com', 41 | url='https://github.com/aws/chalice', 42 | packages=find_packages(exclude=['tests', 'tests.*']), 43 | install_requires=install_requires, 44 | extras_require={ 45 | 'event-file-poller': ['watchdog==2.3.1'], 46 | 'cdk': [ 47 | 'aws_cdk.aws_iam>=1.85.0,<2.0', 48 | 'aws_cdk.aws-s3-assets>=1.85.0,<2.0', 49 | 'aws_cdk.cloudformation-include>=1.85.0,<2.0', 50 | 'aws_cdk.core>=1.85.0,<2.0', 51 | ], 52 | 'cdkv2': ["aws-cdk-lib>2.0,<3.0"] 53 | }, 54 | license="Apache License 2.0", 55 | package_data={'chalice': [ 56 | '*.json', '*.pyi', 'py.typed'] + recursive_include('templates')}, 57 | include_package_data=True, 58 | zip_safe=False, 59 | keywords='chalice', 60 | entry_points={ 61 | 'console_scripts': [ 62 | 'chalice = chalice.cli:main', 63 | ] 64 | }, 65 | classifiers=[ 66 | 'Development Status :: 5 - Production/Stable', 67 | 'Intended Audience :: Developers', 68 | 'License :: OSI Approved :: Apache Software License', 69 | 'Natural Language :: English', 70 | "Programming Language :: Python :: 3", 71 | 'Programming Language :: Python :: 3.9', 72 | 'Programming Language :: Python :: 3.10', 73 | 'Programming Language :: Python :: 3.11', 74 | 'Programming Language :: Python :: 3.12', 75 | 'Programming Language :: Python :: 3.13', 76 | ], 77 | ) 78 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/__init__.py -------------------------------------------------------------------------------- /tests/aws/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/aws/__init__.py -------------------------------------------------------------------------------- /tests/aws/conftest.py: -------------------------------------------------------------------------------- 1 | DEPLOY_TEST_BASENAME = 'test_features.py' 2 | 3 | 4 | def pytest_collection_modifyitems(session, config, items): 5 | # Ensure that all tests with require a redeploy are run after 6 | # tests that don't need a redeploy. 7 | start, end = _get_start_end_index(DEPLOY_TEST_BASENAME, items) 8 | marked = [] 9 | unmarked = [] 10 | for item in items[start:end]: 11 | if item.get_closest_marker('on_redeploy') is not None: 12 | marked.append(item) 13 | else: 14 | unmarked.append(item) 15 | items[start:end] = unmarked + marked 16 | 17 | 18 | def _get_start_end_index(basename, items): 19 | # precondition: all the tests for test_features.py are 20 | # in a contiguous range. This is the case because pytest 21 | # will group all tests in a module together. 22 | matched = [item.fspath.basename == basename for item in items] 23 | if not any(matched): 24 | return 0, len(items) 25 | return ( 26 | matched.index(True), 27 | len(matched) - list(reversed(matched)).index(True) 28 | ) 29 | -------------------------------------------------------------------------------- /tests/aws/testapp/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stages": { 3 | "dev": { 4 | "api_gateway_stage": "api", 5 | "environment_variables": { 6 | "APP_NAME": "replaceme" 7 | } 8 | } 9 | }, 10 | "version": "2.0", 11 | "app_name": "replaceme" 12 | } 13 | -------------------------------------------------------------------------------- /tests/aws/testapp/app-redeploy.py: -------------------------------------------------------------------------------- 1 | """Test app redeploy. 2 | 3 | This file is copied over to app.py during the integration 4 | tests to test behavior on redeploys. 5 | 6 | """ 7 | import os 8 | 9 | from chalice import Chalice 10 | 11 | 12 | app = Chalice(app_name=os.environ['APP_NAME']) 13 | 14 | 15 | # Test an unchanged view, this is the exact 16 | # version from app.py 17 | @app.route('/') 18 | def index(): 19 | return {'hello': 'world'} 20 | 21 | 22 | # Test same route info but changed view code. 23 | @app.route('/a/b/c/d/e/f/g') 24 | def nested_route(): 25 | return {'redeployed': True} 26 | 27 | 28 | # Test route deletion. This view is in the original 29 | # app.py but is now deleted. 30 | # @app.route('/path/{name}') 31 | # def supports_path_params(name): 32 | # return {'path': name} 33 | 34 | # Test route modification with the same view code. 35 | # The original version had methods=['GET', 'POST'] 36 | @app.route('/multimethod', methods=['GET', 'PUT']) 37 | def multiple_methods(): 38 | return {'method': app.current_request.method} 39 | 40 | 41 | # Test new view function added that wasn't in the original 42 | # app.py file. 43 | @app.route('/redeploy') 44 | def redeploy(): 45 | return {'success': True} 46 | -------------------------------------------------------------------------------- /tests/aws/testapp/chalicelib/__init__.py: -------------------------------------------------------------------------------- 1 | MESSAGE = "success" 2 | -------------------------------------------------------------------------------- /tests/aws/testapp/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.38.15 2 | -------------------------------------------------------------------------------- /tests/aws/testwebsocketapp/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "testwebsocketapp", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api", 7 | "environment_variables": {} 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/aws/testwebsocketapp/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /tests/aws/testwebsocketapp/app-redeploy.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import boto3 4 | from chalice import Chalice 5 | 6 | app = Chalice(app_name=os.environ['APP_NAME']) 7 | app.websocket_api.session = boto3.session.Session() 8 | app.experimental_feature_flags.update([ 9 | 'WEBSOCKETS' 10 | ]) 11 | ddb = boto3.client('dynamodb') 12 | 13 | 14 | # This comment is to cause a change which triggers a redeployment 15 | # of the Lambda Function, this is needed to properly test redeployment. 16 | @app.on_ws_message() 17 | def message(event): 18 | ddb.put_item( 19 | TableName=os.environ['APP_NAME'], 20 | Item={ 21 | 'entry': { 22 | 'N': event.body 23 | }, 24 | }, 25 | ) 26 | -------------------------------------------------------------------------------- /tests/aws/testwebsocketapp/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import boto3 4 | from chalice import Chalice 5 | 6 | app = Chalice(app_name=os.environ['APP_NAME']) 7 | app.websocket_api.session = boto3.session.Session() 8 | app.experimental_feature_flags.update([ 9 | 'WEBSOCKETS' 10 | ]) 11 | ddb = boto3.client('dynamodb') 12 | 13 | 14 | @app.on_ws_message() 15 | def message(event): 16 | try: 17 | ddb.put_item( 18 | TableName=os.environ['APP_NAME'], 19 | Item={ 20 | 'entry': { 21 | 'N': event.body 22 | }, 23 | }, 24 | ) 25 | except Exception as e: 26 | # If we get an exception, we need to log it somehow. We can't 27 | # return this back to the user so we'll add something to the ddb 28 | # table to denote that we failed. 29 | ddb.put_item( 30 | TableName=os.environ['APP_NAME'], 31 | Item={ 32 | 'entry': { 33 | 'N': "-9999" 34 | }, 35 | 'errormsg': { 36 | 'S': '%s: %s,\noriginal event: %s' % ( 37 | e.__class__, e, event.to_dict()) 38 | } 39 | } 40 | ) 41 | -------------------------------------------------------------------------------- /tests/aws/testwebsocketapp/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.38.15 2 | -------------------------------------------------------------------------------- /tests/functional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/__init__.py -------------------------------------------------------------------------------- /tests/functional/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/api/__init__.py -------------------------------------------------------------------------------- /tests/functional/api/test_package.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | import pytest 5 | from click.testing import CliRunner 6 | 7 | from chalice.cli import newproj 8 | from chalice.api import package_app 9 | 10 | 11 | @pytest.fixture 12 | def runner(): 13 | return CliRunner() 14 | 15 | 16 | @pytest.mark.parametrize('package_format,template_format,expected_filename', [ 17 | ('cloudformation', 'json', 'sam.json'), 18 | ('cloudformation', 'yaml', 'sam.yaml'), 19 | ('terraform', 'json', 'chalice.tf.json'), 20 | ]) 21 | def test_can_package_different_formats(runner, package_format, 22 | template_format, 23 | expected_filename): 24 | with runner.isolated_filesystem(): 25 | newproj.create_new_project_skeleton('testproject') 26 | package_app('testproject', output_dir='packagedir', stage='dev', 27 | package_format=package_format, 28 | template_format=template_format) 29 | app_contents = os.listdir('packagedir') 30 | assert expected_filename in app_contents 31 | assert 'deployment.zip' in app_contents 32 | 33 | 34 | def test_can_override_chalice_config(runner): 35 | with runner.isolated_filesystem(): 36 | newproj.create_new_project_skeleton('testproject') 37 | chalice_config = { 38 | 'environment_variables': { 39 | 'FOO': 'BAR', 40 | } 41 | } 42 | package_app('testproject', output_dir='packagedir', stage='dev', 43 | chalice_config=chalice_config) 44 | app_contents = os.listdir('packagedir') 45 | assert 'sam.json' in app_contents 46 | with open(os.path.join('packagedir', 'sam.json')) as f: 47 | data = json.loads(f.read()) 48 | properties = data['Resources']['APIHandler']['Properties'] 49 | assert properties['Environment'] == { 50 | 'Variables': { 51 | 'FOO': 'BAR', 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/functional/basicapp/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "app_name": "basicapp", 4 | "stages": { 5 | "dev": { 6 | "api_gateway_stage": "api" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/functional/basicapp/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /tests/functional/basicapp/app.py: -------------------------------------------------------------------------------- 1 | from chalice import Chalice 2 | 3 | app = Chalice(app_name='basicapp') 4 | 5 | 6 | @app.route('/') 7 | def index(): 8 | return {'version': 'original'} 9 | -------------------------------------------------------------------------------- /tests/functional/basicapp/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/basicapp/requirements.txt -------------------------------------------------------------------------------- /tests/functional/cdk/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/cdk/__init__.py -------------------------------------------------------------------------------- /tests/functional/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/cli/__init__.py -------------------------------------------------------------------------------- /tests/functional/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest import fixture 2 | 3 | 4 | @fixture(autouse=True) 5 | def ensure_no_local_config(no_local_config): 6 | pass 7 | -------------------------------------------------------------------------------- /tests/functional/envapp/.chalice/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stages": { 3 | "dev": { 4 | "api_gateway_stage": "api", 5 | "environment_variables": {"FOO": "bar"} 6 | } 7 | }, 8 | "version": "2.0", 9 | "app_name": "env" 10 | } 11 | -------------------------------------------------------------------------------- /tests/functional/envapp/.gitignore: -------------------------------------------------------------------------------- 1 | .chalice/deployments/ 2 | .chalice/venv/ 3 | -------------------------------------------------------------------------------- /tests/functional/envapp/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from chalice import Chalice 4 | 5 | app = Chalice(app_name='env') 6 | 7 | try: 8 | foo = os.environ['FOO'] 9 | except KeyError: 10 | raise AssertionError("Env vars were not loaded at import time.") 11 | 12 | 13 | @app.route('/') 14 | def index(): 15 | return {'hello': foo} 16 | 17 | 18 | sys.stderr.write("READY") 19 | sys.stderr.flush() 20 | -------------------------------------------------------------------------------- /tests/functional/envapp/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/functional/envapp/requirements.txt -------------------------------------------------------------------------------- /tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/integration/__init__.py -------------------------------------------------------------------------------- /tests/integration/conftest.py: -------------------------------------------------------------------------------- 1 | from pytest import fixture 2 | 3 | 4 | @fixture(autouse=True) 5 | def ensure_no_local_config(no_local_config): 6 | pass 7 | -------------------------------------------------------------------------------- /tests/integration/test_cli.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | 4 | import pytest 5 | from chalice.utils import OSUtils 6 | 7 | CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) 8 | PROJECT_DIR = os.path.join( 9 | os.path.dirname(CURRENT_DIR), 10 | 'aws', 11 | 'testapp', 12 | ) 13 | 14 | 15 | @pytest.fixture 16 | def local_app(tmpdir): 17 | temp_dir_path = str(tmpdir) 18 | OSUtils().copytree(PROJECT_DIR, temp_dir_path) 19 | old_dir = os.getcwd() 20 | try: 21 | os.chdir(temp_dir_path) 22 | yield temp_dir_path 23 | finally: 24 | os.chdir(old_dir) 25 | 26 | 27 | def test_stack_trace_printed_on_error(local_app): 28 | app_file = os.path.join(local_app, 'app.py') 29 | with open(app_file, 'w') as f: 30 | f.write( 31 | 'from chalice import Chalice\n' 32 | 'app = Chalice(app_name="test")\n' 33 | 'foobarbaz\n' 34 | ) 35 | p = subprocess.Popen(['chalice', 'local', '--no-autoreload'], 36 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 37 | stderr = p.communicate()[1].decode('ascii') 38 | rc = p.returncode 39 | 40 | assert rc == 2 41 | assert 'Traceback' in stderr 42 | assert 'foobarbaz' in stderr 43 | -------------------------------------------------------------------------------- /tests/plugins/codelinter.py: -------------------------------------------------------------------------------- 1 | # These are linting checks used in the chalice codebase itself. 2 | # These are used to enforce specific coding standards and constraints. 3 | from pylint.checkers import BaseChecker 4 | from astroid.exceptions import InferenceError 5 | import astroid 6 | 7 | 8 | def register(linter): 9 | linter.register_checker(ConditionalImports(linter)) 10 | 11 | 12 | class ConditionalImports(BaseChecker): 13 | # This is used to ensure that any imports that rely on conditional 14 | # dependencies must be wrapped in a try/except ImportError. 15 | name = 'must-catch-import-error' 16 | msgs = { 17 | 'C9997': ('Importing this module must catch ImportError.', 18 | 'must-catch-import-error', 19 | 'Importing this module must catch ImportError.'), 20 | } 21 | 22 | def visit_import(self, node): 23 | names = [name[0] for name in node.names] 24 | if 'chalice.cli.filewatch.eventbased' in names: 25 | if not self._is_in_try_except_import_error(node): 26 | self.add_message('must-catch-import-error', node=node) 27 | return 28 | 29 | def visit_importfrom(self, node): 30 | if node.modname == 'chalice.cli.filewatch.eventbased': 31 | names = [name[0] for name in node.names] 32 | if 'WatchdogWorkerProcess' in names: 33 | # Ensure this is wrapped in a try/except. 34 | # Technically we should ensure anywhere in the call stack 35 | # we're wrapped in a try/except, but in practice we'll just 36 | # enforce you did that in the same scope as your import. 37 | if not self._is_in_try_except_import_error(node): 38 | self.add_message('must-catch-import-error', node=node) 39 | return 40 | 41 | def _is_in_try_except_import_error(self, node): 42 | if not isinstance(node.parent, astroid.Try): 43 | return False 44 | caught_exceptions = [ 45 | handler.type.name for handler in node.parent.handlers] 46 | if 'ImportError' not in caught_exceptions: 47 | # They wrapped a try/except but aren't catching 48 | # ImportError. 49 | return False 50 | return True 51 | -------------------------------------------------------------------------------- /tests/plugins/testlinter.py: -------------------------------------------------------------------------------- 1 | from pylint.checkers import BaseChecker 2 | from astroid.exceptions import InferenceError 3 | 4 | 5 | def register(linter): 6 | linter.register_checker(PatchChecker(linter)) 7 | linter.register_checker(MocksUseSpecArg(linter)) 8 | 9 | 10 | class PatchChecker(BaseChecker): 11 | name = 'patching-banned' 12 | msgs = { 13 | 'C9999': ('Use of mock.patch is not allowed', 14 | 'patch-call', 15 | 'Use of mock.patch not allowed') 16 | } 17 | patch_pytype = 'unittest.mock._patch' 18 | 19 | def visit_call(self, node): 20 | try: 21 | for inferred_type in node.infer(): 22 | if inferred_type.pytype() == self.patch_pytype: 23 | self.add_message('patch-call', node=node) 24 | except InferenceError: 25 | # It's ok if we can't work out what type the function 26 | # call is. 27 | pass 28 | 29 | 30 | class MocksUseSpecArg(BaseChecker): 31 | 32 | name = 'mocks-use-spec' 33 | msgs = { 34 | 'C9998': ('mock.Mock() must provide "spec=" argument', 35 | 'mock-missing-spec', 36 | 'mock.Mock() must provide "spec=" argument') 37 | } 38 | mock_pytype = 'unittest.mock.Mock' 39 | required_kwarg = 'spec' 40 | 41 | def visit_call(self, node): 42 | try: 43 | for inferred_type in node.infer(): 44 | if inferred_type.pytype() == self.mock_pytype: 45 | self._verify_spec_arg_provided(node) 46 | except InferenceError: 47 | pass 48 | 49 | def _verify_spec_arg_provided(self, node): 50 | if not node.keywords: 51 | self.add_message('mock-missing-spec', node=node) 52 | return 53 | kwargs = [kwarg.arg for kwarg in node.keywords] 54 | if self.required_kwarg not in kwargs: 55 | self.add_message('mock-missing-spec', node=node) 56 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/unit/__init__.py -------------------------------------------------------------------------------- /tests/unit/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/unit/cli/__init__.py -------------------------------------------------------------------------------- /tests/unit/cli/filewatch/test_stat.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | from chalice.cli.filewatch import stat 5 | 6 | 7 | class FakeOSUtils(object): 8 | def __init__(self): 9 | self.initial_scan = True 10 | 11 | def walk(self, rootdir): 12 | yield 'rootdir', [], ['bad-file', 'baz'] 13 | if self.initial_scan: 14 | self.initial_scan = False 15 | 16 | def joinpath(self, *parts): 17 | return os.path.join(*parts) 18 | 19 | def mtime(self, path): 20 | if self.initial_scan: 21 | return 1 22 | if path.endswith('bad-file'): 23 | raise OSError("Bad file") 24 | return 2 25 | 26 | 27 | def test_can_ignore_stat_errors(): 28 | calls = [] 29 | 30 | def callback(*args, **kwargs): 31 | calls.append((args, kwargs)) 32 | 33 | watcher = stat.StatFileWatcher(FakeOSUtils()) 34 | watcher.watch_for_file_changes('rootdir', callback) 35 | for _ in range(10): 36 | if len(calls) == 1: 37 | break 38 | time.sleep(0.2) 39 | else: 40 | raise AssertionError("Expected callback to be invoked but was not.") 41 | -------------------------------------------------------------------------------- /tests/unit/cli/test_cli.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | import pytest 3 | import re 4 | 5 | from chalice import cli 6 | from chalice.cli.factory import CLIFactory 7 | from chalice.local import LocalDevServer 8 | 9 | 10 | def test_cannot_run_local_mode_with_trailing_slash_route(): 11 | local_stage_test = 'local_test' 12 | factory = mock.Mock(spec=CLIFactory) 13 | factory.create_config_obj.return_value.environment_variables = {} 14 | factory.create_config_obj.return_value.chalice_app.routes = { 15 | 'foobar/': None 16 | } 17 | local_server = mock.Mock(spec=LocalDevServer) 18 | factory.create_local_server.return_value = local_server 19 | with pytest.raises(ValueError) as e: 20 | cli.run_local_server(factory, 'localhost', 8000, local_stage_test) 21 | assert str(e.value) == 'Route cannot end with a trailing slash: foobar/' 22 | 23 | 24 | def test_get_system_info(): 25 | system_info = cli.get_system_info() 26 | assert re.match(r'python\s*([\d.]+),?\s*(.*) (.*)', system_info) 27 | -------------------------------------------------------------------------------- /tests/unit/cli/test_newproj.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pytest 4 | 5 | from chalice.cli import newproj 6 | 7 | 8 | class InMemoryOSUtils(object): 9 | def __init__(self, filemap=None): 10 | if filemap is None: 11 | filemap = {} 12 | self.filemap = filemap 13 | self.walk_return_val = None 14 | 15 | def dirname(self, name): 16 | return os.path.dirname(name) 17 | 18 | def get_directory_contents(self, dirname): 19 | full_paths = [f for f in self.filemap if f.startswith(dirname)] 20 | return [p.split(os.sep)[1] for p in full_paths] 21 | 22 | def file_exists(self, filename): 23 | return filename in self.filemap 24 | 25 | def joinpath(self, *args): 26 | return os.path.join(*args) 27 | 28 | def walk(self, root_dir): 29 | return self.walk_return_value 30 | 31 | def directory_exists(self, dirname): 32 | return True 33 | 34 | def get_file_contents(self, filename, binary=True): 35 | return self.filemap[filename] 36 | 37 | def set_file_contents(self, filename, contents, binary=True): 38 | self.filemap[filename] = contents 39 | 40 | 41 | @pytest.mark.parametrize( 42 | 'contents,template_kwargs,expected', [ 43 | ('{{myvar}}', {'myvar': 'foo'}, 'foo'), 44 | ('{{myvar}}', {'myvar': 'foo', 'myvar2': 'bar'}, 'foo'), 45 | ('before {{myvar}} after', {'myvar': 'foo'}, 'before foo after'), 46 | ('newlines\n{{myvar}}\nbar', {'myvar': 'foo'}, 'newlines\nfoo\nbar'), 47 | ('NAME = "{{myvar}}"', {'myvar': 'foo'}, 'NAME = "foo"'), 48 | ('{{one}}{{two}}', {'one': 'foo', 'two': 'bar'}, 'foobar'), 49 | ('{nomatch}', {'nomatch': 'bar'}, '{nomatch}'), 50 | ('no template', {'nomatch': 'bar'}, 'no template'), 51 | ('', {}, ''), 52 | ('{{noclose', {}, '{{noclose'), 53 | ('nostart}}', {}, 'nostart}}'), 54 | ('{{unknown_var}}', {}, newproj.BadTemplateError()), 55 | ] 56 | ) 57 | def test_can_get_templated_content(contents, template_kwargs, expected): 58 | if isinstance(expected, Exception): 59 | with pytest.raises(expected.__class__): 60 | newproj.get_templated_content(contents, template_kwargs) 61 | else: 62 | newproj.get_templated_content(contents, template_kwargs) == expected 63 | 64 | 65 | def test_newproj_copies_and_templates_files(): 66 | fake_osutils = InMemoryOSUtils() 67 | fake_osutils.walk_return_value = [ 68 | ('source_dir', [], ['foo', 'bar']), 69 | ] 70 | fake_osutils.filemap = { 71 | os.path.join('source_dir', 'foo'): 'hello', 72 | os.path.join('source_dir', 'bar'): '{{who}}', 73 | } 74 | creator = newproj.ProjectCreator(fake_osutils) 75 | creator.create_new_project('source_dir', 'dest_dir', {'who': 'world'}) 76 | assert fake_osutils.filemap[os.path.join('dest_dir', 'foo')] == 'hello' 77 | assert fake_osutils.filemap[os.path.join('dest_dir', 'bar')] == 'world' 78 | 79 | 80 | def test_can_list_available_projects(): 81 | fake_osutils = InMemoryOSUtils() 82 | join = os.path.join 83 | first_dir = join('template-dir', '0001-first-proj') 84 | second_dir = join('template-dir', '0002-second-proj') 85 | fake_osutils.filemap = { 86 | join(first_dir, 'metadata.json'): '{"description": "First template"}', 87 | join(second_dir, 'metadata.json'): '{"description": "Second"}', 88 | 89 | } 90 | results = newproj.list_available_projects('template-dir', fake_osutils) 91 | assert results == [ 92 | newproj.ProjectTemplate( 93 | dirname='0001-first-proj', 94 | metadata={'description': 'First template'}, 95 | key='first-proj', 96 | ), 97 | newproj.ProjectTemplate( 98 | dirname='0002-second-proj', 99 | metadata={'description': 'Second'}, 100 | key='second-proj', 101 | ), 102 | ] 103 | -------------------------------------------------------------------------------- /tests/unit/deploy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/unit/deploy/__init__.py -------------------------------------------------------------------------------- /tests/unit/deploy/test_models.py: -------------------------------------------------------------------------------- 1 | from dataclasses import replace 2 | 3 | from chalice.deploy import models 4 | 5 | 6 | def test_can_instantiate_empty_application(): 7 | app = models.Application(stage='dev', resources=[]) 8 | assert app.dependencies() == [] 9 | 10 | 11 | def test_can_instantiate_app_with_deps(): 12 | role = models.PreCreatedIAMRole(role_arn='foo') 13 | app = models.Application(stage='dev', resources=[role]) 14 | assert app.dependencies() == [role] 15 | 16 | 17 | def test_can_default_to_no_auths_in_rest_api(lambda_function): 18 | rest_api = models.RestAPI( 19 | resource_name='rest_api', 20 | swagger_doc={'swagger': '2.0'}, 21 | minimum_compression='', 22 | api_gateway_stage='api', 23 | endpoint_type='EDGE', 24 | lambda_function=lambda_function, 25 | xray=False 26 | ) 27 | assert rest_api.dependencies() == [lambda_function] 28 | 29 | 30 | def test_can_add_authorizers_to_dependencies(lambda_function): 31 | auth1 = replace(lambda_function, resource_name='auth1') 32 | auth2 = replace(lambda_function, resource_name='auth2') 33 | rest_api = models.RestAPI( 34 | resource_name='rest_api', 35 | swagger_doc={'swagger': '2.0'}, 36 | minimum_compression='', 37 | api_gateway_stage='api', 38 | endpoint_type='EDGE', 39 | lambda_function=lambda_function, 40 | xray=False, 41 | authorizers=[auth1, auth2], 42 | ) 43 | assert rest_api.dependencies() == [lambda_function, auth1, auth2] 44 | 45 | 46 | def test_can_add_connect_to_dependencies(lambda_function): 47 | api = models.WebsocketAPI( 48 | resource_name='websocket_api', 49 | name='name', 50 | api_gateway_stage='api', 51 | routes=['$connect'], 52 | connect_function=lambda_function, 53 | message_function=None, 54 | disconnect_function=None, 55 | ) 56 | assert api.dependencies() == [lambda_function] 57 | 58 | 59 | def test_can_add_message_to_dependencies(lambda_function): 60 | api = models.WebsocketAPI( 61 | resource_name='websocket_api', 62 | name='name', 63 | api_gateway_stage='api', 64 | routes=['$default'], 65 | connect_function=None, 66 | message_function=lambda_function, 67 | disconnect_function=None, 68 | ) 69 | assert api.dependencies() == [lambda_function] 70 | 71 | 72 | def test_can_add_disconnect_to_dependencies(lambda_function): 73 | api = models.WebsocketAPI( 74 | resource_name='websocket_api', 75 | name='name', 76 | api_gateway_stage='api', 77 | routes=['$disconnect'], 78 | connect_function=None, 79 | message_function=None, 80 | disconnect_function=lambda_function, 81 | ) 82 | assert api.dependencies() == [lambda_function] 83 | -------------------------------------------------------------------------------- /tests/unit/vendored/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/unit/vendored/__init__.py -------------------------------------------------------------------------------- /tests/unit/vendored/botocore/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws/chalice/a33863e29d249b4c04550659c2cc74bd1d54509a/tests/unit/vendored/botocore/__init__.py --------------------------------------------------------------------------------