1 - | import json_rpc11.input
|
2 - | import json_rpc11.middleware
|
3 - | import json_rpc11.output
|
4 - | import json_rpc11.tls
|
5 - | import typing
|
6 - |
|
7 - | Ctx = typing.TypeVar('Ctx')
|
8 - |
|
9 - | class App(typing.Generic[Ctx]):
|
10 - | """
|
11 - | Main Python application, used to register operations and context and start multiple
|
12 - | workers on the same shared socket.
|
13 - |
|
14 - | Operations can be registered using the application object as a decorator (`@app.operation_name`).
|
15 - |
|
16 - | Here's a full example to get you started:
|
17 - |
|
18 - | ```python
|
19 - | from json_rpc11 import input
|
20 - | from json_rpc11 import output
|
21 - | from json_rpc11 import error
|
22 - | from json_rpc11 import middleware
|
23 - | from json_rpc11 import App
|
24 - |
|
25 - | @dataclass
|
26 - | class Context:
|
27 - | counter: int = 0
|
28 - |
|
29 - | app = App()
|
30 - | app.context(Context())
|
31 - |
|
32 - | @app.request_middleware
|
33 - | def request_middleware(request: middleware::Request):
|
34 - | if request.get_header("x-amzn-id") != "secret":
|
35 - | raise middleware.MiddlewareException("Unsupported `x-amz-id` header", 401)
|
36 - |
|
37 - | # The example tests how servers must support requests
|
38 - | # containing a `Content-Type` header with parameters.
|
39 - | @app.content_type_parameters
|
40 - | def content_type_parameters(input: input::ContentTypeParametersInput, ctx: Context) -> output::ContentTypeParametersOutput:
|
41 - | raise NotImplementedError
|
42 - |
|
43 - | @app.datetime_offsets
|
44 - | def datetime_offsets(input: input::DatetimeOffsetsInput, ctx: Context) -> output::DatetimeOffsetsOutput:
|
45 - | raise NotImplementedError
|
46 - |
|
47 - | @app.empty_operation
|
48 - | def empty_operation(input: input::EmptyOperationInput, ctx: Context) -> output::EmptyOperationOutput:
|
49 - | raise NotImplementedError
|
50 - |
|
51 - | @app.endpoint_operation
|
52 - | def endpoint_operation(input: input::EndpointOperationInput, ctx: Context) -> output::EndpointOperationOutput:
|
53 - | raise NotImplementedError
|
54 - |
|
55 - | @app.endpoint_with_host_label_operation
|
56 - | def endpoint_with_host_label_operation(input: input::EndpointWithHostLabelOperationInput, ctx: Context) -> output::EndpointWithHostLabelOperationOutput:
|
57 - | raise NotImplementedError
|
58 - |
|
59 - | @app.fractional_seconds
|
60 - | def fractional_seconds(input: input::FractionalSecondsInput, ctx: Context) -> output::FractionalSecondsOutput:
|
61 - | raise NotImplementedError
|
62 - |
|
63 - | # This operation has three possible return values:
|
64 - | #
|
65 - | # 1. A successful response in the form of GreetingWithErrorsOutput
|
66 - | # 2. An InvalidGreeting error.
|
67 - | # 3. A ComplexError error.
|
68 - | #
|
69 - | # Implementations must be able to successfully take a response and
|
70 - | # properly deserialize successful and error responses.
|
71 - | @app.greeting_with_errors
|
72 - | def greeting_with_errors(input: input::GreetingWithErrorsInput, ctx: Context) -> output::GreetingWithErrorsOutput:
|
73 - | raise NotImplementedError
|
74 - |
|
75 - | @app.host_with_path_operation
|
76 - | def host_with_path_operation(input: input::HostWithPathOperationInput, ctx: Context) -> output::HostWithPathOperationOutput:
|
77 - | raise NotImplementedError
|
78 - |
|
79 - | # This example serializes enums as top level properties, in lists, sets, and maps.
|
80 - | @app.json_enums
|
81 - | def json_enums(input: input::JsonEnumsInput, ctx: Context) -> output::JsonEnumsOutput:
|
82 - | raise NotImplementedError
|
83 - |
|
84 - | # This example serializes intEnums as top level properties, in lists, sets, and maps.
|
85 - | @app.json_int_enums
|
86 - | def json_int_enums(input: input::JsonIntEnumsInput, ctx: Context) -> output::JsonIntEnumsOutput:
|
87 - | raise NotImplementedError
|
88 - |
|
89 - | # This operation uses unions for inputs and outputs.
|
90 - | @app.json_unions
|
91 - | def json_unions(input: input::JsonUnionsInput, ctx: Context) -> output::JsonUnionsOutput:
|
92 - | raise NotImplementedError
|
93 - |
|
94 - | @app.kitchen_sink_operation
|
95 - | def kitchen_sink_operation(input: input::KitchenSinkOperationInput, ctx: Context) -> output::KitchenSinkOperationOutput:
|
96 - | raise NotImplementedError
|
97 - |
|
98 - | @app.null_operation
|
99 - | def null_operation(input: input::NullOperationInput, ctx: Context) -> output::NullOperationOutput:
|
100 - | raise NotImplementedError
|
101 - |
|
102 - | @app.operation_with_optional_input_output
|
103 - | def operation_with_optional_input_output(input: input::OperationWithOptionalInputOutputInput, ctx: Context) -> output::OperationWithOptionalInputOutputOutput:
|
104 - | raise NotImplementedError
|
105 - |
|
106 - | # This example serializes an inline document as part of the payload.
|
107 - | @app.put_and_get_inline_documents
|
108 - | def put_and_get_inline_documents(input: input::PutAndGetInlineDocumentsInput, ctx: Context) -> output::PutAndGetInlineDocumentsOutput:
|
109 - | raise NotImplementedError
|
110 - |
|
111 - | @app.put_with_content_encoding
|
112 - | def put_with_content_encoding(input: input::PutWithContentEncodingInput, ctx: Context) -> output::PutWithContentEncodingOutput:
|
113 - | raise NotImplementedError
|
114 - |
|
115 - | @app.simple_scalar_properties
|
116 - | def simple_scalar_properties(input: input::SimpleScalarPropertiesInput, ctx: Context) -> output::SimpleScalarPropertiesOutput:
|
117 - | raise NotImplementedError
|
118 - |
|
119 - | @app.sparse_nulls_operation
|
120 - | def sparse_nulls_operation(input: input::SparseNullsOperationInput, ctx: Context) -> output::SparseNullsOperationOutput:
|
121 - | raise NotImplementedError
|
122 - |
|
123 - | app.run()
|
124 - | ```
|
125 - |
|
126 - | Any of operations above can be written as well prepending the `async` keyword and
|
127 - | the Python application will automatically handle it and schedule it on the event loop for you.
|
128 - | """
|
129 - |
|
130 - | def content_type_parameters(self, func: typing.Union[typing.Callable[[json_rpc11.input.ContentTypeParametersInput, Ctx], typing.Union[json_rpc11.output.ContentTypeParametersOutput, typing.Awaitable[json_rpc11.output.ContentTypeParametersOutput]]], typing.Callable[[json_rpc11.input.ContentTypeParametersInput], typing.Union[json_rpc11.output.ContentTypeParametersOutput, typing.Awaitable[json_rpc11.output.ContentTypeParametersOutput]]]]) -> None:
|
131 - | """
|
132 - | Method to register `content_type_parameters` Python implementation inside the handlers map.
|
133 - | It can be used as a function decorator in Python.
|
134 - | """
|
135 - | ...
|
136 - |
|
137 - |
|
138 - | def context(self, context: Ctx) -> None:
|
139 - | """
|
140 - | Register a context object that will be shared between handlers.
|
141 - | """
|
142 - | ...
|
143 - |
|
144 - |
|
145 - | def datetime_offsets(self, func: typing.Union[typing.Callable[[json_rpc11.input.DatetimeOffsetsInput, Ctx], typing.Union[json_rpc11.output.DatetimeOffsetsOutput, typing.Awaitable[json_rpc11.output.DatetimeOffsetsOutput]]], typing.Callable[[json_rpc11.input.DatetimeOffsetsInput], typing.Union[json_rpc11.output.DatetimeOffsetsOutput, typing.Awaitable[json_rpc11.output.DatetimeOffsetsOutput]]]]) -> None:
|
146 - | """
|
147 - | Method to register `datetime_offsets` Python implementation inside the handlers map.
|
148 - | It can be used as a function decorator in Python.
|
149 - | """
|
150 - | ...
|
151 - |
|
152 - |
|
153 - | def empty_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.EmptyOperationInput, Ctx], typing.Union[json_rpc11.output.EmptyOperationOutput, typing.Awaitable[json_rpc11.output.EmptyOperationOutput]]], typing.Callable[[json_rpc11.input.EmptyOperationInput], typing.Union[json_rpc11.output.EmptyOperationOutput, typing.Awaitable[json_rpc11.output.EmptyOperationOutput]]]]) -> None:
|
154 - | """
|
155 - | Method to register `empty_operation` Python implementation inside the handlers map.
|
156 - | It can be used as a function decorator in Python.
|
157 - | """
|
158 - | ...
|
159 - |
|
160 - |
|
161 - | def endpoint_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.EndpointOperationInput, Ctx], typing.Union[json_rpc11.output.EndpointOperationOutput, typing.Awaitable[json_rpc11.output.EndpointOperationOutput]]], typing.Callable[[json_rpc11.input.EndpointOperationInput], typing.Union[json_rpc11.output.EndpointOperationOutput, typing.Awaitable[json_rpc11.output.EndpointOperationOutput]]]]) -> None:
|
162 - | """
|
163 - | Method to register `endpoint_operation` Python implementation inside the handlers map.
|
164 - | It can be used as a function decorator in Python.
|
165 - | """
|
166 - | ...
|
167 - |
|
168 - |
|
169 - | def endpoint_with_host_label_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.EndpointWithHostLabelOperationInput, Ctx], typing.Union[json_rpc11.output.EndpointWithHostLabelOperationOutput, typing.Awaitable[json_rpc11.output.EndpointWithHostLabelOperationOutput]]], typing.Callable[[json_rpc11.input.EndpointWithHostLabelOperationInput], typing.Union[json_rpc11.output.EndpointWithHostLabelOperationOutput, typing.Awaitable[json_rpc11.output.EndpointWithHostLabelOperationOutput]]]]) -> None:
|
170 - | """
|
171 - | Method to register `endpoint_with_host_label_operation` Python implementation inside the handlers map.
|
172 - | It can be used as a function decorator in Python.
|
173 - | """
|
174 - | ...
|
175 - |
|
176 - |
|
177 - | def fractional_seconds(self, func: typing.Union[typing.Callable[[json_rpc11.input.FractionalSecondsInput, Ctx], typing.Union[json_rpc11.output.FractionalSecondsOutput, typing.Awaitable[json_rpc11.output.FractionalSecondsOutput]]], typing.Callable[[json_rpc11.input.FractionalSecondsInput], typing.Union[json_rpc11.output.FractionalSecondsOutput, typing.Awaitable[json_rpc11.output.FractionalSecondsOutput]]]]) -> None:
|
178 - | """
|
179 - | Method to register `fractional_seconds` Python implementation inside the handlers map.
|
180 - | It can be used as a function decorator in Python.
|
181 - | """
|
182 - | ...
|
183 - |
|
184 - |
|
185 - | def greeting_with_errors(self, func: typing.Union[typing.Callable[[json_rpc11.input.GreetingWithErrorsInput, Ctx], typing.Union[json_rpc11.output.GreetingWithErrorsOutput, typing.Awaitable[json_rpc11.output.GreetingWithErrorsOutput]]], typing.Callable[[json_rpc11.input.GreetingWithErrorsInput], typing.Union[json_rpc11.output.GreetingWithErrorsOutput, typing.Awaitable[json_rpc11.output.GreetingWithErrorsOutput]]]]) -> None:
|
186 - | """
|
187 - | Method to register `greeting_with_errors` Python implementation inside the handlers map.
|
188 - | It can be used as a function decorator in Python.
|
189 - | """
|
190 - | ...
|
191 - |
|
192 - |
|
193 - | def host_with_path_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.HostWithPathOperationInput, Ctx], typing.Union[json_rpc11.output.HostWithPathOperationOutput, typing.Awaitable[json_rpc11.output.HostWithPathOperationOutput]]], typing.Callable[[json_rpc11.input.HostWithPathOperationInput], typing.Union[json_rpc11.output.HostWithPathOperationOutput, typing.Awaitable[json_rpc11.output.HostWithPathOperationOutput]]]]) -> None:
|
194 - | """
|
195 - | Method to register `host_with_path_operation` Python implementation inside the handlers map.
|
196 - | It can be used as a function decorator in Python.
|
197 - | """
|
198 - | ...
|
199 - |
|
200 - |
|
201 - | def json_enums(self, func: typing.Union[typing.Callable[[json_rpc11.input.JsonEnumsInput, Ctx], typing.Union[json_rpc11.output.JsonEnumsOutput, typing.Awaitable[json_rpc11.output.JsonEnumsOutput]]], typing.Callable[[json_rpc11.input.JsonEnumsInput], typing.Union[json_rpc11.output.JsonEnumsOutput, typing.Awaitable[json_rpc11.output.JsonEnumsOutput]]]]) -> None:
|
202 - | """
|
203 - | Method to register `json_enums` Python implementation inside the handlers map.
|
204 - | It can be used as a function decorator in Python.
|
205 - | """
|
206 - | ...
|
207 - |
|
208 - |
|
209 - | def json_int_enums(self, func: typing.Union[typing.Callable[[json_rpc11.input.JsonIntEnumsInput, Ctx], typing.Union[json_rpc11.output.JsonIntEnumsOutput, typing.Awaitable[json_rpc11.output.JsonIntEnumsOutput]]], typing.Callable[[json_rpc11.input.JsonIntEnumsInput], typing.Union[json_rpc11.output.JsonIntEnumsOutput, typing.Awaitable[json_rpc11.output.JsonIntEnumsOutput]]]]) -> None:
|
210 - | """
|
211 - | Method to register `json_int_enums` Python implementation inside the handlers map.
|
212 - | It can be used as a function decorator in Python.
|
213 - | """
|
214 - | ...
|
215 - |
|
216 - |
|
217 - | def json_unions(self, func: typing.Union[typing.Callable[[json_rpc11.input.JsonUnionsInput, Ctx], typing.Union[json_rpc11.output.JsonUnionsOutput, typing.Awaitable[json_rpc11.output.JsonUnionsOutput]]], typing.Callable[[json_rpc11.input.JsonUnionsInput], typing.Union[json_rpc11.output.JsonUnionsOutput, typing.Awaitable[json_rpc11.output.JsonUnionsOutput]]]]) -> None:
|
218 - | """
|
219 - | Method to register `json_unions` Python implementation inside the handlers map.
|
220 - | It can be used as a function decorator in Python.
|
221 - | """
|
222 - | ...
|
223 - |
|
224 - |
|
225 - | def kitchen_sink_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.KitchenSinkOperationInput, Ctx], typing.Union[json_rpc11.output.KitchenSinkOperationOutput, typing.Awaitable[json_rpc11.output.KitchenSinkOperationOutput]]], typing.Callable[[json_rpc11.input.KitchenSinkOperationInput], typing.Union[json_rpc11.output.KitchenSinkOperationOutput, typing.Awaitable[json_rpc11.output.KitchenSinkOperationOutput]]]]) -> None:
|
226 - | """
|
227 - | Method to register `kitchen_sink_operation` Python implementation inside the handlers map.
|
228 - | It can be used as a function decorator in Python.
|
229 - | """
|
230 - | ...
|
231 - |
|
232 - |
|
233 - | def middleware(self, func: typing.Callable[[json_rpc11.middleware.Request, typing.Callable[[json_rpc11.middleware.Request], typing.Awaitable[json_rpc11.middleware.Response]]], typing.Awaitable[json_rpc11.middleware.Response]]) -> None:
|
234 - | """
|
235 - | Register a Python function to be executed inside a Tower middleware layer.
|
236 - | """
|
237 - | ...
|
238 - |
|
239 - |
|
240 - | def null_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.NullOperationInput, Ctx], typing.Union[json_rpc11.output.NullOperationOutput, typing.Awaitable[json_rpc11.output.NullOperationOutput]]], typing.Callable[[json_rpc11.input.NullOperationInput], typing.Union[json_rpc11.output.NullOperationOutput, typing.Awaitable[json_rpc11.output.NullOperationOutput]]]]) -> None:
|
241 - | """
|
242 - | Method to register `null_operation` Python implementation inside the handlers map.
|
243 - | It can be used as a function decorator in Python.
|
244 - | """
|
245 - | ...
|
246 - |
|
247 - |
|
248 - | def operation_with_optional_input_output(self, func: typing.Union[typing.Callable[[json_rpc11.input.OperationWithOptionalInputOutputInput, Ctx], typing.Union[json_rpc11.output.OperationWithOptionalInputOutputOutput, typing.Awaitable[json_rpc11.output.OperationWithOptionalInputOutputOutput]]], typing.Callable[[json_rpc11.input.OperationWithOptionalInputOutputInput], typing.Union[json_rpc11.output.OperationWithOptionalInputOutputOutput, typing.Awaitable[json_rpc11.output.OperationWithOptionalInputOutputOutput]]]]) -> None:
|
249 - | """
|
250 - | Method to register `operation_with_optional_input_output` Python implementation inside the handlers map.
|
251 - | It can be used as a function decorator in Python.
|
252 - | """
|
253 - | ...
|
254 - |
|
255 - |
|
256 - | def put_and_get_inline_documents(self, func: typing.Union[typing.Callable[[json_rpc11.input.PutAndGetInlineDocumentsInput, Ctx], typing.Union[json_rpc11.output.PutAndGetInlineDocumentsOutput, typing.Awaitable[json_rpc11.output.PutAndGetInlineDocumentsOutput]]], typing.Callable[[json_rpc11.input.PutAndGetInlineDocumentsInput], typing.Union[json_rpc11.output.PutAndGetInlineDocumentsOutput, typing.Awaitable[json_rpc11.output.PutAndGetInlineDocumentsOutput]]]]) -> None:
|
257 - | """
|
258 - | Method to register `put_and_get_inline_documents` Python implementation inside the handlers map.
|
259 - | It can be used as a function decorator in Python.
|
260 - | """
|
261 - | ...
|
262 - |
|
263 - |
|
264 - | def put_with_content_encoding(self, func: typing.Union[typing.Callable[[json_rpc11.input.PutWithContentEncodingInput, Ctx], typing.Union[json_rpc11.output.PutWithContentEncodingOutput, typing.Awaitable[json_rpc11.output.PutWithContentEncodingOutput]]], typing.Callable[[json_rpc11.input.PutWithContentEncodingInput], typing.Union[json_rpc11.output.PutWithContentEncodingOutput, typing.Awaitable[json_rpc11.output.PutWithContentEncodingOutput]]]]) -> None:
|
265 - | """
|
266 - | Method to register `put_with_content_encoding` Python implementation inside the handlers map.
|
267 - | It can be used as a function decorator in Python.
|
268 - | """
|
269 - | ...
|
270 - |
|
271 - |
|
272 - | def run(self, address: typing.Optional[str] = ..., port: typing.Optional[int] = ..., backlog: typing.Optional[int] = ..., workers: typing.Optional[int] = ..., tls: typing.Optional[json_rpc11.tls.TlsConfig] = ...) -> None:
|
273 - | """
|
274 - | Main entrypoint: start the server on multiple workers.
|
275 - | """
|
276 - | ...
|
277 - |
|
278 - |
|
279 - | def run_lambda(self) -> None:
|
280 - | """
|
281 - | Lambda entrypoint: start the server on Lambda.
|
282 - | """
|
283 - | ...
|
284 - |
|
285 - |
|
286 - | def simple_scalar_properties(self, func: typing.Union[typing.Callable[[json_rpc11.input.SimpleScalarPropertiesInput, Ctx], typing.Union[json_rpc11.output.SimpleScalarPropertiesOutput, typing.Awaitable[json_rpc11.output.SimpleScalarPropertiesOutput]]], typing.Callable[[json_rpc11.input.SimpleScalarPropertiesInput], typing.Union[json_rpc11.output.SimpleScalarPropertiesOutput, typing.Awaitable[json_rpc11.output.SimpleScalarPropertiesOutput]]]]) -> None:
|
287 - | """
|
288 - | Method to register `simple_scalar_properties` Python implementation inside the handlers map.
|
289 - | It can be used as a function decorator in Python.
|
290 - | """
|
291 - | ...
|
292 - |
|
293 - |
|
294 - | def sparse_nulls_operation(self, func: typing.Union[typing.Callable[[json_rpc11.input.SparseNullsOperationInput, Ctx], typing.Union[json_rpc11.output.SparseNullsOperationOutput, typing.Awaitable[json_rpc11.output.SparseNullsOperationOutput]]], typing.Callable[[json_rpc11.input.SparseNullsOperationInput], typing.Union[json_rpc11.output.SparseNullsOperationOutput, typing.Awaitable[json_rpc11.output.SparseNullsOperationOutput]]]]) -> None:
|
295 - | """
|
296 - | Method to register `sparse_nulls_operation` Python implementation inside the handlers map.
|
297 - | It can be used as a function decorator in Python.
|
298 - | """
|
299 - | ...
|
300 - |
|
301 - |
|
302 - | def start_worker(self) -> None:
|
303 - | """
|
304 - | Build the service and start a single worker.
|
305 - | """
|
306 - | ...
|
307 - |
|
308 - |
|
309 - | def __init__(self) -> None:
|
310 - | ...
|
311 - |
|
312 - |
|
313 - | CODEGEN_VERSION: str = ...
|