Using jsonp with the django-rest-framework - jsonp

The django rest framework release notes claim that JSONP support was added back in 0.3.0. I also found a JSONPRenderer class in the framework. However, I can't seem to find any documentation on how to use the thing... I'm fairly new to jsonp.
Has anyone ever successfully used jsonp with the django rest framework?

While posting this, I found the answer (or at least AN answer). It appears that the jsonp renderer is available by default on a ModelResource, so all you need to do is add "?format=json-p" to the requesting url.

Just in case someone is looking for jsonp.
First (docs):
pip install djangorestframework-jsonp
And then modify your REST framework settings.
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework_jsonp.renderers.JSONPRenderer',
),
}
Finally make sure that your url contains ?format=jsonp and not ?format=json-p.

from rest_framework.views import APIView
from rest_framework_jsonp.renderers import JSONPRenderer, JSONRenderer
from rest_framework.response import Response
class YourClass(APIView):
renderer_classes = (JSONPRenderer, JSONRenderer)
def get(self, request, *args, **kwargs):
your_result = {{ your serialized result }}
return Response({'status': 'success', 'result': your_result})

Related

Karate: Problem with requests using bearer token | Karate is showing "org/apache/commons/codec/binary/Base64" in response instead of HTTP 401 [duplicate]

We're automating our test with karate framework. In one of our features we need to decode a token and get a scope in the response. Everything works well, except this code in js.
function(token) {
return JSON.parse(new Buffer(token.split('.')[1],'base64').toString('ascii')).scope;
}
Error:
Caused by: <eval>:2 ReferenceError: "Buffer" is not defined
Caused by: jdk.nashorn.internal.runtime.ECMAException
In official tutorials it is said that javascript is 'native' to karate, so we don't understand why Buffer is not recognized? What we should do? Thanks for any help
I was able to successfully base64Decode a JWT token payload to JSON using the following code without the need for a Java method:
Background:
* def parseJwt =
"""
function(token) {
var base64Url = token.split('.')[1];
var base64Str = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var Base64 = Java.type('java.util.Base64');
var decoded = Base64.getDecoder().decode(base64Str);
var String = Java.type('java.lang.String')
return new String(decoded)
};
"""
Scenario: JWT Token
Given path 'jwt/authenticate'
And header x-goog-authenticated-user-email = 'email'
And request {}
When method get
Then status 200
* json result = parseJwt(responseHeaders['Set-Cookie'][0])
* match result == {permissions: [1,2,3], iss: "us", exp: "#number", email: "email"}
Note: It does seem to be required to use json rather than def as Karate does better if it parses the string to json itself. Also, you may obtain the token from a header rather than a cookie as in this example if so, just change the responseHeader that you are looking for.
I'm pretty sure that Buffer is advanced / non-standard or NodeJS so it probably is not supported by the JVM JS engine (Nashorn).
Here's my recommendation. For this case, do the work using Java utilities.
For example, look at the Karate basic-auth example in the doc which uses Base64 encoding.
If it is really complex, simply create a Java static function, it will be much easier to test as a side-benefit. Hope this helps !
With respect to the post Karate: Problem with requests using bearer token | Karate is showing "org/apache/commons/codec/binary/Base64" in response instead of HTTP 401
My query was marked duplicate hence posting an answer/solution which we have found in our project.
We did some debugging in karate core about the error. It seemed a dependency was missing.
We added the dependency in the POM.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
Afterwards the problem was resolved and we started getting HTTP 401.
I am not sure it can be added to the karate core.

Flask API optional parameter is not working

I have a route that was created via flask_restplus.Api, not flask.Flask.
from flask import Flask
from flask_restplus import Api, Resource
flask_app = Flask(__name__)
app = Api(app=flask_app)
name_space = app.namespace('', description="Описание маршрутизаций")
And I would like to send an optional parameter like this, in the docs. Here is my code to send optional parameter:
from flask_restplus import Resource
#name_space.route("/structure/", defaults={'path': None})
#name_space.route("/structure/<string:path>")
#name_space.doc(params={'path': {'description': 'Get structure of a given path'}})
class struct_level(Resource):
def get(self, path):
print(path) # shows None
return method_to_work()
I've tried to change slashes in the end and to change method to post, nothing helped. Whatever value I send to 'path' parameter it returns None. If I make 'path' parameter required it works well, however I need this parameter to be optional, so that I can pass empty value.
Please, help me with an advice: how to make 'path' parameter optional in a route that was created by Api. Thanks!
P.S: Also, it is needed to be one endpoint.
I realised from my coworkers, that it is impossible to make this request in one route(endpoint). So I just had to create two endpoints, and that was ok.

Karate DSL - Converting a PNG response to Base64 [duplicate]

We're automating our test with karate framework. In one of our features we need to decode a token and get a scope in the response. Everything works well, except this code in js.
function(token) {
return JSON.parse(new Buffer(token.split('.')[1],'base64').toString('ascii')).scope;
}
Error:
Caused by: <eval>:2 ReferenceError: "Buffer" is not defined
Caused by: jdk.nashorn.internal.runtime.ECMAException
In official tutorials it is said that javascript is 'native' to karate, so we don't understand why Buffer is not recognized? What we should do? Thanks for any help
I was able to successfully base64Decode a JWT token payload to JSON using the following code without the need for a Java method:
Background:
* def parseJwt =
"""
function(token) {
var base64Url = token.split('.')[1];
var base64Str = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var Base64 = Java.type('java.util.Base64');
var decoded = Base64.getDecoder().decode(base64Str);
var String = Java.type('java.lang.String')
return new String(decoded)
};
"""
Scenario: JWT Token
Given path 'jwt/authenticate'
And header x-goog-authenticated-user-email = 'email'
And request {}
When method get
Then status 200
* json result = parseJwt(responseHeaders['Set-Cookie'][0])
* match result == {permissions: [1,2,3], iss: "us", exp: "#number", email: "email"}
Note: It does seem to be required to use json rather than def as Karate does better if it parses the string to json itself. Also, you may obtain the token from a header rather than a cookie as in this example if so, just change the responseHeader that you are looking for.
I'm pretty sure that Buffer is advanced / non-standard or NodeJS so it probably is not supported by the JVM JS engine (Nashorn).
Here's my recommendation. For this case, do the work using Java utilities.
For example, look at the Karate basic-auth example in the doc which uses Base64 encoding.
If it is really complex, simply create a Java static function, it will be much easier to test as a side-benefit. Hope this helps !
With respect to the post Karate: Problem with requests using bearer token | Karate is showing "org/apache/commons/codec/binary/Base64" in response instead of HTTP 401
My query was marked duplicate hence posting an answer/solution which we have found in our project.
We did some debugging in karate core about the error. It seemed a dependency was missing.
We added the dependency in the POM.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
Afterwards the problem was resolved and we started getting HTTP 401.
I am not sure it can be added to the karate core.

Django-Rest-Framework: How to Document GET-less Endpoint?

My co-worker implemented an API that only allows GET requests with an ID parameter (so I can GET /foo/5 but can't GET /foo/). If I try to access the API's endpoint without providing an ID parameter, it (correctly) throws an unimplemented exception.
I want to fix this endpoint to show its documentation when viewed, without an ID, over the web. However, I still want it to throw an exception when that endpoint is accessed programatically.
As I remember it, django-rest-framework is capable of distinguishing those two cases (via request headers), but I'm not sure how to define the endpoint such that it returns either documentation HTML or an exception as appropriate.
Can anyone help provide the pattern for this?
Based on the description, I would guess that the endpoint is a function based view, which is registered on a route where it listens for get requests WITH parameters. I would suggest to register another route where you will listen for get requests without parameters...
from rest_framework.decorators import api_view
from rest_framework import status
#api_view(['GET'])
def existing_get_item_api(request, item_id, *args, **kwargs):
# query and return the item here ...
pass
#api_view(['GET'])
def get_help(request, *args, **kwargs):
# compose the help
return Response(data=help, status = status.HTTP_200_OK)
# somewhere in urls.py
urlpatterns = [
url(r'api/items/(?P<item_id>[0-9]+)/', existing_get_item_api),
url(r'api/items/', get_help),
]
Let me know how is this working out for you.
We can user modelviewsets and routers for this implementation
viewsets.py
class AccountViewSet(viewsets.ModelViewSet):
"""
A simple ViewSet for viewing and editing accounts.
"""
http_method_names = ['GET']
queryset = Account.objects.all()
serializer_class = AccountSerializer
routers.py
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'accounts', AccountViewSet)

Expand Tumblr shortened link

I have a Tumblr link like this: http://tumblr.com/XXXXXXXX
In order to communicate with their API I need the hostname of the blog, therefore I need to expand the link to the complete link. Something like: http://blogname.tumblr.com/post/XXXXXX
How can I expand a tumblr shortened link?
Within the Tumblr API, I do not believe it is possible as mentioned by Derek Gottfrid. If you are using it within your app or service you can try looking at the headers.
For example in python, you can use urllib2
import urllib2
tumb = urllib2.urlopen('http://tumblr.com/XXXXXXXX')
print tumb.url
In PHP, you can use the get_headers method
$url = 'http://tumblr.com/XXXXXXXX'
print_r(get_headers($url))
Here's another way to do it in Ruby. It needs to follow tumblr redirection. From http://tmblr.co/XXXXX to http://www.tumblr.com/XXXXX and lastly to the expanded URL. From Net::HTTP documentation:
require 'net/http'
require 'uri'
def get_permalink(uri_str, limit=5)
# You should choose better exception.
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
response = Net::HTTP.get_response(URI.parse(uri_str))
case response
when Net::HTTPOK then uri_str
when Net::HTTPMovedPermanently
get_permalink(response['location'], limit-1)
when Net::HTTPFound
get_permalink(response['location'], limit-1)
end
end
Hope it helps someone