wellapi 0.2.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wellapi-0.3.3/.github/workflows/build.pipeline.yml +31 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/.gitignore +3 -0
- wellapi-0.3.3/PKG-INFO +142 -0
- wellapi-0.3.3/README.md +125 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/pyproject.toml +8 -5
- wellapi-0.3.3/src/wellapi/__init__.py +10 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/applications.py +132 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/build/cdk.py +107 -16
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/build/packager.py +7 -3
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/cli/main.py +2 -1
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/router.py +2 -3
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/models.py +2 -2
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/models.py +11 -3
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/utils.py +86 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/params.py +32 -1
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/security.py +33 -0
- wellapi-0.3.3/uv.lock +359 -0
- wellapi-0.2.1/.idea/.gitignore +0 -8
- wellapi-0.2.1/.idea/inspectionProfiles/Project_Default.xml +0 -15
- wellapi-0.2.1/.idea/inspectionProfiles/profiles_settings.xml +0 -6
- wellapi-0.2.1/.idea/misc.xml +0 -7
- wellapi-0.2.1/.idea/modules.xml +0 -8
- wellapi-0.2.1/.idea/vcs.xml +0 -6
- wellapi-0.2.1/.idea/wellapi.iml +0 -11
- wellapi-0.2.1/.idea/workspace.xml +0 -170
- wellapi-0.2.1/PKG-INFO +0 -32
- wellapi-0.2.1/README.md +0 -17
- wellapi-0.2.1/handlers/other.py +0 -85
- wellapi-0.2.1/main.py +0 -19
- wellapi-0.2.1/openapi.json +0 -323
- wellapi-0.2.1/request.json +0 -129
- wellapi-0.2.1/src/wellapi/__init__.py +0 -5
- wellapi-0.2.1/src/wellapi/awsmodel.py +0 -17
- wellapi-0.2.1/src/wellapi/build/sam_openapi.py +0 -10
- wellapi-0.2.1/src/wellapi/openapi/__init__.py +0 -0
- wellapi-0.2.1/uv.lock +0 -1429
- {wellapi-0.2.1 → wellapi-0.3.3}/.python-version +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/__main__.py +0 -0
- {wellapi-0.2.1/handlers → wellapi-0.3.3/src/wellapi/build}/__init__.py +0 -0
- {wellapi-0.2.1/src/wellapi/build → wellapi-0.3.3/src/wellapi/cli}/__init__.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/convertors.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/datastructures.py +0 -0
- {wellapi-0.2.1/src/wellapi/cli → wellapi-0.3.3/src/wellapi/dependencies}/__init__.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/dependencies/models.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/dependencies/utils.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/exceptions.py +0 -0
- {wellapi-0.2.1/src/wellapi/dependencies → wellapi-0.3.3/src/wellapi/local}/__init__.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/reloader.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/server.py +0 -0
- {wellapi-0.2.1/src/wellapi/local → wellapi-0.3.3/src/wellapi/middleware}/__init__.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/base.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/error.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/exceptions.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/main.py +0 -0
- {wellapi-0.2.1/src/wellapi/middleware → wellapi-0.3.3/src/wellapi/openapi}/__init__.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/docs.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/routing.py +0 -0
- {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/utils.py +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Python package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
version: "0.6.14"
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
run: uv python install
|
|
23
|
+
|
|
24
|
+
- name: Install the project
|
|
25
|
+
run: uv sync --all-extras --dev
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: uv build
|
|
29
|
+
|
|
30
|
+
- name: Publish package
|
|
31
|
+
run: uv publish --trusted-publishing always
|
wellapi-0.3.3/PKG-INFO
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wellapi
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: A simple web framework for aws lambda
|
|
5
|
+
Author-email: romayuhym <romayuhym@gmail.com>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: email-validator>=2.0.0
|
|
8
|
+
Requires-Dist: pydantic==2.11.3
|
|
9
|
+
Requires-Dist: typing-extensions>=4.8.0
|
|
10
|
+
Provides-Extra: deploy
|
|
11
|
+
Requires-Dist: aws-cdk-lib>=2.189.1; extra == 'deploy'
|
|
12
|
+
Requires-Dist: constructs>=10.0.0; extra == 'deploy'
|
|
13
|
+
Provides-Extra: local
|
|
14
|
+
Requires-Dist: click>=8.1.8; extra == 'local'
|
|
15
|
+
Requires-Dist: watchdog>=4.0.2; extra == 'local'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# WellAPI
|
|
19
|
+
|
|
20
|
+
WellAPI is a simple web framework for work with AWS Lambda
|
|
21
|
+
and API Gateway. It is designed to be easy to use and flexible, allowing you to create RESTful APIs quickly and efficiently.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
- Simple and intuitive API for defining routes and handling requests
|
|
25
|
+
- Support for middleware functions
|
|
26
|
+
- Automatic request validation and error handling
|
|
27
|
+
- Support for CORS
|
|
28
|
+
- Support for query parameters, path parameters, and request bodies
|
|
29
|
+
- Support for error handling
|
|
30
|
+
- Support for AWS Lambda and API Gateway
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
You can install WellAPI using pip:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip instsll wellapi
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Example
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from wellapi import WellApi
|
|
44
|
+
|
|
45
|
+
app = WellApi()
|
|
46
|
+
|
|
47
|
+
@app.get("/hello")
|
|
48
|
+
def hello():
|
|
49
|
+
return {"message": "Hello, World!"}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Local development
|
|
53
|
+
|
|
54
|
+
You can run your WellAPI application locally using the `wellapi` command:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
wellapi run main:app
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## Deploy
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from wellapi.build.cdk import WellApiCDK
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class MyStack(Stack):
|
|
68
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
69
|
+
super().__init__(scope, id_, **kwargs)
|
|
70
|
+
|
|
71
|
+
app = WellApiCDK(
|
|
72
|
+
self,
|
|
73
|
+
"WellApiCDK",
|
|
74
|
+
app_srt="main:app",
|
|
75
|
+
handlers_dir="handlers",
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### CORS
|
|
80
|
+
You can enable CORS for your API by setting the `cors` parameter to `True` when creating the `WellApiCDK` instance:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from wellapi.build.cdk import WellApiCDK
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class MyStack(Stack):
|
|
87
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
88
|
+
super().__init__(scope, id_, **kwargs)
|
|
89
|
+
|
|
90
|
+
app = WellApiCDK(
|
|
91
|
+
self,
|
|
92
|
+
"WellApiCDK",
|
|
93
|
+
app_srt="main:app",
|
|
94
|
+
handlers_dir="handlers",
|
|
95
|
+
cors=True,
|
|
96
|
+
)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Cache
|
|
100
|
+
|
|
101
|
+
You can enable caching for your API by setting the `cache_enable` parameter to `True` when creating the `WellApiCDK` instance:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from wellapi.build.cdk import WellApiCDK
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class MyStack(Stack):
|
|
108
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
109
|
+
super().__init__(scope, id_, **kwargs)
|
|
110
|
+
|
|
111
|
+
app = WellApiCDK(
|
|
112
|
+
self,
|
|
113
|
+
"WellApiCDK",
|
|
114
|
+
app_srt="main:app",
|
|
115
|
+
handlers_dir="handlers",
|
|
116
|
+
cache_enable=True,
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
**!!! WARNING !!!**
|
|
120
|
+
|
|
121
|
+
Caching support only GET endpoints
|
|
122
|
+
|
|
123
|
+
### Logging
|
|
124
|
+
|
|
125
|
+
You can enable logging for your API by setting the `log_enable` parameter to `True` when creating the `WellApiCDK` instance:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from wellapi.build.cdk import WellApiCDK
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class MyStack(Stack):
|
|
132
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
133
|
+
super().__init__(scope, id_, **kwargs)
|
|
134
|
+
|
|
135
|
+
app = WellApiCDK(
|
|
136
|
+
self,
|
|
137
|
+
"WellApiCDK",
|
|
138
|
+
app_srt="main:app",
|
|
139
|
+
handlers_dir="handlers",
|
|
140
|
+
log_enable=True,
|
|
141
|
+
)
|
|
142
|
+
```
|
wellapi-0.3.3/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# WellAPI
|
|
2
|
+
|
|
3
|
+
WellAPI is a simple web framework for work with AWS Lambda
|
|
4
|
+
and API Gateway. It is designed to be easy to use and flexible, allowing you to create RESTful APIs quickly and efficiently.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
- Simple and intuitive API for defining routes and handling requests
|
|
8
|
+
- Support for middleware functions
|
|
9
|
+
- Automatic request validation and error handling
|
|
10
|
+
- Support for CORS
|
|
11
|
+
- Support for query parameters, path parameters, and request bodies
|
|
12
|
+
- Support for error handling
|
|
13
|
+
- Support for AWS Lambda and API Gateway
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
You can install WellAPI using pip:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip instsll wellapi
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from wellapi import WellApi
|
|
27
|
+
|
|
28
|
+
app = WellApi()
|
|
29
|
+
|
|
30
|
+
@app.get("/hello")
|
|
31
|
+
def hello():
|
|
32
|
+
return {"message": "Hello, World!"}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Local development
|
|
36
|
+
|
|
37
|
+
You can run your WellAPI application locally using the `wellapi` command:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
wellapi run main:app
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## Deploy
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from wellapi.build.cdk import WellApiCDK
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MyStack(Stack):
|
|
51
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
52
|
+
super().__init__(scope, id_, **kwargs)
|
|
53
|
+
|
|
54
|
+
app = WellApiCDK(
|
|
55
|
+
self,
|
|
56
|
+
"WellApiCDK",
|
|
57
|
+
app_srt="main:app",
|
|
58
|
+
handlers_dir="handlers",
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### CORS
|
|
63
|
+
You can enable CORS for your API by setting the `cors` parameter to `True` when creating the `WellApiCDK` instance:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from wellapi.build.cdk import WellApiCDK
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class MyStack(Stack):
|
|
70
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
71
|
+
super().__init__(scope, id_, **kwargs)
|
|
72
|
+
|
|
73
|
+
app = WellApiCDK(
|
|
74
|
+
self,
|
|
75
|
+
"WellApiCDK",
|
|
76
|
+
app_srt="main:app",
|
|
77
|
+
handlers_dir="handlers",
|
|
78
|
+
cors=True,
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Cache
|
|
83
|
+
|
|
84
|
+
You can enable caching for your API by setting the `cache_enable` parameter to `True` when creating the `WellApiCDK` instance:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from wellapi.build.cdk import WellApiCDK
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class MyStack(Stack):
|
|
91
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
92
|
+
super().__init__(scope, id_, **kwargs)
|
|
93
|
+
|
|
94
|
+
app = WellApiCDK(
|
|
95
|
+
self,
|
|
96
|
+
"WellApiCDK",
|
|
97
|
+
app_srt="main:app",
|
|
98
|
+
handlers_dir="handlers",
|
|
99
|
+
cache_enable=True,
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
**!!! WARNING !!!**
|
|
103
|
+
|
|
104
|
+
Caching support only GET endpoints
|
|
105
|
+
|
|
106
|
+
### Logging
|
|
107
|
+
|
|
108
|
+
You can enable logging for your API by setting the `log_enable` parameter to `True` when creating the `WellApiCDK` instance:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from wellapi.build.cdk import WellApiCDK
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class MyStack(Stack):
|
|
115
|
+
def __init__(self, scope: Construct, id_: str, **kwargs) -> None:
|
|
116
|
+
super().__init__(scope, id_, **kwargs)
|
|
117
|
+
|
|
118
|
+
app = WellApiCDK(
|
|
119
|
+
self,
|
|
120
|
+
"WellApiCDK",
|
|
121
|
+
app_srt="main:app",
|
|
122
|
+
handlers_dir="handlers",
|
|
123
|
+
log_enable=True,
|
|
124
|
+
)
|
|
125
|
+
```
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "wellapi"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.3.3"
|
|
4
|
+
description = "A simple web framework for aws lambda"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
7
|
-
{ name = "
|
|
7
|
+
{ name = "romayuhym", email = "romayuhym@gmail.com" }
|
|
8
8
|
]
|
|
9
9
|
requires-python = ">=3.12"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"pydantic==2.11.3",
|
|
12
12
|
"typing-extensions>=4.8.0",
|
|
13
13
|
"email-validator>=2.0.0",
|
|
14
|
-
"aws-cdk-lib>=2.189.1",
|
|
15
14
|
]
|
|
16
15
|
|
|
17
16
|
[project.scripts]
|
|
18
17
|
wellapi = "wellapi.cli.main:cli"
|
|
19
18
|
|
|
20
19
|
[project.optional-dependencies]
|
|
21
|
-
|
|
20
|
+
deploy = [
|
|
21
|
+
"aws-cdk-lib>=2.189.1",
|
|
22
|
+
"constructs>=10.0.0",
|
|
23
|
+
]
|
|
24
|
+
local = [
|
|
22
25
|
"click>=8.1.8",
|
|
23
26
|
"watchdog>=4.0.2",
|
|
24
27
|
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from wellapi.applications import WellApi as WellApi
|
|
2
|
+
from wellapi.params import Path as Path
|
|
3
|
+
from wellapi.params import Query as Query
|
|
4
|
+
from wellapi.params import Header as Header
|
|
5
|
+
from wellapi.params import Body as Body
|
|
6
|
+
from wellapi.params import Cache as Cache
|
|
7
|
+
from wellapi.models import RequestAPIGateway as RequestAPIGateway
|
|
8
|
+
from wellapi.models import ResponseAPIGateway as ResponseAPIGateway
|
|
9
|
+
from wellapi.security import OAuth2PasswordBearer as OAuth2PasswordBearer
|
|
10
|
+
from wellapi.security import APIKeyHeader as APIKeyHeader
|
|
@@ -55,6 +55,7 @@ class Lambda:
|
|
|
55
55
|
response_model: Any = Default(None),
|
|
56
56
|
status_code: int | None = None,
|
|
57
57
|
description: str | None = None,
|
|
58
|
+
cache_parameters: params.Cache | None = None,
|
|
58
59
|
response_description: str = "Successful Response",
|
|
59
60
|
responses: dict[int | str, dict[str, Any]] | None = None,
|
|
60
61
|
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
@@ -79,6 +80,7 @@ class Lambda:
|
|
|
79
80
|
self.timeout = timeout
|
|
80
81
|
self.method = method
|
|
81
82
|
self.endpoint = endpoint
|
|
83
|
+
self.cache_parameters = cache_parameters
|
|
82
84
|
self.path_regex, self.path_format, self.param_convertors = compile_path(path)
|
|
83
85
|
self.dependencies = list(dependencies or [])
|
|
84
86
|
self.operation_id = operation_id
|
|
@@ -271,6 +273,7 @@ class WellApi:
|
|
|
271
273
|
*,
|
|
272
274
|
response_model: Any = Default(None),
|
|
273
275
|
status_code: int | None = None,
|
|
276
|
+
cache_parameters: params.Cache | None = None,
|
|
274
277
|
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
275
278
|
ResponseAPIGateway
|
|
276
279
|
),
|
|
@@ -291,6 +294,7 @@ class WellApi:
|
|
|
291
294
|
response_model=response_model,
|
|
292
295
|
status_code=status_code,
|
|
293
296
|
method="GET",
|
|
297
|
+
cache_parameters=cache_parameters,
|
|
294
298
|
response_class=response_class,
|
|
295
299
|
response_model_include=response_model_include,
|
|
296
300
|
response_model_exclude=response_model_exclude,
|
|
@@ -311,6 +315,7 @@ class WellApi:
|
|
|
311
315
|
*,
|
|
312
316
|
response_model: Any = Default(None),
|
|
313
317
|
status_code: int | None = None,
|
|
318
|
+
cache_parameters: params.Cache | None = None,
|
|
314
319
|
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
315
320
|
ResponseAPIGateway
|
|
316
321
|
),
|
|
@@ -331,6 +336,133 @@ class WellApi:
|
|
|
331
336
|
response_model=response_model,
|
|
332
337
|
status_code=status_code,
|
|
333
338
|
method="POST",
|
|
339
|
+
cache_parameters=cache_parameters,
|
|
340
|
+
response_class=response_class,
|
|
341
|
+
response_model_include=response_model_include,
|
|
342
|
+
response_model_exclude=response_model_exclude,
|
|
343
|
+
response_model_by_alias=response_model_by_alias,
|
|
344
|
+
response_model_exclude_unset=response_model_exclude_unset,
|
|
345
|
+
response_model_exclude_defaults=response_model_exclude_defaults,
|
|
346
|
+
response_model_exclude_none=response_model_exclude_none,
|
|
347
|
+
dependencies=dependencies,
|
|
348
|
+
tags=tags,
|
|
349
|
+
)
|
|
350
|
+
return lambda_
|
|
351
|
+
|
|
352
|
+
return decorator
|
|
353
|
+
|
|
354
|
+
def put(
|
|
355
|
+
self,
|
|
356
|
+
path: str,
|
|
357
|
+
*,
|
|
358
|
+
response_model: Any = Default(None),
|
|
359
|
+
status_code: int | None = None,
|
|
360
|
+
cache_parameters: params.Cache | None = None,
|
|
361
|
+
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
362
|
+
ResponseAPIGateway
|
|
363
|
+
),
|
|
364
|
+
response_model_include: IncEx | None = None,
|
|
365
|
+
response_model_exclude: IncEx | None = None,
|
|
366
|
+
response_model_by_alias: bool = True,
|
|
367
|
+
response_model_exclude_unset: bool = False,
|
|
368
|
+
response_model_exclude_defaults: bool = False,
|
|
369
|
+
response_model_exclude_none: bool = False,
|
|
370
|
+
dependencies: Sequence[params.Depends] | None = None,
|
|
371
|
+
tags: list[str | Enum] | None = None,
|
|
372
|
+
):
|
|
373
|
+
def decorator(func):
|
|
374
|
+
lambda_ = self.add_endpoint(
|
|
375
|
+
path,
|
|
376
|
+
func,
|
|
377
|
+
type_="endpoint",
|
|
378
|
+
response_model=response_model,
|
|
379
|
+
status_code=status_code,
|
|
380
|
+
method="PUT",
|
|
381
|
+
cache_parameters=cache_parameters,
|
|
382
|
+
response_class=response_class,
|
|
383
|
+
response_model_include=response_model_include,
|
|
384
|
+
response_model_exclude=response_model_exclude,
|
|
385
|
+
response_model_by_alias=response_model_by_alias,
|
|
386
|
+
response_model_exclude_unset=response_model_exclude_unset,
|
|
387
|
+
response_model_exclude_defaults=response_model_exclude_defaults,
|
|
388
|
+
response_model_exclude_none=response_model_exclude_none,
|
|
389
|
+
dependencies=dependencies,
|
|
390
|
+
tags=tags,
|
|
391
|
+
)
|
|
392
|
+
return lambda_
|
|
393
|
+
|
|
394
|
+
return decorator
|
|
395
|
+
|
|
396
|
+
def patch(
|
|
397
|
+
self,
|
|
398
|
+
path: str,
|
|
399
|
+
*,
|
|
400
|
+
response_model: Any = Default(None),
|
|
401
|
+
status_code: int | None = None,
|
|
402
|
+
cache_parameters: params.Cache | None = None,
|
|
403
|
+
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
404
|
+
ResponseAPIGateway
|
|
405
|
+
),
|
|
406
|
+
response_model_include: IncEx | None = None,
|
|
407
|
+
response_model_exclude: IncEx | None = None,
|
|
408
|
+
response_model_by_alias: bool = True,
|
|
409
|
+
response_model_exclude_unset: bool = False,
|
|
410
|
+
response_model_exclude_defaults: bool = False,
|
|
411
|
+
response_model_exclude_none: bool = False,
|
|
412
|
+
dependencies: Sequence[params.Depends] | None = None,
|
|
413
|
+
tags: list[str | Enum] | None = None,
|
|
414
|
+
):
|
|
415
|
+
def decorator(func):
|
|
416
|
+
lambda_ = self.add_endpoint(
|
|
417
|
+
path,
|
|
418
|
+
func,
|
|
419
|
+
type_="endpoint",
|
|
420
|
+
response_model=response_model,
|
|
421
|
+
status_code=status_code,
|
|
422
|
+
method="PATCH",
|
|
423
|
+
cache_parameters=cache_parameters,
|
|
424
|
+
response_class=response_class,
|
|
425
|
+
response_model_include=response_model_include,
|
|
426
|
+
response_model_exclude=response_model_exclude,
|
|
427
|
+
response_model_by_alias=response_model_by_alias,
|
|
428
|
+
response_model_exclude_unset=response_model_exclude_unset,
|
|
429
|
+
response_model_exclude_defaults=response_model_exclude_defaults,
|
|
430
|
+
response_model_exclude_none=response_model_exclude_none,
|
|
431
|
+
dependencies=dependencies,
|
|
432
|
+
tags=tags,
|
|
433
|
+
)
|
|
434
|
+
return lambda_
|
|
435
|
+
|
|
436
|
+
return decorator
|
|
437
|
+
|
|
438
|
+
def delete(
|
|
439
|
+
self,
|
|
440
|
+
path: str,
|
|
441
|
+
*,
|
|
442
|
+
response_model: Any = Default(None),
|
|
443
|
+
status_code: int | None = None,
|
|
444
|
+
cache_parameters: params.Cache | None = None,
|
|
445
|
+
response_class: type[ResponseAPIGateway] | DefaultPlaceholder = Default(
|
|
446
|
+
ResponseAPIGateway
|
|
447
|
+
),
|
|
448
|
+
response_model_include: IncEx | None = None,
|
|
449
|
+
response_model_exclude: IncEx | None = None,
|
|
450
|
+
response_model_by_alias: bool = True,
|
|
451
|
+
response_model_exclude_unset: bool = False,
|
|
452
|
+
response_model_exclude_defaults: bool = False,
|
|
453
|
+
response_model_exclude_none: bool = False,
|
|
454
|
+
dependencies: Sequence[params.Depends] | None = None,
|
|
455
|
+
tags: list[str | Enum] | None = None,
|
|
456
|
+
):
|
|
457
|
+
def decorator(func):
|
|
458
|
+
lambda_ = self.add_endpoint(
|
|
459
|
+
path,
|
|
460
|
+
func,
|
|
461
|
+
type_="endpoint",
|
|
462
|
+
response_model=response_model,
|
|
463
|
+
status_code=status_code,
|
|
464
|
+
method="DELETE",
|
|
465
|
+
cache_parameters=cache_parameters,
|
|
334
466
|
response_class=response_class,
|
|
335
467
|
response_model_include=response_model_include,
|
|
336
468
|
response_model_exclude=response_model_exclude,
|
|
@@ -11,10 +11,10 @@ from aws_cdk import (
|
|
|
11
11
|
aws_iam as iam,
|
|
12
12
|
aws_lambda as _lambda,
|
|
13
13
|
aws_lambda_event_sources as lambda_event_source,
|
|
14
|
+
aws_logs as logs,
|
|
14
15
|
aws_sqs as sqs,
|
|
15
16
|
aws_s3_assets as s3_assets,
|
|
16
17
|
)
|
|
17
|
-
from aws_cdk.aws_lambda import CfnFunction
|
|
18
18
|
from constructs import Construct
|
|
19
19
|
|
|
20
20
|
from wellapi.applications import Lambda, WellApi
|
|
@@ -39,24 +39,18 @@ class WellApiCDK(Construct):
|
|
|
39
39
|
*,
|
|
40
40
|
app_srt: str,
|
|
41
41
|
handlers_dir: str,
|
|
42
|
+
cors: bool = False,
|
|
43
|
+
cache_enable: bool = False,
|
|
44
|
+
log_enable: bool = False,
|
|
42
45
|
) -> None:
|
|
43
46
|
super().__init__(scope, id_)
|
|
44
47
|
|
|
45
48
|
self.app_srt = app_srt
|
|
46
49
|
self.handlers_dir = os.path.abspath(handlers_dir)
|
|
47
50
|
|
|
48
|
-
wellapi_app: WellApi = self._package_app()
|
|
51
|
+
wellapi_app: WellApi = self._package_app(cors=cors)
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
open_api_asset = s3_assets.Asset(self, "OpenApiAsset", path=OPENAPI_FILE)
|
|
52
|
-
transform_map = {"Location": open_api_asset.s3_object_url}
|
|
53
|
-
data = Fn.transform("AWS::Include", transform_map)
|
|
54
|
-
|
|
55
|
-
self.api = apigw.SpecRestApi(
|
|
56
|
-
self,
|
|
57
|
-
f"{wellapi_app.title}Api",
|
|
58
|
-
api_definition=apigw.ApiDefinition.from_inline(data),
|
|
59
|
-
)
|
|
53
|
+
self._create_api(wellapi_app, cache_enable=cache_enable, log_enable=log_enable)
|
|
60
54
|
|
|
61
55
|
for q in wellapi_app.queues:
|
|
62
56
|
queue = sqs.Queue(self, f"{q.queue_name}Queue", queue_name=q.queue_name)
|
|
@@ -91,12 +85,13 @@ class WellApiCDK(Construct):
|
|
|
91
85
|
f"{lmbd.arn}Permission",
|
|
92
86
|
principal=iam.ServicePrincipal("apigateway.amazonaws.com"),
|
|
93
87
|
action="lambda:InvokeFunction",
|
|
94
|
-
source_arn=self.api.arn_for_execute_api(
|
|
88
|
+
source_arn=self.api.arn_for_execute_api(
|
|
89
|
+
lmbd.method.upper(), lmbd.path
|
|
90
|
+
),
|
|
95
91
|
)
|
|
96
92
|
|
|
97
|
-
cfn_lambda: CfnFunction = lambda_function.node.default_child # type: ignore
|
|
93
|
+
cfn_lambda: _lambda.CfnFunction = lambda_function.node.default_child # type: ignore
|
|
98
94
|
cfn_lambda.override_logical_id(f"{lmbd.arn}Function")
|
|
99
|
-
# self.api.node.add_dependency(lambda_function)
|
|
100
95
|
|
|
101
96
|
if lmbd.type_ == "queue":
|
|
102
97
|
queue = sqs.Queue(
|
|
@@ -120,7 +115,102 @@ class WellApiCDK(Construct):
|
|
|
120
115
|
|
|
121
116
|
rule.add_target(targets.LambdaFunction(lambda_function)) # type: ignore
|
|
122
117
|
|
|
123
|
-
def
|
|
118
|
+
def _create_api(
|
|
119
|
+
self, wellapi_app: WellApi, cache_enable: bool = False, log_enable: bool = False
|
|
120
|
+
) -> None:
|
|
121
|
+
# defining a Cfn Asset from the openAPI file
|
|
122
|
+
open_api_asset = s3_assets.Asset(self, "OpenApiAsset", path=OPENAPI_FILE)
|
|
123
|
+
transform_map = {"Location": open_api_asset.s3_object_url}
|
|
124
|
+
data = Fn.transform("AWS::Include", transform_map)
|
|
125
|
+
|
|
126
|
+
cache_deploy_options = {}
|
|
127
|
+
if cache_enable:
|
|
128
|
+
cache_deploy_options = {
|
|
129
|
+
"cache_cluster_enabled": cache_enable,
|
|
130
|
+
# "cache_cluster_size": "0.5",
|
|
131
|
+
# "cache_ttl": Duration.minutes(15),
|
|
132
|
+
"method_options": {
|
|
133
|
+
# "{resource_path}/{http_method}": apigw.MethodDeploymentOptions
|
|
134
|
+
"/*/*": apigw.MethodDeploymentOptions(
|
|
135
|
+
caching_enabled=True,
|
|
136
|
+
cache_ttl=Duration.minutes(15),
|
|
137
|
+
)
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
log_deploy_options = {}
|
|
142
|
+
if log_enable:
|
|
143
|
+
access_log_group = logs.LogGroup(
|
|
144
|
+
self,
|
|
145
|
+
"AccessLogGroup",
|
|
146
|
+
log_group_name="AccessLogGroup-apiGateway",
|
|
147
|
+
retention=logs.RetentionDays.ONE_MONTH,
|
|
148
|
+
)
|
|
149
|
+
log_deploy_options = {
|
|
150
|
+
"logging_level": apigw.MethodLoggingLevel.ERROR,
|
|
151
|
+
# data_trace_enabled=True,
|
|
152
|
+
"metrics_enabled": True,
|
|
153
|
+
"access_log_destination": apigw.LogGroupLogDestination(
|
|
154
|
+
access_log_group # type: ignore
|
|
155
|
+
),
|
|
156
|
+
"access_log_format": apigw.AccessLogFormat.custom(
|
|
157
|
+
json.dumps(
|
|
158
|
+
{
|
|
159
|
+
"request_id": apigw.AccessLogField.context_request_id(),
|
|
160
|
+
"source_ip": apigw.AccessLogField.context_identity_source_ip(),
|
|
161
|
+
"method": apigw.AccessLogField.context_http_method(),
|
|
162
|
+
"path": apigw.AccessLogField.context_resource_path(),
|
|
163
|
+
"request_path": apigw.AccessLogField.context_path(),
|
|
164
|
+
"status": apigw.AccessLogField.context_status(),
|
|
165
|
+
"user_agent": apigw.AccessLogField.context_identity_user_agent(),
|
|
166
|
+
"integration_id": apigw.AccessLogField.context_aws_endpoint_request_id(),
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
),
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if cache_deploy_options or log_deploy_options:
|
|
173
|
+
deploy_options = apigw.StageOptions(
|
|
174
|
+
**cache_deploy_options, **log_deploy_options
|
|
175
|
+
)
|
|
176
|
+
else:
|
|
177
|
+
deploy_options = None
|
|
178
|
+
|
|
179
|
+
self.api = apigw.SpecRestApi(
|
|
180
|
+
self,
|
|
181
|
+
f"{wellapi_app.title}Api",
|
|
182
|
+
api_definition=apigw.ApiDefinition.from_inline(data),
|
|
183
|
+
deploy_options=deploy_options,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
self.api_key = apigw.ApiKey(
|
|
187
|
+
self,
|
|
188
|
+
"MyApiKey",
|
|
189
|
+
api_key_name="my-service-key",
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
self.usage_plan = apigw.UsagePlan(
|
|
193
|
+
self,
|
|
194
|
+
"MyUsagePlan",
|
|
195
|
+
api_stages=[
|
|
196
|
+
apigw.UsagePlanPerApiStage(
|
|
197
|
+
api=self.api,
|
|
198
|
+
stage=self.api.deployment_stage,
|
|
199
|
+
)
|
|
200
|
+
],
|
|
201
|
+
name="MyUsagePlan",
|
|
202
|
+
quota=apigw.QuotaSettings(
|
|
203
|
+
limit=10_000,
|
|
204
|
+
period=apigw.Period.DAY,
|
|
205
|
+
),
|
|
206
|
+
throttle=apigw.ThrottleSettings(
|
|
207
|
+
burst_limit=2,
|
|
208
|
+
rate_limit=10,
|
|
209
|
+
),
|
|
210
|
+
)
|
|
211
|
+
self.usage_plan.add_api_key(self.api_key)
|
|
212
|
+
|
|
213
|
+
def _package_app(self, cors: bool = False) -> WellApi:
|
|
124
214
|
wellapi_app = import_app(self.app_srt)
|
|
125
215
|
load_handlers(self.handlers_dir)
|
|
126
216
|
|
|
@@ -132,6 +222,7 @@ class WellApiCDK(Construct):
|
|
|
132
222
|
lambdas=wellapi_app.lambdas,
|
|
133
223
|
tags=wellapi_app.openapi_tags,
|
|
134
224
|
servers=wellapi_app.servers,
|
|
225
|
+
cors=cors,
|
|
135
226
|
)
|
|
136
227
|
with open(OPENAPI_FILE, "w") as f:
|
|
137
228
|
json.dump(resp, f)
|