Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/botocore/docs/utils.py: 56%

75 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

1# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"). You 

4# may not use this file except in compliance with the License. A copy of 

5# the License is located at 

6# 

7# http://aws.amazon.com/apache2.0/ 

8# 

9# or in the "license" file accompanying this file. This file is 

10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

11# ANY KIND, either express or implied. See the License for the specific 

12# language governing permissions and limitations under the License. 

13import re 

14from collections import namedtuple 

15 

16 

17def py_type_name(type_name): 

18 """Get the Python type name for a given model type. 

19 

20 >>> py_type_name('list') 

21 'list' 

22 >>> py_type_name('structure') 

23 'dict' 

24 

25 :rtype: string 

26 """ 

27 return { 

28 'blob': 'bytes', 

29 'character': 'string', 

30 'double': 'float', 

31 'long': 'integer', 

32 'map': 'dict', 

33 'structure': 'dict', 

34 'timestamp': 'datetime', 

35 }.get(type_name, type_name) 

36 

37 

38def py_default(type_name): 

39 """Get the Python default value for a given model type. 

40 

41 >>> py_default('string') 

42 '\'string\'' 

43 >>> py_default('list') 

44 '[...]' 

45 >>> py_default('unknown') 

46 '...' 

47 

48 :rtype: string 

49 """ 

50 return { 

51 'double': '123.0', 

52 'long': '123', 

53 'integer': '123', 

54 'string': "'string'", 

55 'blob': "b'bytes'", 

56 'boolean': 'True|False', 

57 'list': '[...]', 

58 'map': '{...}', 

59 'structure': '{...}', 

60 'timestamp': 'datetime(2015, 1, 1)', 

61 }.get(type_name, '...') 

62 

63 

64def get_official_service_name(service_model): 

65 """Generate the official name of an AWS Service 

66 

67 :param service_model: The service model representing the service 

68 """ 

69 official_name = service_model.metadata.get('serviceFullName') 

70 short_name = service_model.metadata.get('serviceAbbreviation', '') 

71 if short_name.startswith('Amazon'): 

72 short_name = short_name[7:] 

73 if short_name.startswith('AWS'): 

74 short_name = short_name[4:] 

75 if short_name and short_name.lower() not in official_name.lower(): 

76 official_name += f' ({short_name})' 

77 return official_name 

78 

79 

80_DocumentedShape = namedtuple( 

81 'DocumentedShape', 

82 [ 

83 'name', 

84 'type_name', 

85 'documentation', 

86 'metadata', 

87 'members', 

88 'required_members', 

89 ], 

90) 

91 

92 

93class DocumentedShape(_DocumentedShape): 

94 """Use this class to inject new shapes into a model for documentation""" 

95 

96 def __new__( 

97 cls, 

98 name, 

99 type_name, 

100 documentation, 

101 metadata=None, 

102 members=None, 

103 required_members=None, 

104 ): 

105 if metadata is None: 

106 metadata = [] 

107 if members is None: 

108 members = [] 

109 if required_members is None: 

110 required_members = [] 

111 return super().__new__( 

112 cls, 

113 name, 

114 type_name, 

115 documentation, 

116 metadata, 

117 members, 

118 required_members, 

119 ) 

120 

121 

122class AutoPopulatedParam: 

123 def __init__(self, name, param_description=None): 

124 self.name = name 

125 self.param_description = param_description 

126 if param_description is None: 

127 self.param_description = ( 

128 'Please note that this parameter is automatically populated ' 

129 'if it is not provided. Including this parameter is not ' 

130 'required\n' 

131 ) 

132 

133 def document_auto_populated_param(self, event_name, section, **kwargs): 

134 """Documents auto populated parameters 

135 

136 It will remove any required marks for the parameter, remove the 

137 parameter from the example, and add a snippet about the parameter 

138 being autopopulated in the description. 

139 """ 

140 if event_name.startswith('docs.request-params'): 

141 if self.name in section.available_sections: 

142 section = section.get_section(self.name) 

143 if 'is-required' in section.available_sections: 

144 section.delete_section('is-required') 

145 description_section = section.get_section( 

146 'param-documentation' 

147 ) 

148 description_section.writeln(self.param_description) 

149 elif event_name.startswith('docs.request-example'): 

150 section = section.get_section('structure-value') 

151 if self.name in section.available_sections: 

152 section.delete_section(self.name) 

153 

154 

155class HideParamFromOperations: 

156 """Hides a single parameter from multiple operations. 

157 

158 This method will remove a parameter from documentation and from 

159 examples. This method is typically used for things that are 

160 automatically populated because a user would be unable to provide 

161 a value (e.g., a checksum of a serialized XML request body).""" 

162 

163 def __init__(self, service_name, parameter_name, operation_names): 

164 """ 

165 :type service_name: str 

166 :param service_name: Name of the service to modify. 

167 

168 :type parameter_name: str 

169 :param parameter_name: Name of the parameter to modify. 

170 

171 :type operation_names: list 

172 :param operation_names: Operation names to modify. 

173 """ 

174 self._parameter_name = parameter_name 

175 self._params_events = set() 

176 self._example_events = set() 

177 # Build up the sets of relevant event names. 

178 param_template = 'docs.request-params.%s.%s.complete-section' 

179 example_template = 'docs.request-example.%s.%s.complete-section' 

180 for name in operation_names: 

181 self._params_events.add(param_template % (service_name, name)) 

182 self._example_events.add(example_template % (service_name, name)) 

183 

184 def hide_param(self, event_name, section, **kwargs): 

185 if event_name in self._example_events: 

186 # Modify the structure value for example events. 

187 section = section.get_section('structure-value') 

188 elif event_name not in self._params_events: 

189 return 

190 if self._parameter_name in section.available_sections: 

191 section.delete_section(self._parameter_name) 

192 

193 

194class AppendParamDocumentation: 

195 """Appends documentation to a specific parameter""" 

196 

197 def __init__(self, parameter_name, doc_string): 

198 self._parameter_name = parameter_name 

199 self._doc_string = doc_string 

200 

201 def append_documentation(self, event_name, section, **kwargs): 

202 if self._parameter_name in section.available_sections: 

203 section = section.get_section(self._parameter_name) 

204 description_section = section.get_section('param-documentation') 

205 description_section.writeln(self._doc_string) 

206 

207 

208_CONTROLS = { 

209 '\n': '\\n', 

210 '\r': '\\r', 

211 '\t': '\\t', 

212 '\b': '\\b', 

213 '\f': '\\f', 

214} 

215# Combines all CONTROLS keys into a big or regular expression 

216_ESCAPE_CONTROLS_RE = re.compile('|'.join(map(re.escape, _CONTROLS))) 

217# Based on the match get the appropriate replacement from CONTROLS 

218_CONTROLS_MATCH_HANDLER = lambda match: _CONTROLS[match.group(0)] 

219 

220 

221def escape_controls(value): 

222 return _ESCAPE_CONTROLS_RE.sub(_CONTROLS_MATCH_HANDLER, value)