Giter Site home page Giter Site logo

cenobites / flask-jsonrpc Goto Github PK

View Code? Open in Web Editor NEW
287.0 287.0 64.0 1.75 MB

Basic JSON-RPC implementation for your Flask-powered sites

License: Other

Python 80.17% JavaScript 5.41% CSS 7.52% HTML 3.82% Makefile 0.37% Shell 2.71%
flask flask-extensions jsonrpc python

flask-jsonrpc's People

Contributors

alexted avatar ash211 avatar dependabot[bot] avatar hualongsd avatar ireardon avatar jameshilliard avatar jordanfung avatar langimike avatar nycholas avatar obi1kenobi avatar shanehh avatar timgates42 avatar

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

flask-jsonrpc's Issues

Bug validate

Work

@jsonrpc.method('add(a=int, b=int)')
def add(a, b)->int:
    ...

And work

@jsonrpc.method('add(a=int, b=int)')
def add(a: int, b: int):
    ...

And work

@jsonrpc.method('add(a=int, b=int)')
def add(a: int, b: int)->int:
    ...

Use of flask-jsonrpc with gevent

Hello,

do you know any issue involving use of flask-jsonrpc with gevent ?

I've realized an API that use Blueprint, following your modular example.
In normal way (http) it works correctly.
Using WSGIServer (https) I've always get exception MethodNotFoundError.

app = Flask(__name__)
jsonrpc = JSONRPC(app, '/api', enable_web_browsable_api=True)
http_server = WSGIServer((Config.host, Config.port), app,
                         keyfile=Config.app_path + "\privkey.pem",
                         certfile=Config.app_path + "\cacert.pem")

I try to put jsonrpc instead of app in the call of WSGIServer, but it doesn't work, I get back TypeError: 'JSONRPC' object is not callable.

Can you help me ?

Thanks in advice, best regards

Giuseppe Garzotto

CORS?

how to provide 'Access-Control-Allow-Origin' header automatically?
i'm try to use this decorator http://flask.pocoo.org/snippets/56/ but no.

@crossdomain(origin='*', methods=['GET', 'OPTIONS', 'POST'])
@jsonrpc.method('addSession')
def addSession(params):
      ...

0.2 not in pypi?

pip install --upgrade flask-JSONRPC

Version 0.1 is installed by this command. Version 0.2 does not appear in pypi although its documentation is updated to 0.2 on its pypi page.

$ pip install flask-JSONRPC==0.2 Could not find a version that satisfies the requirement flask-JSONRPC==0.2

Multiple JSONRPCSites are not supported

_site_api always uses default_site, so you can't define separate JSONRPCSites for different JSONRPC instances, which means you can't use different URL paths accepting JSON queries with same method names (which may be very useful in REST apps handling many similar clients).
However, this issue is easy to fix - all you need is wrap "_site_api" to "View" class, define "dispatch_request" method which accepts "site" as param, and rewrite "add_url_rule"s, (use unique "endpoints" and pass self.site to View constructor).
I can provide this patch, but my version (installed from pip) differs from master branch.

Support For Default/Optional Arguments

Before I go off and try to implement this, do you think it's possible?

If the bound function has defaulted arguments, maybe fill in the web UI with the default value (if possible to retrieve), or just mark it as non-required to hit the 'send' button.

Example:

jsonrpc = JSONRPC(app, '/api', enable_web_browsable_api=True)

@jsonrpc.method('foo(int)->bool')
def foo(x=100):
    return True;

Thanks! If you cannot implement this but think it's possible, I think I can tackle it!

Add support for functions with type annotations

It looks like the API used by Flask-JsonRPC to inspect functions (as of version 0.3.1) is not compatible with typing annotations...

Example:

@jsonrpc.method('Test.Ping')
def ping() -> str:
    return 'pong'

causes the following exception:

Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    class Server:
  File "./test.py", line 29, in Server
    def ping() -> str:
  File "/home/abustany/test/.direnv/python-3.7.1/lib/python3.7/site-packages/flask_jsonrpc/__init__.py", line 225, in decorator
    arg_names = getargspec(f)[0]
  File "/usr/lib64/python3.7/inspect.py", line 1080, in getargspec
    raise ValueError("Function has keyword-only parameters or annotations"
ValueError: Function has keyword-only parameters or annotations, use getfullargspec() API which can support them

UnicodeDecodeError causes 500 Error

Hi, HTTP 500 error occurred when calling rpc in browsable webconsole:

Traceback (most recent call last)

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1836, in __call__

    return self.wsgi_app(environ, start_response)

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1820, in wsgi_app

    response = self.make_response(self.handle_exception(e))

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1403, in handle_exception

    reraise(exc_type, exc_value, tb)

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1817, in wsgi_app

    response = self.full_dispatch_request()

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1477, in full_dispatch_request

    rv = self.handle_user_exception(e)

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1381, in handle_user_exception

    reraise(exc_type, exc_value, tb)

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1475, in full_dispatch_request

    rv = self.dispatch_request()

    File "C:\Python27\lib\site-packages\flask-0.10-py2.7.egg\flask\app.py", line 1461, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

    File "C:\Python27\lib\site-packages\flask_jsonrpc-0.2-py2.7.egg\flask_jsonrpc\__init__.py", line 158, in wrapper

    response_dict, status_code = site.dispatch(request, method)

    File "C:\Python27\lib\site-packages\flask_jsonrpc-0.2-py2.7.egg\flask_jsonrpc\site.py", line 267, in dispatch

    raw_data = extract_raw_data_request(request)

    File "C:\Python27\lib\site-packages\flask_jsonrpc-0.2-py2.7.egg\flask_jsonrpc\helpers.py", line 56, in extract_raw_data_request

    raw_data = _extract_raw_data_request(request)

    File "C:\Python27\lib\site-packages\flask_jsonrpc-0.2-py2.7.egg\flask_jsonrpc\helpers.py", line 52, in _extract_raw_data_request

    return u(request.data)

    File "C:\Python27\lib\site-packages\flask_jsonrpc-0.2-py2.7.egg\flask_jsonrpc\_compat.py", line 85, in u

    return unicode(s)

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 64: ordinal not in range(128)

This problem doesn't exist when using version 787fb55 (2013/11/21). There's Chinese character in posted JSON(utf-8 encoded).

ServiceProxy(): Forces JSON strings to be url decoded

Currently ServiceProxy() uses urllib, which in Python 2.x doesn't allow for HTTP header modification. This becomes an issue when trying to send JSON strings with characters that contain values that look like url-encoded characters. By default urllib sends POST data with the HTTP header "Content-Type" set to "application/x-www-form-urlencoded". The JSON client should be using "application/json" for the "Content-Type" in the HTTP header. The following code is meant to demonstrate the problem:

Server:

from flask import Flask
from flask_jsonrpc import JSONRPC
app = Flask("DEBUG")
annote = JSONRPC(app,'/DEBUG',enable_web_browsable_api=True)
@annote.method('one(str)->str')
def one(instr):
    print("string is %s" % instr)
    return instr

app.run(host='0.0.0.0',port=5001,debug=True)

Client:

from flask_jsonrpc.proxy import ServiceProxy
s=ServiceProxy('http://0.0.0.0:5001/DEBUG')
print(s.one('No%20Space'))

Resulting output:

{u'jsonrpc': u'2.0', u'id': u'df4932b0-8551-11e4-86b1-0026b9641702', u'result': u'No Space '}

The "%20" was decoded into a space (" ").

The solution for this would be to replace urllib with urllib2 in _compat.py and subsequently the import of urllib in ServiceProxy(). The default HTTP header "Content-Type" should be set to "application/json" but there will be a overriding parameter available so users can provide their own HTTP headers dictionary.

The following are code snippets that illustrate the solution:

_compat.py:

For PY3:

encode_filename = _identity
    get_next = lambda x: x.__next__

    from urllib.parse import urlparse
    from urllib.request import urlopen
    from urllib.request import Request

For PY2:

        return filename

    from urlparse import urlparse
    from urllib2 import urlopen
    from urllib2 import Request

proxy.py:

class ServiceProxy(object):

    DEFAULT_HEADERS = {"Content-Type":"application/json"}

    def __init__(self, service_url, service_name=None, version='2.0', headers=None):
        self.headers = headers or self.DEFAULT_HEADERS
        self.version = text_type(version)
...
...
...
    def send_payload(self, params):
        """Performs the actual sending action and returns the result
        """
        data = json.dumps({
            'jsonrpc': self.version,
            'method': self.service_name,
            'params': params,
            'id': text_type(uuid.uuid1())
        })
        data_binary = data.encode('utf-8')
        url_request = Request(self.service_url,data_binary,headers=self.headers)
        return urlopen(url_request).read()

Thanks for taking a look!

Invalid JSON RPC 2.0 error responses

Some errors cause response objects that violate the JSON RPC 2.0 spec, because they have both, a "result" and "error" member set. An example would be MethodNotFoundError.

See https://github.com/cenobites/flask-jsonrpc/blob/723db17b1ef11d15d4180fd0e372b9a51723f4e4/flask_jsonrpc/site.py#L186-195 .
It seems that the version is initialized to late in the marked block and early exceptions are handled with the JSON RPC 1.0 spec, because the version_hint is always "1.0".

"InvalidRequestError: Unterminated string" with equals sign in params

I'm getting an "InvalidRequestError: Unterminated string" error when I include an equals sign in a string param.

Test app:

from flask import Flask
from flask_jsonrpc import JSONRPC

app = Flask(__name__)
jsonrpc = JSONRPC(app, '/api')

@jsonrpc.method('echo')
def echo(s):
  return s

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

Success:

$ curl -i -X POST -d '{"jsonrpc": "2.0", "method": "echo", "params": ["hello"], "id": "1"}' http://localhost:5000/api
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 58
Server: Werkzeug/0.10.4 Python/2.7.5
Date: Fri, 10 Jul 2015 19:56:43 GMT

{
  "id": "1", 
  "jsonrpc": "2.0", 
  "result": "hello"
}

Unexpected failure:

$ curl -i -X POST -d '{"jsonrpc": "2.0", "method": "echo", "params": ["hello=world"], "id": "1"}' http://localhost:3431/api
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 473
Server: Werkzeug/0.10.4 Python/2.7.5
Date: Fri, 10 Jul 2015 19:56:48 GMT

{
  "error": {
    "code": -32600, 
    "data": null, 
    "executable": "/usr/bin/python", 
    "message": "InvalidRequestError: Unterminated string starting at: line 1 column 49 (char 48)", 
    "name": "InvalidRequestError", 
    "stack": "Traceback (most recent call last):\n  File \"/usr/lib/python2.7/site-packages/flask_jsonrpc/site.py\", line 281, in dispatch\n    raise InvalidRequestError(e.message)\nInvalidRequestError\n"
  }, 
  "id": null, 
  "result": null
}

I'm on CentOS 7 with up to date packages:

$ sudo pip install flask-jsonrpc --upgrade
Requirement already up-to-date: flask-jsonrpc in /usr/lib/python2.7/site-packages
Requirement already up-to-date: Flask>=0.9 in /usr/lib/python2.7/site-packages (from flask-jsonrpc)
Requirement already up-to-date: Werkzeug>=0.7 in /usr/lib/python2.7/site-packages (from Flask>=0.9->flask-jsonrpc)
Requirement already up-to-date: Jinja2>=2.4 in /usr/lib/python2.7/site-packages (from Flask>=0.9->flask-jsonrpc)
Requirement already up-to-date: itsdangerous>=0.21 in /usr/lib/python2.7/site-packages (from Flask>=0.9->flask-jsonrpc)
Requirement already up-to-date: markupsafe in /usr/lib64/python2.7/site-packages (from Jinja2>=2.4->Flask>=0.9->flask-jsonrpc)
Cleaning up...

Thanks!

Add extended data validation library support for method parameters

There's currently some basic data validation for methods, but it only supports type validation (i.e., verify parameter is dict, int, str, etc.). It would be nice if users could utilize an external library like Cerberus to validate the data inside the extension rather than unpacking all of the variables inside of the view itself.

I could probably get the feature implemented myself and submit a pull request, but as I said in the last issue report I opened, there aren't any contributing guidelines so I'm not sure what the next step of that would be.

add license to all code files

I noticed that the .py scripts do not contain a proper license header but only a copyright line. Please add the contents of COPYING to all code files if they are under the respective license.

Error's pass as HTML200's to the frontend. They don't show up as output of python console (ehen debugging is on)

When developing an API backend with flask_jsonrpc and a seperate backend API errors are being
sent to the frontend as regular correct 200 responses with the Error encoded as JSON. So far so good and
i can understand that design desision. The built in Web browsable API shows the error message as a normal valid JSONRPC result.

However when the API get's more complex and the Web browsable API becomes to cumbersome to use (because let's say 50 or 100 fields have to be filled to generate a API request) you will want to use your custom frontend. But "errors" are just being sent as valid 200 responses.

It would be nice to (when the debug mode is on) the json error message is also being printed to the python console. Otherwise JSONSRPC error's especially the OtherError's will just dissapear when the frontend does not log them.

It would be a simple change:

exceptions.py line 80 add:

76 if current_app.config['DEBUG']:
77 import sys, traceback
78 error['stack'] = traceback.format_exc()
79 error['executable'] = sys.executable
80 print(error)

Parameters not see url /api/browse in decorators

Parameters not see in decorators between

Work in url /api/browse

@jsonrpc.method('tag.add')
def tag_add(name):

Not work in url /api/browse

@jsonrpc.method('tag.add')
@exampleDecorator
def tag_add(name):

Incorrect path used for browse interface

When flask_jsonrpc is used with browse enabled on a non-root script path, the browse functionality does not work. It just shows a blank page with a header bar.

This appears to be due to within the file views/browse/__init__.py the function index starts with:
url_prefix = request.path
but if the application is not deployed to the root URL path this is not correct and should instead be:
url_prefix = request.script_root + request.path
as described in https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data

Decimal cannot be json.dumps()

I cannot return the result of db search which contain the type of Decimal directly.
My solution is like this:

class EnhancedJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            ARGS = ('year', 'month', 'day', 'hour', 'minute',
                     'second', 'microsecond')
            return {'__type__': 'datetime.datetime',
                    'args': [getattr(obj, a) for a in ARGS]}
        elif isinstance(obj, datetime.date):
            ARGS = ('year', 'month', 'day')
            return {'__type__': 'datetime.date',
                    'args': [getattr(obj, a) for a in ARGS]}
        elif isinstance(obj, datetime.time):
            ARGS = ('hour', 'minute', 'second', 'microsecond')
            return {'__type__': 'datetime.time',
                    'args': [getattr(obj, a) for a in ARGS]}
        elif isinstance(obj, datetime.timedelta):
            ARGS = ('days', 'seconds', 'microseconds')
            return {'__type__': 'datetime.timedelta',
                    'args': [getattr(obj, a) for a in ARGS]}
        elif isinstance(obj, decimal.Decimal):
            '''
            return {'__type__': 'decimal.Decimal',
                    'args': [str(obj),]}
            '''
            return float(obj)
        else:
            return super().default(obj)


class EnhancedJSONDecoder(json.JSONDecoder):

    def __init__(self, *args, **kwargs):
        super(EnhancedJSONDecoder, self).__init__(*args, object_hook=self.object_hook,
                         **kwargs)

    def object_hook(self, d):
        if '__type__' not in d:
            return d
        o = sys.modules[__name__]
        for e in d['__type__'].split('.'):
            o = getattr(o, e)
        args, kwargs = d.get('args', ()), d.get('kwargs', {})
        return o(*args, **kwargs)

def execute_select_sql(sql):
    """excute SELECT SQL """


    try:
        db = get_db_connect()
        cursor = db.cursor()
        print 'execute sql is [{}]'.format(sql)
        cursor.execute(sql)
        data = cursor.fetchall()
        try:
            json_data = json.dumps(data, cls=EnhancedJSONEncoder)
            data = json.loads(json_data, cls=EnhancedJSONDecoder)
        except UnicodeDecodeError as e:
            data = 'Don not select BLOB!!!'
        except Exception as e:
            data = repr(e)

    except Exception as e:
        print repr(e)
        raise e
    else:
        print 'data is [{}]'.format(data)
        return data
    finally:
        try:
            db.close()
        except:
            pass

@jsonrpc.method('run_sql')
def run_sql(sql):
    return execute_select_sql(sql)

Web browsable API does not encode booleans correctly

Sending a boolean as an argument to a route gets encoded as a dictionary -- if you set validate=True, you'll always get the response '"message": "InvalidParamsError: <type 'dict'> is not the correct type <type 'bool'> for ...', if you do not set validate=True, then every argument is considered "truthy".

The API works correctly when using curl directly.

The problem can be created by running the app below (Flask 0.10.1, Flask-JSONRPC 0.3), and navigating to http://localhost:5000/api/browse/#/say

from flask import Flask                                         
from flask_jsonrpc import JSONRPC                               

app = Flask(__name__)                                           
jsonrpc = JSONRPC(app, '/api', enable_web_browsable_api=True)   


@jsonrpc.method('say(hi=bool) -> String', validate=True)        
def say(hi=False):                                              
    if hi:                                                      
        return "hi"                                             
    return "bye"                                                


@jsonrpc.method('nsay(n=int, hi=bool) -> String', validate=True)
def nsay(n=5, hi=False):                                        
    if hi:                                                      
        return n * "hi "                                        
    return n * "bye "                                           


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

Parameters order for Error Exception Class

Based on pull request 51 which allows setting a value for "data"...

The actual parameters order for Error Class is:

def __init__(self, message=None, code=None, data=None):

In order to set a value for "data" without setting the "message", we must adjust our code and use a named argument:

raise InvalidParamsError(data='This value cannot be an integer.')

But this module (flask-jsonrpc) still raises exceptions using positioned arguments, like:

InvalidRequestError('The method you are trying to access is not availble by GET requests')

It sets 'The method you are trying to access is not availble by GET requests' to message instead of data.

"data": null,
"message": "The method you are trying to access is not availble by GET requests",

While the correct should be:

"data": "The method you are trying to access is not availble by GET requests",
"message": "Invalid Request.",

So the problem is: should this module use named argument for setting data or should the Error class change the parameters order to data come first to messsage for the first argument be always a data by default?

500 error (decoding Unicode is not supported) on OPTIONS request using JS libs

Hi,

When calling the API from either of these two JS libraries:

I get a 500 error returned and a traceback looking like this:

[2016-08-19 12:35:59,471] ERROR in app: Exception on /api [OPTIONS]
Traceback (most recent call last):
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask/app.py", line 1988, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask/app.py", line 1641, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask_cors/extension.py", line 188, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask/app.py", line 1544, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask/app.py", line 1639, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask/app.py", line 1625, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask_jsonrpc/__init__.py", line 163, in wrapper
    response_obj, status_code = site.dispatch(request, method)
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask_jsonrpc/site.py", line 362, in dispatch
    raw_data = extract_raw_data_request(request)
  File "/home/flyte/.virtualenvs/herkulex/local/lib/python2.7/site-packages/flask_jsonrpc/helpers.py", line 82, in extract_raw_data_request
    return text_type(raw_data, encoding)
TypeError: decoding Unicode is not supported
127.0.0.1 - - [19/Aug/2016 12:35:59] "OPTIONS /api HTTP/1.1" 500 -

I'm able to consume the API fine using the Python ServiceProxy.

Is this intended behavior? If so, how do I stop the JS clients from using Unicode?

Thank you.

OtherError in not a valid JSON RPC 2.0 error response

Hello,

error OtherError message looks like

{
  "code": -32001,
  "data": null,
  "message": "OtherError: Invalid Terminal ID u'tid01x'",
  "name": "OtherError"
}

but a a malformed JSON RPC request error looks like

{
    "error": {
        "code": -32000,
        "message": "Not a valid JSON RPC request"
    },
    "id": null,
    "jsonrpc": "2.0"
}

Every error message should be JSON RPC 2.0 error response
moreover they can sometimes have id different from null so
we should provide a way to set id (maybe in constructor with id=None as default value)

Kind regards

High load?

When i'm give high load (5-10 connections at second from browsers via ajax) on simple server, writen with this lib, i have 'connection timed out'.
Without high load all work fine.
all json-rpc methods simple and no any special (no db connections or any long operations).

Ability to use digest and basic auth

I did't find how can i use this two types to auth. It is not a good idea for me to send username and password as params. If somebody know how to use basic auth with this component please tell me. I am new in python and flask :)

unicode error

There is an error at function extract_raw_data_request._extract_raw_data_request in file helpers.py, the not right code is return list(request.form.to_dict().keys())[0], this sentence maybe get a str object then will meet an Unicode Error, but I think it should be a bytes object.

I suggest correct it as return list(request.form.to_dict().keys())[0] if instance(list(request.form.to_dict().keys())[0], bytes) else list(request.form.to_dict().keys())[0].encode()

Minimum Python Client Example

Prior to version 1.0, for a python flask client, I was using,

from flask_jsonrpc.proxy import ServiceProxy

based on the example here and here

but ServiceProxy no longer imports, and I can't find any documentation on how to jsonrpc from python.

The documentation for blueprints isn't clear on how they work

I'd like to know how blueprints actually work in Flask-JSONRPC; the only thing the examples look to be doing is registering the blueprint itself, but the methods on it are registered to the toplevel JSONRPC instance, instead of one for the blueprint itself:

from base_app import jsonrpc  # the one from the toplevel app
from flask import Blueprint

bp = Blueprint(__name__)

# if I had a method here:
@bp.route("/')
def method():
    pass

# but for the JSONRPC, the blueprint doesn't seem to be used:
@jsonrpc.method("BluePrint.a_method")
def a_method():
    pass

I'd expect something like this:

from flask_jsonrpc import JSONRPC
from flask import Blueprint

bp = Blueprint(__name__)
bprpc = JSONRPC(blueprint=bp)

@bprpc.method("a_method")
def a_method():
    pass

from base_app import jsonrpc
jsonrpc.register_blueprint("TopLevel", bprpc)

This would end up being called as TopLevel.a_method.

I'm not sure this makes sense, but it lines up with my intuition about how blueprints work.

No logging facility in use for extension

I'm using flask-jsonrpc for a project of mine, and I can't seem to find a way to report or log the logging or exceptions that are caught in the repository.

For instance, if someone tries to use a non-existant method, or sends a bad parameter, there is no way for me to log that I can find.

EDIT: After I read through the code, I've realized that I can't override or use the logging facility because there is no logging facility. So I guess this isn't a bug request or issue, as much as it is a feature request for the addition of a logging facility.

Some basic usage would be logging when a user accesses a method, what method is accessed, if there is/was an error with the JSONRPC backend, etc.

If necessary, I can add some code and submit a pull request. Just let me know what the preferred path is for this. I can't find any contributing guidelines.

Does not support member functions

It would be nice to not restrict this to work on plain functions or static methods.

I think a lot of people would like to use this library like this:

from flask import Flask
from flask_jsonrpc import JSONRPC

class Test:
	app = Flask(__name__)
	jsonrpc = JSONRPC(app, '/api', enable_web_browsable_api=True)

	@jsonrpc.method('App.sum(Number, Number) -> Number', validate=True)
	def sum_(self, a, b):
		return a + b

	def run(host='0.0.0.0', port=3500):
		self.app.run(host=host, port=port, debug=True)

if __name__ == '__main__':
	Test().app.run()

api

Running curl would require 3 arguments, but it does "work":

$ curl -v -XPOST -H "Content-type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method" : "App.sum", "params":[1,1,2]}' 'http://localhost:5000/api'
{"id":1,"jsonrpc":"2.0","result":3}

Automatic Javascript API

It would be amazing if flask-jsonrpc could auto-serve (potentially jQuery-based) Javascript classes generated from the registered methods, as a script that can be easily loaded by HTML in a browser. As it is I would still have to write the browser client part of the transaction.

Equals Sign in Strings Returns Invalid Request

If a string passed to the JSON-RPC api contains the character =, the API returns "Invalid Request Error". This is problematic, especially for Base64 encoded text, as the = character is padded to the end of the string.

Authentication backend assumes username and password (was marked as ToDo)

In init.py (line 228-229) the authentication backend assumes that a username and password is given in the check_auth function that is given in the api.method(...., authenticated=check_auth) function.

# TODO: this is an assumption
X['arg_names'] = ['username', 'password'] + X['arg_names']
X['name'] = _inject_args(X['name'], ('String', 'String'))

If you change this in:

auth_args = [x for x in authenticated.__code__.co_varnames[:authenticated.__code__.co_argcount]]
X['arg_names'] = auth_args + X['arg_names']
X['name'] = _inject_args(X['name'], tuple(["String"]) * len(auth_args))

It would dynamically use the arguments that you define in the handler in ...method.(...authenticated=check_auth). The tuple(["String"]) * len(auth_args) would however assume that the arguments used are always Strings. But i don't see why not. In that way you could use:

def check_auth(token):
    <do some magic token checking here for example>

Or any other means of authentication, instead of username and password, with any arbitrary number of arguments without having to declare them specifically in every decorator (as i saw in the Issue related to this one) , which seems a bit more DRY to me.

update: added
[:authenticated.code.co_argcount]
To only extract the agruments passed to the check_auth function, and not the internal variables

The CSRF token is missing when enabled CsrfProtect

from flask_wtf import CsrfProtect
CsrfProtect(app)

from flask_jsonrpc import JSONRPC
jsonrpc = JSONRPC(app, '/JOB/script/call/jsonrpc2')
@jsonrpc.method('create_script_interface')
def get( ):
pass

the result is :

<title>400 Bad Request</title>

Bad Request

The CSRF token is missing.

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.