-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace readthedocs with mkdocs (#282)
* Add docs back * Replace readthedocs with mkdocs
- Loading branch information
Showing
9 changed files
with
327 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
Async dispatch is supported. | ||
|
||
```python | ||
from jsonrpcserver import async_dispatch, async_method, Ok, Result | ||
|
||
@async_method | ||
async def ping() -> Result: | ||
return Ok("pong") | ||
|
||
await async_dispatch('{"jsonrpc": "2.0", "method": "ping", "id": 1}') | ||
``` | ||
|
||
Some reasons to use this: | ||
|
||
- Use it with an asynchronous protocol like sockets or message queues. | ||
- `await` long-running functions from your method. | ||
- Batch requests are dispatched concurrently. | ||
|
||
## Notifications | ||
|
||
Notifications are requests without an `id`. We should not respond to | ||
notifications, so jsonrpcserver gives an empty string to signify there is *no | ||
response*. | ||
|
||
```python | ||
>>> await async_dispatch('{"jsonrpc": "2.0", "method": "ping"}') | ||
'' | ||
``` | ||
|
||
If the response is an empty string, don't send it. | ||
|
||
```python | ||
if response := dispatch(request): | ||
send(response) | ||
``` | ||
|
||
```{note} | ||
A synchronous protocol like HTTP requires a response no matter what, so we can | ||
send back the empty string. However with async protocols, we have the choice of | ||
responding or not. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Dispatch | ||
|
||
The `dispatch` function processes a JSON-RPC request, attempting to call the method(s) | ||
and gives a JSON-RPC response. | ||
|
||
```python | ||
>>> dispatch('{"jsonrpc": "2.0", "method": "ping", "id": 1}') | ||
'{"jsonrpc": "2.0", "result": "pong", "id": 1}' | ||
``` | ||
|
||
It's a pure function; it will always give you a JSON-RPC response. No exceptions will be | ||
raised. | ||
|
||
[See how dispatch is used in different frameworks.](examples) | ||
|
||
## Optional parameters | ||
|
||
The `dispatch` function takes a request as its argument, and also has some optional | ||
parameters that allow you to customise how it works. | ||
|
||
### methods | ||
|
||
This lets you specify the methods to dispatch to. It's an alternative to using | ||
the `@method` decorator. The value should be a dict mapping function names to | ||
functions. | ||
|
||
```python | ||
def ping(): | ||
return Ok("pong") | ||
|
||
dispatch(request, methods={"ping": ping}) | ||
``` | ||
|
||
Default is `global_methods`, which is an internal dict populated by the | ||
`@method` decorator. | ||
|
||
### context | ||
|
||
If specified, this will be the first argument to all methods. | ||
|
||
```python | ||
@method | ||
def greet(context, name): | ||
return Ok(f"Hello {context}") | ||
|
||
>>> dispatch('{"jsonrpc": "2.0", "method": "greet", "params": ["Beau"], "id": 1}', context="Beau") | ||
'{"jsonrpc": "2.0", "result": "Hello Beau", "id": 1}' | ||
``` | ||
|
||
### deserializer | ||
|
||
A function that parses the JSON request string. Default is `json.loads`. | ||
|
||
```python | ||
dispatch(request, deserializer=ujson.loads) | ||
``` | ||
|
||
### jsonrpc_validator | ||
|
||
A function that validates the request once the JSON string has been parsed. The | ||
function should raise an exception (any exception) if the request doesn't match | ||
the JSON-RPC spec (https://www.jsonrpc.org/specification). Default is | ||
`default_jsonrpc_validator` which uses Jsonschema to validate requests against | ||
a schema. | ||
|
||
To disable JSON-RPC validation, pass `jsonrpc_validator=lambda _: None`, which | ||
will improve performance because this validation takes around half the dispatch | ||
time. | ||
|
||
### args_validator | ||
|
||
A function that validates a request's parameters against the signature of the | ||
Python function that will be called for it. Note this should not validate the | ||
_values_ of the parameters, it should simply ensure the parameters match the | ||
Python function's signature. For reference, see the `validate_args` function in | ||
`dispatcher.py`, which is the default `args_validator`. | ||
|
||
### serializer | ||
|
||
A function that serializes the response string. Default is `json.dumps`. | ||
|
||
```python | ||
dispatch(request, serializer=ujson.dumps) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## How to disable schema validation? | ||
|
||
Validating requests is costly - roughly 40% of dispatching time is spent on schema validation. | ||
If you know the incoming requests are valid, you can disable the validation for better | ||
performance. | ||
|
||
```python | ||
dispatch(request, validator=lambda _: None) | ||
``` | ||
|
||
## Which HTTP status code to respond with? | ||
|
||
I suggest: | ||
|
||
```python | ||
200 if response else 204 | ||
``` | ||
|
||
If the request was a notification, `dispatch` will give you an empty string. So | ||
since there's no http body, use status code 204 - no content. | ||
|
||
## How to rename a method | ||
|
||
Use `@method(name="new_name")`. | ||
|
||
Or use the dispatch function's [methods | ||
parameter](https://www.jsonrpcserver.com/en/latest/dispatch.html#methods). | ||
|
||
## How to get the response in other forms? | ||
|
||
Instead of `dispatch`, use: | ||
|
||
- `dispatch_to_serializable` to get the response as a dict. | ||
- `dispatch_to_response` to get the response as a namedtuple (either a | ||
`SuccessResponse` or `ErrorResponse`, these are defined in | ||
[response.py](https://github.com/explodinglabs/jsonrpcserver/blob/main/jsonrpcserver/response.py)). | ||
|
||
For these functions, if the request was a batch, you'll get a list of | ||
responses. If the request was a notification, you'll get `None`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Jsonrpcserver | ||
|
||
Jsonrpcserver processes JSON-RPC requests. | ||
|
||
## Quickstart | ||
|
||
Install jsonrpcserver: | ||
```python | ||
pip install jsonrpcserver | ||
``` | ||
|
||
Create a `server.py`: | ||
|
||
```python | ||
from jsonrpcserver import method, serve, Ok | ||
|
||
@method | ||
def ping(): | ||
return Ok("pong") | ||
|
||
if __name__ == "__main__": | ||
serve() | ||
``` | ||
|
||
Start the server: | ||
```sh | ||
$ python server.py | ||
``` | ||
|
||
Send a request: | ||
```sh | ||
$ curl -X POST http://localhost:5000 -d '{"jsonrpc": "2.0", "method": "ping", "id": 1}' | ||
{"jsonrpc": "2.0", "result": "pong", "id": 1} | ||
``` | ||
|
||
`serve` starts a basic development server. Do not use it in a production deployment. Use | ||
a production WSGI server instead, with jsonrpcserver's [dispatch](dispatch) function. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Methods | ||
|
||
Methods are functions that can be called by a JSON-RPC request. | ||
|
||
## Writing methods | ||
|
||
To write a method, decorate a function with `@method`: | ||
|
||
```python | ||
from jsonrpcserver import method, Error, Ok, Result | ||
|
||
@method | ||
def ping() -> Result: | ||
return Ok("pong") | ||
``` | ||
|
||
If you don't need to respond with any value simply `return Ok()`. | ||
|
||
## Responses | ||
|
||
Methods return either `Ok` or `Error`. These are the [JSON-RPC response | ||
objects](https://www.jsonrpc.org/specification#response_object) (excluding the | ||
`jsonrpc` and `id` parts). `Error` takes a code, message, and optionally | ||
'data'. | ||
|
||
```python | ||
@method | ||
def test() -> Result: | ||
return Error(1, "There was a problem") | ||
``` | ||
|
||
Alternatively, raise a `JsonRpcError`, which takes the same arguments as `Error`. | ||
|
||
## Parameters | ||
|
||
Methods can accept arguments. | ||
|
||
```python | ||
@method | ||
def hello(name: str) -> Result: | ||
return Ok("Hello " + name) | ||
``` | ||
|
||
Testing it: | ||
|
||
```sh | ||
$ curl -X POST http://localhost:5000 -d '{"jsonrpc": "2.0", "method": "hello", "params": ["Beau"], "id": 1}' | ||
{"jsonrpc": "2.0", "result": "Hello Beau", "id": 1} | ||
``` | ||
|
||
## Invalid params | ||
|
||
A common error response is *invalid params*. | ||
The JSON-RPC error code for this is **-32602**. A shortcut, *InvalidParams*, is | ||
included so you don't need to remember that. | ||
|
||
```python | ||
from jsonrpcserver import dispatch, method, InvalidParams, Ok, Result | ||
|
||
@method | ||
def within_range(num: int) -> Result: | ||
if num not in range(1, 5): | ||
return InvalidParams("Value must be 1-5") | ||
return Ok() | ||
``` | ||
|
||
This is the same as saying | ||
```python | ||
return Error(-32602, "Invalid params", "Value must be 1-5") | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
markdown_extensions: | ||
- pymdownx.highlight: | ||
pygments_lang_class: true | ||
- pymdownx.inlinehilite | ||
- pymdownx.snippets | ||
- pymdownx.details | ||
- pymdownx.superfences | ||
- pymdownx.mark | ||
nav: | ||
- Home: 'index.md' | ||
- 'methods.md' | ||
- 'dispatch.md' | ||
- 'async.md' | ||
- 'faq.md' | ||
- 'examples.md' | ||
repo_name: jsonrpcserver | ||
repo_url: https://github.com/explodinglabs/jsonrpcserver | ||
site_author: Exploding Labs | ||
site_description: Welcome to the documentation for Jsonrcpcserver. | ||
site_name: Jsonrpcserver | ||
site_url: https://www.jsonrpcserver.com/ | ||
theme: | ||
features: | ||
- content.code.copy | ||
- navigation.footer | ||
- navigation.tabs | ||
- toc.integrate | ||
name: material | ||
palette: | ||
# Palette toggle for automatic mode | ||
- media: "(prefers-color-scheme)" | ||
toggle: | ||
icon: material/brightness-auto | ||
name: Switch to light mode | ||
# Palette toggle for light mode | ||
- media: "(prefers-color-scheme: light)" | ||
scheme: default | ||
toggle: | ||
icon: material/brightness-7 | ||
name: Switch to dark mode | ||
# Palette toggle for dark mode | ||
- media: "(prefers-color-scheme: dark)" | ||
scheme: slate | ||
toggle: | ||
icon: material/brightness-4 | ||
name: Switch to system preference | ||
extra: | ||
version: | ||
provider: mike |