Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2# cardinal_pythonlib/pyramid/responses.py 

3 

4""" 

5=============================================================================== 

6 

7 Original code copyright (C) 2009-2021 Rudolf Cardinal (rudolf@pobox.com). 

8 

9 This file is part of cardinal_pythonlib. 

10 

11 Licensed under the Apache License, Version 2.0 (the "License"); 

12 you may not use this file except in compliance with the License. 

13 You may obtain a copy of the License at 

14 

15 https://www.apache.org/licenses/LICENSE-2.0 

16 

17 Unless required by applicable law or agreed to in writing, software 

18 distributed under the License is distributed on an "AS IS" BASIS, 

19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

20 See the License for the specific language governing permissions and 

21 limitations under the License. 

22 

23=============================================================================== 

24 

25**Specialized response types for Pyramid (which implement MIME types and 

26suggested download methods, etc.).** 

27 

28""" 

29 

30# noinspection PyUnresolvedReferences 

31from pyramid.response import Response 

32 

33from cardinal_pythonlib.httpconst import MimeType 

34 

35 

36# ============================================================================= 

37# Responses 

38# ============================================================================= 

39 

40class BinaryResponse(Response): 

41 """ 

42 Base class for creating binary HTTP responses. 

43 """ 

44 def __init__(self, body: bytes, filename: str, 

45 content_type: str, as_inline: bool = False, **kwargs) -> None: 

46 """ 

47 Args: 

48 body: binary data 

49 filename: filename to associate with the download 

50 content_type: MIME content type 

51 as_inline: inline, rather than as an attachment? 

52 Inline: display within browser, if possible. 

53 Attachment: download. 

54 """ 

55 disp = "inline" if as_inline else "attachment" 

56 super().__init__( 

57 content_type=content_type, 

58 content_disposition=f"{disp}; filename={filename}", 

59 content_encoding="binary", 

60 content_length=len(body), 

61 body=body, 

62 **kwargs 

63 ) 

64 

65 

66class OdsResponse(BinaryResponse): 

67 """ 

68 Response class for returning an ODS (OpenOffice Spreadsheet) file to the 

69 user. 

70 """ 

71 def __init__(self, body: bytes, filename: str, **kwargs) -> None: 

72 super().__init__( 

73 content_type=MimeType.ODS, 

74 body=body, 

75 filename=filename, 

76 **kwargs 

77 ) 

78 

79 

80class PdfResponse(BinaryResponse): 

81 """ 

82 Response class for returning a PDF to the user. 

83 """ 

84 def __init__(self, body: bytes, filename: str, 

85 as_inline: bool = True, **kwargs) -> None: 

86 super().__init__( 

87 content_type=MimeType.PDF, 

88 filename=filename, 

89 as_inline=as_inline, 

90 body=body, 

91 **kwargs 

92 ) 

93 

94 

95class SqliteBinaryResponse(BinaryResponse): 

96 """ 

97 Response class for returning a SQLite binary database to the user. 

98 """ 

99 def __init__(self, body: bytes, filename: str, **kwargs) -> None: 

100 super().__init__( 

101 content_type=MimeType.SQLITE3, 

102 filename=filename, 

103 body=body, 

104 **kwargs 

105 ) 

106 

107 

108class TextAttachmentResponse(Response): 

109 """ 

110 Response class for returning text to the user as an attachment. 

111 """ 

112 def __init__(self, body: str, filename: str, **kwargs) -> None: 

113 # Will default to UTF-8 

114 super().__init__( 

115 content_type=MimeType.TEXT, 

116 content_disposition=f"attachment; filename={filename}", 

117 body=body, 

118 **kwargs 

119 ) 

120 

121 

122class TextResponse(Response): 

123 """ 

124 Response class for returning text to the user, viewed in the browser. 

125 """ 

126 def __init__(self, body: str, **kwargs) -> None: 

127 super().__init__( 

128 content_type=MimeType.TEXT, 

129 body=body, 

130 **kwargs 

131 ) 

132 

133 

134class TsvResponse(Response): 

135 """ 

136 Response class for returning a TSV file to the user. 

137 """ 

138 def __init__(self, body: str, filename: str, **kwargs) -> None: 

139 super().__init__( 

140 content_type=MimeType.TSV, 

141 content_disposition=f"attachment; filename={filename}", 

142 body=body, 

143 **kwargs 

144 ) 

145 

146 

147class XlsxResponse(BinaryResponse): 

148 """ 

149 Response class for returning an XLSX (Excel) file to the user. 

150 """ 

151 def __init__(self, body: bytes, filename: str, **kwargs) -> None: 

152 super().__init__( 

153 content_type=MimeType.XLSX, 

154 body=body, 

155 filename=filename, 

156 **kwargs 

157 ) 

158 

159 

160class XmlResponse(Response): 

161 """ 

162 Response class for returning XML to the user. 

163 """ 

164 def __init__(self, body: str, **kwargs) -> None: 

165 # application/xml versus text/xml: 

166 # https://stackoverflow.com/questions/4832357 

167 super().__init__( 

168 content_type=MimeType.XML, 

169 body=body, 

170 **kwargs 

171 ) 

172 

173 

174class ZipResponse(BinaryResponse): 

175 """ 

176 Response class for returning a ZIP file to the user. 

177 """ 

178 def __init__(self, body: bytes, filename: str, **kwargs) -> None: 

179 # For ZIP, "inline" and "attachment" dispositions are equivalent, since 

180 # browsers don't display ZIP files inline. 

181 # https://stackoverflow.com/questions/1395151 

182 super().__init__( 

183 content_type=MimeType.ZIP, 

184 filename=filename, 

185 body=body, 

186 **kwargs 

187 )