-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
common.py
100 lines (76 loc) · 3.29 KB
/
common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import json
from functools import partial
from pathlib import Path
from typing import Any, Dict, List, Literal, Optional, TypeVar, Union
from samtranslator.compat import pydantic
from samtranslator.model.types import PassThrough
# If using PassThrough as-is, pydantic will mark the field as not required:
# - https://github.com/pydantic/pydantic/issues/990
# - https://github.com/pydantic/pydantic/issues/1223
#
# That isn't what we want; we want it to specify any type, but still required.
# Using a class gets around it.
class PassThroughProp(pydantic.BaseModel):
__root__: PassThrough
# Intrinsic resolvable by the SAM transform
T = TypeVar("T")
SamIntrinsicable = Union[Dict[str, Any], T]
SamIntrinsic = Dict[str, Any]
# TODO: Get rid of this in favor of proper types
Unknown = Optional[Any]
DictStrAny = Dict[str, Any]
LenientBaseModel = pydantic.BaseModel
_docdir = Path(__file__).absolute().parent
_DOCS = json.loads((_docdir / "sam-docs.json").read_bytes())
# Connector Permissions
PermissionsType = List[Literal["Read", "Write"]]
def get_prop(stem: str) -> Any:
return partial(_get_prop, stem)
def passthrough_prop(sam_docs_stem: str, sam_docs_name: str, prop_path: List[str]) -> Any:
"""
Specifies a pass-through field, where resource_type is the CloudFormation
resource type, and path is the list of keys to the property.
"""
path = ["definitions", prop_path[0]]
for s in prop_path[1:]:
path.extend(["properties", s])
docs = _DOCS["properties"][sam_docs_stem][sam_docs_name]
return pydantic.Field(
title=sam_docs_name,
# We add a custom value to the schema containing the path to the pass-through
# documentation; the dict containing the value is replaced in the final schema
__samPassThrough={
# To know at schema build-time where to find the property schema
"schemaPath": path,
# Use SAM docs at the top-level pass-through; it can include useful SAM-specific information
"markdownDescriptionOverride": docs,
},
)
def _get_prop(stem: str, name: str) -> Any:
docs = _DOCS["properties"][stem][name]
return pydantic.Field(
title=name,
# https://code.visualstudio.com/docs/languages/json#_use-rich-formatting-in-hovers
markdownDescription=docs,
)
# By default strict: https://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally
class BaseModel(LenientBaseModel):
class Config:
extra = pydantic.Extra.forbid
def __getattribute__(self, __name: str) -> Any:
"""Overloading get attribute operation to allow access PassThroughProp without using __root__"""
attr_value = super().__getattribute__(__name)
if isinstance(attr_value, PassThroughProp):
# See docstring of PassThroughProp
return attr_value.__root__
return attr_value
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html
class Ref(BaseModel):
Ref: str
class ResourceAttributes(BaseModel):
DependsOn: Optional[PassThroughProp]
DeletionPolicy: Optional[PassThroughProp]
Metadata: Optional[PassThroughProp]
UpdateReplacePolicy: Optional[PassThroughProp]
Condition: Optional[PassThroughProp]
IgnoreGlobals: Optional[Union[str, List[str]]]