Giter VIP home page Giter VIP logo

json-rpc's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-rpc's Issues

TypeError in user code is hidden by library

Can I please draw your attention to jsonrpc/manager.py in __get_responses where parameters are validated for a method.
Due to the way that parameters are validated, a TypeError is raised when the method is given incorrect parameters, and thus, the following line is executed

output = response(error=JSONRPCInvalidParams()._data)

The exception handling around this doesn't account for the fact that a developer's code within that method can potentially throw a TypeError. In this case, the real issue is hidden and the following error is returned:

{u'jsonrpc': u'2.0', u'id': 0, u'error': {u'message': u'Invalid params', u'code': -32602}}

I've just lost some time investigating why I was getting this error, and it would be great to avoid inflicting that upon someone else.

Customizing the dispatcher for the Flask back end is difficult.

Since Dispatcher acts as a collection, it evaluates as False when empty. This causes the assignment self.dispatcher = dispatcher or Dispatcher() to make a new Dispatcher instance when passed an empty Dispatcher.

To reproduce:

class SubDispatcher(Dispatcher):
    pass

type(JSONRPCAPI(SubDispatcher()).dispatcher) == Dispatcher # This should be SubDispatcher

On certain TypeErrors, json-rpc fails to log and responds incorrectly

If application code raises a TypeError, json-rpc doesn't necessarily log the exception and stack trace. Instead, it responds with an "Invalid params" error with code "-32602".

This is also not a correct message in this case because the reason for the error is not invalid parameters sent by the caller. It is an error in application code.

I believe this issue is due to the exception handling here, where the code bypasses exception logging if the exception has type TypeError. Or perhaps it is due to incorrect logic in is_invalid_params().

Add README badges

  1. Python versions
  2. Coverage (connect)
  3. Codacy
  4. Documentation
  5. PyPI version

All should be opened in a new window.

Django backend fails on exception with non-serializable argument

I encountered a situation where json-rpc will break on certain exceptions. This is with json-rpc version 1.10.3 and Django 1.9.6.

If an exception is raised with code like raise Exception(foo), where foo is not serializable, then json-rpc doesn't return a proper JSON response.

Here is an example stack trace:

Traceback (most recent call last):
  File ".../python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File ".../python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File ".../python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File ".../python3.5/site-packages/jsonrpc/backend/django.py", line 65, in jsonrpc
    response = response.json
  File ".../python3.5/site-packages/jsonrpc/base.py", line 85, in json
    return self.serialize(self.data)
  File ".../python3.5/site-packages/jsonrpc/backend/django.py", line 62, in serialize
    return json.dumps(s, cls=DatetimeDecimalEncoder)
  File "/usr/lib/python3.5/json/__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.5/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.5/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File ".../python3.5/site-packages/jsonrpc/utils.py", line 53, in default
    return json.JSONEncoder.default(self, o)
  File "/usr/lib/python3.5/json/encoder.py", line 180, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Foo object> is not JSON serializable

In the case of handling an exception, it seems like json-rpc should be able to fall back to something like calling repr() on the exception, instead of insisting that the exception be serializable.

This is because the developer doesn't necessarily have control over what exceptions are raised (e.g. if they come from third-party code, etc).

Add names for django's views

Hi!
It's a veeeeery goooood idea to add names for django's views.
Just replace this

    @property
    def urls(self):
        urls = [
            url(r'^$', self.jsonrpc),
            url(r'map$', self.jsonrpc_map),
        ]

with this

    @property
    def urls(self):
        urls = [
            url(r'^$', self.jsonrpc, name='endpoint'),
            url(r'map$', self.jsonrpc_map, name='map'),
        ]

in file backend/django.py.
Let's make this library better!
Thanks ;)

Uart as a transport layer

Hi,

Is is possible to use the json-rpc with uart as a transporter. Do you have any example where transport layer and protocol are separated.

Thank you

custom define for application defined errors.

the spec. mentions that "-32000 to -32099 Server error Reserved for implementation-defined server-errors."

The remainder of the space is available for application defined errors.
Could we have custom define errors for application in the future?
Like:

    return JSONRPCError(-32000, "Empty Request").as_response()

or just let user define class JSONRPCEmptyRequest(JSONRPCError)
Thanks

Support multiple callbacks

At the moment there is no way of specifying whether a response is final or if there are more responses, meaning JSON-RPC only supports a single response for each request. This means it does not cover use-cases where the server sends response data as it comes in, rather than having to wait for all the response data to complete and then send it. Think for an example of a search engine that uses JSON-RPC.

I suggest simply adding a field called complete which indicates whether this is the last response for the given request id.

output is referenced before assignment error

If function does not return output, django manager returns 500 error: reference before assignment.

Function:

def echo(request=None, text=None):
    send_mail(text)

default django client is used. Request:

{jsonrpc: "2.0", id: "0", method: "echo", params: {text: "My text"}}

Server response:

Traceback (most recent call last):
  File "~/.env/lib/python3.4/site-packages/django/contrib/staticfiles/handlers.py", line 64, in __call__
    return self.application(environ, start_response)
  File "~/.env/lib/python3.4/site-packages/django/core/handlers/wsgi.py", line 187, in __call__
    response = self.get_response(request)
  File "~/.env/lib/python3.4/site-packages/django/core/handlers/base.py", line 199, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "~/.env/lib/python3.4/site-packages/django/core/handlers/base.py", line 236, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "~/.env/lib/python3.4/site-packages/django_extensions/management/technical_response.py", line 5, in null_technical_500_response
    six.reraise(exc_type, exc_value, tb)
  File "~/.env/lib/python3.4/site-packages/six.py", line 659, in reraise
    raise value
  File "~/.env/lib/python3.4/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "~/.env/lib/python3.4/site-packages/jsonrpc/backend/django.py", line 52, in jsonrpc
    jsonrpc_request, self.dispatcher)
  File "~/.env/lib/python3.4/site-packages/jsonrpc/manager.py", line 75, in handle_request
    responses = [r for r in cls._get_responses(rs, dispatcher)
  File "~/.env/lib/python3.4/site-packages/jsonrpc/manager.py", line 75, in <listcomp>
    responses = [r for r in cls._get_responses(rs, dispatcher)
  File "~/.env/lib/python3.4/site-packages/jsonrpc/manager.py", line 129, in _get_responses
    yield output
UnboundLocalError: local variable 'output' referenced before assignment

Quickfix:

def echo(request=None):
    send_mail()
    return ""

Add contribution guidelines

Add documentation on how to write a code, what code to write and additional changes.

  1. What does this library do: no dependencies. It does not test django/flask compatibility matrix.
  2. Code should be covered with tests and documentation written for function as well as in docs/ if appropriate. If commit breaks test I would not merge.
  3. If you want to improve, good way is to ask questions first and then submit pull request.
  4. On your contribution add you name to AUTHORS list
  5. Make commits flat. All of the fixes should be squashed and formed into clear release. Majority of this library's history it was not the case, changing now.

Client API?

Would this package consider supplying a client API similar to this one?

If the getaddr tricks give people the willies, an alternative might be to explicitly initialize each remote method, for example:

from jsonrpc import Remote

# Optional kwargs for jsonrpc, headers
my_remote = Remote(url)
my_remote.add_method('echo')
my_remote.add_method('ping', notify=True)

response = my_remote.echo('foobar')
print response.result

my_remote.ping()  # returns None

client example

Hi

I want to test ur server with advanced rest client
but some param is wrong

what must I write in raw payload panel?

thanks

Help! How to set a new JSONEncoder

When my server try respone some data including bson`s objectid:

TypeError: ObjectId('5840edd2f04ba72b510184bf') is not JSON serializable

I know that should set a new JSONEncode, but how?

Server issued notifications

I would like to push some notifications from the server down to the client.
From the looks of it, json-rpc does not supports such use case, or does it?

HTTPS w/TLS support

Dear all,

Does this library support establishing connections to a JSON-RPC server over HTTPS?

I am currently using RPC4Django that implements a JSON-RPC interface over HTTPS (externally handled by Apache).

Thanks, Ricardo.

Fails to return null

I want to return null as a result. I expect like {"jsonrpc": "2.0", "result": null, "id": 0}, but it throws exceptions: ValueError: Either result or error should be used and UnboundLocalError: local variable 'output' referenced before assignment.
I think the reason is that it takes None as not defined and ignores null.
Would you correct this problem?

Example code:

from jsonrpc import JSONRPCResponseManager, dispatcher

dispatcher["nop"] = lambda: None

data = '{"jsonrpc": "2.0", "method": "nop", "params": [], "id": 0}'
JSONRPCResponseManager.handle(data, dispatcher)

This prints (python3.4):

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 119, in _get_responses
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 96, in response
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/base.py", line 62, in __init__
ValueError: Either result or error should be used

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "foo.py", line 6, in <module>
    JSONRPCResponseManager.handle(data, dispatcher)
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 58, in handle
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 74, in handle_request
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 74, in <listcomp>
  File "/usr/local/lib/python3.4/dist-packages/json_rpc-1.8.0-py3.4.egg/jsonrpc/manager.py", line 122, in _get_responses
UnboundLocalError: local variable 'output' referenced before assignment

Werkzeug python 3.3 manager.py exception in handle() method

Hi pavlov99

First of all Thank You for good job done in json-rpc package!

i got exception when testing example provided on python package page for json-rpc. It concern changes in Werkzeug guess due to python v3 when request is encoded as bytes instead of string like in python v2. Managed solve it by change in manager.py (see bottom of mail)

My current setup is centos 6.5 virtual machine virtualenv and package information as below:
(app1)[root@localhost python3.3]# pip list
gevent (1.0)
greenlet (0.4.2)
hiredis (0.1.2)
json-rpc (1.1)
lxml (3.2.5)
pip (1.4.1)
redis (2.9.0)
requests (2.2.0)
setuptools (0.9.8)
tinyrpc (0.5)
uWSGI (2.0)
WebOb (1.3.1)
Werkzeug (0.9.4)
(app1)[root@localhost python3.3]# python -V
Python 3.3.3
(app1)[root@localhost python3.3]#

It can be solved by following modification to start of handle function and for backward compatibility type checking can be done on request string as below :

in manager.py
JSONRPCResponseManager.handle()

@classmethod
def handle(cls, request_str, dispatcher):
    try:
        if isinstance(request_str, bytes):<- modified start*************
            json.loads(request_str.decode("utf-8"))
        else:
            json.loads(request_str) <- modified block end *****************
    except (TypeError, ValueError):
        return JSONRPC20Response(error=JSONRPCParseError()._data)

    try:
        if isinstance(request_str, bytes): <- modified start ******************
            request = JSONRPCRequest.from_json(request_str.decode("utf-8"))
        else:
            request = JSONRPCRequest.from_json(request_str) <-- modified end *******

    except JSONRPCInvalidRequestException:
        return JSONRPC20Response(error=JSONRPCInvalidRequest()._data)

    rs = request if isinstance(request, JSONRPC20BatchRequest) \
        else [request]
    responses = [r for r in cls._get_responses(rs, dispatcher)
                 if r is not None]

    # notifications
    if not responses:
        return

    if isinstance(request, JSONRPC20BatchRequest):
        return JSONRPC20BatchResponse(*responses)
    else:
        return responses[0]

it would be nice to be able to return None from jsonrpc calls

I have API calls I'd like to return None from (i.e. no results returned)... however jsonrpc doesn't allow this (see line 62 at https://github.com/pavlov99/json-rpc/blob/master/jsonrpc/base.py)

  File "/home/xcp/counterpartyd_build/env/lib/python3.3/site-packages/jsonrpc/manager.py", line 56, in handle
    responses = [r for r in cls._get_responses(rs, dispatcher)
  File "/home/xcp/counterpartyd_build/env/lib/python3.3/site-packages/jsonrpc/manager.py", line 56, in <listcomp>
    responses = [r for r in cls._get_responses(rs, dispatcher)
  File "/home/xcp/counterpartyd_build/env/lib/python3.3/site-packages/jsonrpc/manager.py", line 104, in _get_responses
    yield response(result=result)
  File "/home/xcp/counterpartyd_build/env/lib/python3.3/site-packages/jsonrpc/manager.py", line 77, in <lambda>
    request.JSONRPC_VERSION](_id=request._id, **kwargs)
  File "/home/xcp/counterpartyd_build/env/lib/python3.3/site-packages/jsonrpc/base.py", line 62, in __init__
    raise ValueError("Either result or error should be used")
ValueError: Either result or error should be used

Could we take that line out? Any negatives to doing that?

Add support for flask blueprints subdomains

Description

Currently it is not possible to natively use flask blueprints subdomains wildcards, because JSONRPCAPI.jsonrpc method in flask backend doesn't handle additional argument if blueprint subdomain is defined as a wildcard, i.e.

    app.register_blueprint(api.as_blueprint(), subdomain='<subdomain>')

In this way, the api can be used through api.example.com or api2.example.com or other.example.com.

Steps to Reproduce

  1. Define api endpoint
  2. Register endpoint as a blueprint with wildcard subdomain
  3. Perform call to an endpoint

Expected behavior: api can be used through registered endpoint and subdomain wildcard is available in the jsonrpc method.

Actual behavior: jsonrpc raises an exception, that it can't accept additional argument, i.e. subdomain.

Reproduces how often: always

Versions

  • Ubuntu 16.04
  • Python 3.6.3
  • nginx 1.10.3 or /etc/hosts
  • json-rpc 1.10.8

Additional Information

I can see there are multiple ways this can be solved. For now I am using a workaround to handle subdomains in the application, which involves nginx and setting some headers.
I would also like to contribute and make this possible, what are your thoughts on this feature?

dispatcher class methods

If I use a class to hold the dispatcher methods and decorate them with @dispatcher.add_method
I always get "Invalid params" code: -32602.

I have to add a parameter 'self':None to the request to get this to work.

Thank you

question: use it with flask to a demo,but the requested url not found.

run.py

from flask import Flask

from jsonrpc.backend.flask import api

app = Flask(__name__)
app.register_blueprint(api.as_blueprint())
app.add_url_rule('/', 'api', api.as_view())

@api.dispatcher.add_method
def my_method(*args, **kwargs):
    return args, kwargs

if __name__ == '__main__':
    app.run(debug=True)

then i use postman to post the url : localhost:5000/api/

data:{
"jsonrpc": "2.0",
"id": "1111",
"method": "my_method",
"params": ["1"]
}


response 404


help~

json string -> JSONRPC20Response

I receive a JSON string and want to construct a JSONRPC20Response object, like:

JSONRPC20Response.from_json(my_str) or JSONRPC20Response(**json.loads(my_str))

However, JSONRPC20Response expects _id instead of id, so the response's id is always None.

I realize I could simply do JSONRPC20Response(_id=obj.get('id'), ...) but it seems like there should be a more natural way. I would expect the object representation of a response to be easily constructed from a JSON response. Maybe I'm missing something?

Chat api

Hi

I want to make a simple chat server with this api but it is staighless how can I send a interrupt to the client for fetching messages?

if I use "always check" data, it become harmful for the server

any ideas?

UnboundLocalError: local variable 'output' referenced before assignment

Unexpectedly occurs. Seems pretty clear.
Version: json-rpc==1.9.0

File "/app_path/.env/local/lib/python2.7/site-packages/jsonrpc/manager.py", line 59, in handle
    return cls.handle_request(request, dispatcher)
  File "/app_path/.env/local/lib/python2.7/site-packages/jsonrpc/manager.py", line 75, in handle_request
    responses = [r for r in cls._get_responses(rs, dispatcher)
  File "/app_path/.env/local/lib/python2.7/site-packages/jsonrpc/manager.py", line 129, in _get_responses
    yield output
UnboundLocalError: local variable 'output' referenced before assignment

Change _dict -> _data

field with data should be changed to avoid misunderstanding with batchrequest._dict (it is list)

Way to pass additional data to dispatcher? [question/feature request]

I need to pass some additional data to the request dispatcher (a connection ID)

What is the best way to accomplish this? Currently I'm munging the request like so:

def munge_request(request, client_id):
    try:
        if isinstance(request, bytes):
            decoded = request.decode("utf-8")
        parsed = json.loads(decoded)
        if 'params' in parsed:
            parsed["params"] = {"orig_params": parsed["params"], "client_id": client_id}
        return json.dumps(parsed)
    except Exception as e:
        log.error("Munge_request caught exception! %s" % e)
        return request

This is obviously not optimal for multiple reasons. Is there a better way?

Variable number of args and kwargs for handler functions

Hi

I couldn't find anything about this in the docs:
Does this library support a variable number of args and kwargs for a handler function?

Example:

@dispatcher.add_method
def foobar(*args, **kwargs):
    return kwargs["foo"] + kwargs["bar"] + args[0]

License file in pypi archive

The pypi source archive isn't including the LICENSE.txt file. Would it be possible to add it? It is very helpful when packaging this for Linux distributions. Thank you.

Consider accepting params=None for JSON-RPC 1.0

We are dealing with a client library that sends "params": null in a JSON-RPC 1.0 "hello" request, which is rejected by JSONRPC10Request.from_json() (as specifically tested by TestJSONRPC10Request.test_params_validation_none()) because it's not a list.

The JSON-RPC 2.0 Specification states the following:

If present, parameters for the rpc call MUST be provided as a Structured value. Either by-position through an Array or by-name through an Object.

but the JSON-RPC 1.0 Specification just says

params - An Array of objects to pass as arguments to the method

which makes it pretty clear that an empty array is what's expected if you want to pass zero params, but isn't totally definitive on whether null/None is a valid value.

Would it cause any problems to treat null as if it's an empty list for JSON-RPC 1.0?

The implementation might look like:

# JSONRPC10Request
@params.setter
def params(self, value):
    value = value if value is not None else []  # <= New line
    if not isinstance(value, (list, tuple)):
        raise ValueError("Incorrect params {0}".format(value))

    self._data["params"] = list(value)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.