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.
Files changed (58) hide show
  1. wellapi-0.3.3/.github/workflows/build.pipeline.yml +31 -0
  2. {wellapi-0.2.1 → wellapi-0.3.3}/.gitignore +3 -0
  3. wellapi-0.3.3/PKG-INFO +142 -0
  4. wellapi-0.3.3/README.md +125 -0
  5. {wellapi-0.2.1 → wellapi-0.3.3}/pyproject.toml +8 -5
  6. wellapi-0.3.3/src/wellapi/__init__.py +10 -0
  7. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/applications.py +132 -0
  8. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/build/cdk.py +107 -16
  9. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/build/packager.py +7 -3
  10. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/cli/main.py +2 -1
  11. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/router.py +2 -3
  12. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/models.py +2 -2
  13. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/models.py +11 -3
  14. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/utils.py +86 -0
  15. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/params.py +32 -1
  16. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/security.py +33 -0
  17. wellapi-0.3.3/uv.lock +359 -0
  18. wellapi-0.2.1/.idea/.gitignore +0 -8
  19. wellapi-0.2.1/.idea/inspectionProfiles/Project_Default.xml +0 -15
  20. wellapi-0.2.1/.idea/inspectionProfiles/profiles_settings.xml +0 -6
  21. wellapi-0.2.1/.idea/misc.xml +0 -7
  22. wellapi-0.2.1/.idea/modules.xml +0 -8
  23. wellapi-0.2.1/.idea/vcs.xml +0 -6
  24. wellapi-0.2.1/.idea/wellapi.iml +0 -11
  25. wellapi-0.2.1/.idea/workspace.xml +0 -170
  26. wellapi-0.2.1/PKG-INFO +0 -32
  27. wellapi-0.2.1/README.md +0 -17
  28. wellapi-0.2.1/handlers/other.py +0 -85
  29. wellapi-0.2.1/main.py +0 -19
  30. wellapi-0.2.1/openapi.json +0 -323
  31. wellapi-0.2.1/request.json +0 -129
  32. wellapi-0.2.1/src/wellapi/__init__.py +0 -5
  33. wellapi-0.2.1/src/wellapi/awsmodel.py +0 -17
  34. wellapi-0.2.1/src/wellapi/build/sam_openapi.py +0 -10
  35. wellapi-0.2.1/src/wellapi/openapi/__init__.py +0 -0
  36. wellapi-0.2.1/uv.lock +0 -1429
  37. {wellapi-0.2.1 → wellapi-0.3.3}/.python-version +0 -0
  38. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/__main__.py +0 -0
  39. {wellapi-0.2.1/handlers → wellapi-0.3.3/src/wellapi/build}/__init__.py +0 -0
  40. {wellapi-0.2.1/src/wellapi/build → wellapi-0.3.3/src/wellapi/cli}/__init__.py +0 -0
  41. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/convertors.py +0 -0
  42. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/datastructures.py +0 -0
  43. {wellapi-0.2.1/src/wellapi/cli → wellapi-0.3.3/src/wellapi/dependencies}/__init__.py +0 -0
  44. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/dependencies/models.py +0 -0
  45. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/dependencies/utils.py +0 -0
  46. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/exceptions.py +0 -0
  47. {wellapi-0.2.1/src/wellapi/dependencies → wellapi-0.3.3/src/wellapi/local}/__init__.py +0 -0
  48. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/reloader.py +0 -0
  49. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/local/server.py +0 -0
  50. {wellapi-0.2.1/src/wellapi/local → wellapi-0.3.3/src/wellapi/middleware}/__init__.py +0 -0
  51. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/base.py +0 -0
  52. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/error.py +0 -0
  53. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/exceptions.py +0 -0
  54. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/middleware/main.py +0 -0
  55. {wellapi-0.2.1/src/wellapi/middleware → wellapi-0.3.3/src/wellapi/openapi}/__init__.py +0 -0
  56. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/openapi/docs.py +0 -0
  57. {wellapi-0.2.1 → wellapi-0.3.3}/src/wellapi/routing.py +0 -0
  58. {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
@@ -7,3 +7,6 @@ wheels/
7
7
 
8
8
  # Virtual environments
9
9
  .venv
10
+
11
+ # IDE and editor files
12
+ .idea/
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
+ ```
@@ -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.2.1"
4
- description = "Add your description here"
3
+ version = "0.3.3"
4
+ description = "A simple web framework for aws lambda"
5
5
  readme = "README.md"
6
6
  authors = [
7
- { name = "ramses", email = "romayuhym@gmail.com" }
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
- standard = [
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
- # defining a Cfn Asset from the openAPI file
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(lmbd.method.upper()),
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 _package_app(self) -> WellApi:
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)