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 operation uses unions for inputs and outputs.
|
85 - | @app.json_unions
|
86 - | def json_unions(input: input::JsonUnionsInput, ctx: Context) -> output::JsonUnionsOutput:
|
87 - | raise NotImplementedError
|
88 - |
|
89 - | @app.kitchen_sink_operation
|
90 - | def kitchen_sink_operation(input: input::KitchenSinkOperationInput, ctx: Context) -> output::KitchenSinkOperationOutput:
|
91 - | raise NotImplementedError
|
92 - |
|
93 - | @app.null_operation
|
94 - | def null_operation(input: input::NullOperationInput, ctx: Context) -> output::NullOperationOutput:
|
95 - | raise NotImplementedError
|
96 - |
|
97 - | @app.operation_with_optional_input_output
|
98 - | def operation_with_optional_input_output(input: input::OperationWithOptionalInputOutputInput, ctx: Context) -> output::OperationWithOptionalInputOutputOutput:
|
99 - | raise NotImplementedError
|
100 - |
|
101 - | # This example serializes an inline document as part of the payload.
|
102 - | @app.put_and_get_inline_documents
|
103 - | def put_and_get_inline_documents(input: input::PutAndGetInlineDocumentsInput, ctx: Context) -> output::PutAndGetInlineDocumentsOutput:
|
104 - | raise NotImplementedError
|
105 - |
|
106 - | @app.put_with_content_encoding
|
107 - | def put_with_content_encoding(input: input::PutWithContentEncodingInput, ctx: Context) -> output::PutWithContentEncodingOutput:
|
108 - | raise NotImplementedError
|
109 - |
|
110 - | @app.simple_scalar_properties
|
111 - | def simple_scalar_properties(input: input::SimpleScalarPropertiesInput, ctx: Context) -> output::SimpleScalarPropertiesOutput:
|
112 - | raise NotImplementedError
|
113 - |
|
114 - | @app.sparse_nulls_operation
|
115 - | def sparse_nulls_operation(input: input::SparseNullsOperationInput, ctx: Context) -> output::SparseNullsOperationOutput:
|
116 - | raise NotImplementedError
|
117 - |
|
118 - | app.run()
|
119 - | ```
|
120 - |
|
121 - | Any of operations above can be written as well prepending the `async` keyword and
|
122 - | the Python application will automatically handle it and schedule it on the event loop for you.
|
123 - | """
|
124 - |
|
125 - | 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:
|
126 - | """
|
127 - | Method to register `content_type_parameters` Python implementation inside the handlers map.
|
128 - | It can be used as a function decorator in Python.
|
129 - | """
|
130 - | ...
|
131 - |
|
132 - |
|
133 - | def context(self, context: Ctx) -> None:
|
134 - | """
|
135 - | Register a context object that will be shared between handlers.
|
136 - | """
|
137 - | ...
|
138 - |
|
139 - |
|
140 - | 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:
|
141 - | """
|
142 - | Method to register `datetime_offsets` Python implementation inside the handlers map.
|
143 - | It can be used as a function decorator in Python.
|
144 - | """
|
145 - | ...
|
146 - |
|
147 - |
|
148 - | 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:
|
149 - | """
|
150 - | Method to register `empty_operation` Python implementation inside the handlers map.
|
151 - | It can be used as a function decorator in Python.
|
152 - | """
|
153 - | ...
|
154 - |
|
155 - |
|
156 - | 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:
|
157 - | """
|
158 - | Method to register `endpoint_operation` Python implementation inside the handlers map.
|
159 - | It can be used as a function decorator in Python.
|
160 - | """
|
161 - | ...
|
162 - |
|
163 - |
|
164 - | 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:
|
165 - | """
|
166 - | Method to register `endpoint_with_host_label_operation` Python implementation inside the handlers map.
|
167 - | It can be used as a function decorator in Python.
|
168 - | """
|
169 - | ...
|
170 - |
|
171 - |
|
172 - | 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:
|
173 - | """
|
174 - | Method to register `fractional_seconds` Python implementation inside the handlers map.
|
175 - | It can be used as a function decorator in Python.
|
176 - | """
|
177 - | ...
|
178 - |
|
179 - |
|
180 - | 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:
|
181 - | """
|
182 - | Method to register `greeting_with_errors` Python implementation inside the handlers map.
|
183 - | It can be used as a function decorator in Python.
|
184 - | """
|
185 - | ...
|
186 - |
|
187 - |
|
188 - | 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:
|
189 - | """
|
190 - | Method to register `host_with_path_operation` Python implementation inside the handlers map.
|
191 - | It can be used as a function decorator in Python.
|
192 - | """
|
193 - | ...
|
194 - |
|
195 - |
|
196 - | 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:
|
197 - | """
|
198 - | Method to register `json_enums` Python implementation inside the handlers map.
|
199 - | It can be used as a function decorator in Python.
|
200 - | """
|
201 - | ...
|
202 - |
|
203 - |
|
204 - | 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:
|
205 - | """
|
206 - | Method to register `json_unions` Python implementation inside the handlers map.
|
207 - | It can be used as a function decorator in Python.
|
208 - | """
|
209 - | ...
|
210 - |
|
211 - |
|
212 - | 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:
|
213 - | """
|
214 - | Method to register `kitchen_sink_operation` Python implementation inside the handlers map.
|
215 - | It can be used as a function decorator in Python.
|
216 - | """
|
217 - | ...
|
218 - |
|
219 - |
|
220 - | 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:
|
221 - | """
|
222 - | Register a Python function to be executed inside a Tower middleware layer.
|
223 - | """
|
224 - | ...
|
225 - |
|
226 - |
|
227 - | 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:
|
228 - | """
|
229 - | Method to register `null_operation` Python implementation inside the handlers map.
|
230 - | It can be used as a function decorator in Python.
|
231 - | """
|
232 - | ...
|
233 - |
|
234 - |
|
235 - | 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:
|
236 - | """
|
237 - | Method to register `operation_with_optional_input_output` Python implementation inside the handlers map.
|
238 - | It can be used as a function decorator in Python.
|
239 - | """
|
240 - | ...
|
241 - |
|
242 - |
|
243 - | 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:
|
244 - | """
|
245 - | Method to register `put_and_get_inline_documents` Python implementation inside the handlers map.
|
246 - | It can be used as a function decorator in Python.
|
247 - | """
|
248 - | ...
|
249 - |
|
250 - |
|
251 - | 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:
|
252 - | """
|
253 - | Method to register `put_with_content_encoding` Python implementation inside the handlers map.
|
254 - | It can be used as a function decorator in Python.
|
255 - | """
|
256 - | ...
|
257 - |
|
258 - |
|
259 - | 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:
|
260 - | """
|
261 - | Main entrypoint: start the server on multiple workers.
|
262 - | """
|
263 - | ...
|
264 - |
|
265 - |
|
266 - | def run_lambda(self) -> None:
|
267 - | """
|
268 - | Lambda entrypoint: start the server on Lambda.
|
269 - | """
|
270 - | ...
|
271 - |
|
272 - |
|
273 - | 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:
|
274 - | """
|
275 - | Method to register `simple_scalar_properties` Python implementation inside the handlers map.
|
276 - | It can be used as a function decorator in Python.
|
277 - | """
|
278 - | ...
|
279 - |
|
280 - |
|
281 - | 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:
|
282 - | """
|
283 - | Method to register `sparse_nulls_operation` Python implementation inside the handlers map.
|
284 - | It can be used as a function decorator in Python.
|
285 - | """
|
286 - | ...
|
287 - |
|
288 - |
|
289 - | def start_worker(self) -> None:
|
290 - | """
|
291 - | Build the service and start a single worker.
|
292 - | """
|
293 - | ...
|
294 - |
|
295 - |
|
296 - | def __init__(self) -> None:
|
297 - | ...
|
298 - |
|
299 - |
|
300 - | CODEGEN_VERSION: str = ...
|