This is probably a silly question, but I been scratching my head over this for far too long.
I am trying to request the photo information from the facebook GraphAPI using Facepy/social-auth in django.
My view has the following code, but how do i turn the resulting json into python objects?
instance = UserSocialAuth.objects.filter(user=request.user).filter(provider='facebook')
graph = GraphAPI(instance[0].extra_data['access_token'])
p=graph.get('me/photos')
Facepy seems very good, but the documentation is poor at best, is there a better python facebook sdk that plays nice with social-auth?
Thanks for all suggestions.
Facepy returns native Python objects, not JSON.
response = graph.get('me/photos')
for photo in response['data']:
print photo['source']
You can use simplejson's loads function
from django.utils import simplejson
simplejson.loads(args)
Deserialize s (a str or unicode instance containing a JSON
document) to a Python object.
If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
must be specified. Encodings that are not ASCII based (such as UCS-2)
are not allowed and should be decoded to ``unicode`` first.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN, null, true, false.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg.
Related
I need to pass an object to redirect function. Is this the way to go about it ?
redirect('/view', kwargs={'obj': obj})
def view(request, obj):
do something
How do I implement it so url dispatcher accepts it ? I would use:
url(r'view/.+', view, name='whatever'),
Since I'm passing an object I'm not using url converters (str, int, slug, etc) but using regular expression that tells url dispatcher to accept anything I pass to it, however this is throwing me an error.
What is the right way to go about it ?
How do I implement it so url dispatcher accepts it?
You can not do that. you can not pass an object itself through a URL (or through anything else), or at least not without using a lot of "hacks", by using a serializer like pickle, but that would generate huge URLs (URLs are not strictly limited, but usually it is advisable to keep a URL shorter than 2000 characters). An empty dictionary will already take 8 characters if you encode it with a base64 encoding over a pickle stream.
You can not pass a generic object to a URL. You can only pass text as the URL. You can convert an integer to text, etc. But converting a generic object to text, that strictly speaking can be done (through pickling), but that is not recommended at all. It would furthermore potentially expose the webserver internals. If for example your object somehow refers to the Django settings, it might encode the database credentials, and thus impose a severe security risk.
You thus can pass text, or convert some data to text. In order to handle that, you first need to define a parameter in your url. How else will you capture the data. We can thus define a parameter, like:
url(r'view/(?P<obj>.*)/$', view, name='whatever'),
You can then generate a redirect by using the name of the view, and passing the parameters as named parameters:
redirect('whatever', obj='sometext')
Then the view will be called with obj as 'sometext'. Usually one passes the primary key, slug, etc. This makes it easy to read, compact, and furthermore it only exposes a small amount of data to the client.
I am trying to write a C++ application, using C++ REST SDK lib, that will process JSON data produced by a C# application. A C# program can produce JSON in a "wrapped" or "bare" style.
Using BodyStyle = WebMessageBodyStyle.Wrapped, C# produces JSON like the following:
{"Echo":"{\"firstname\":\"an'",\"number\":21,\"secondname\":\"pn\"}"}
Using BodyStyle = WebMessageBodyStyle.Bare, C# produces JSON like this:
"{\"firstname\":\"an'",\"number\":21,\"secondname\":\"pn\"}"
How can my program recognize which type was produced: Wrapped or Bare?
JSON is a standard format for representing, and exchanging, data. It does not define the terms Wrapped or Bare. I am not familiar with C# and its libraries for encoding data as JSON, however I can make a guess based on the samples you provided.
If you have control over the C# application, code it to use Bare only. I see no advantage, in general, to the Wrapped style. Perhaps it is designed specifically for some other C# client libraries.
The only difference I see in the produced output is the structure of the data. There is no way to be absolutely certain, but from those two samples you can simply look at the deserialized object and check if it has an attribute Echo. If it does, use the value of that attribute and if it doesn't then use the object as-is.
Since I haven't worked in C++ in over a decade and I do not know the JSON library you are using, I will give an example in JavaScript (though using a style that may be somewhat closer to C++). Here is how those two objects could be handled:
var data = JSON.parse(...); // the '...' represents where ever you get the text
if (data["Echo"] !== undefined)
{ data = data["Echo"]; }
console.log("The first name is:", data["firstname"]);
Here is a psuedo-code example that is almost valid Java which may be more easily recognized and translated to C++:
Map<String, Object> data = JSON.parse(...); // the '...' represents where ever you get the text
if (data.containsKey("Echo"))
{ data = (Map)data.get("Echo"); }
System.out.println("The first name is: " + data.get("firstname"));
I'm completely baffled by a problem I found today: I have a PostgreSQL database with tables which are not managed by Django, and completely normal queries via QuerySet on these tables. However, I've started getting Unicode exceptions and when I went digging, I found that my QuerySets are returning non-Unicode strings!
Example code:
d = Document.objects.get(id=45787)
print repr(d.title), type(d.title)
The output of the above statement is a normal string (without the u prefix), followed by a <str> type identifier. What's more, this normal string contains UTF-8 data as expected, in raw byte form! If I call d.title.decode('utf-8'), I get valid Unicode strings!
Even more puzzling, some of the fields work correctly. This same table / model contains another field, html_filename of the same type (TextField) which is returned correctly, as a Unicode string!
I have no special options, the database data is correctly encoded, and I don't even know where to begin searching for a solution. This is Django 1.6.2.
Update:
Database Server encoding is UTF8, as usual, and the data is correctly encoded. This is on PostgreSQL 9.1 on Ubuntu.
Update 2:
I think I may have found the cause, but I don't know why it behaves this way: I thought the database fields were defined with the text type, as usual, but instead they are defined as citext (http://www.postgresql.org/docs/9.1/static/citext.html). Since the Django model is unmanaged, it looks like Django doesn't interpret the field type as being worthy of converting to Unicode. Any ideas how to force Django to do this?
Apparently, Django will not treat fields of type citext as textual and return them as Unicode strings.
I'm calling facebook authentication API
https://www.facebook.com/dialog/oauth?client_id=3768637750&redirect_uri=http://localhost:8080/login.html?loginType=facebook
I get back following response.
=">http://localhost:8080/login.html?loginType=facebook&code=AQA84TrJjJNQaib2qvhGSdrPIIwJoIlfs9ZABjhBO6H9vt2wSZuRedigWjgV8SMg7QafCq-0xgbvi5k1e-RtFNA1pbrcfSsIqBL__-YWWhVFFepTGUuJeXWPW8Z3orRl-fWJUqb2mnmAJ995VFVX3O9N4iDj_3mhgQLC0DVwegprezqV6fU1tElMpH5Gj0#=
I'm using Spring3.0, and when is use some method like getCode() to read query parameter in Controller, I get truncated value for query paramter "code"
instead of getting,
AQA84TrJjJNQaib2qvhGSdrPIIwJoIlfs9ZABjhBO6H9vt2wSZuRedigWjgV8SMg7QafCq-0xgbvi5k1e-RtFNA1pbrcfSsIqBL__-YWWhVFFepTGUuJeXWPW8Z3orRl-fWJUqb2mnmAJ995VFVX3O9N4iDj_3mhgQLC0DVwegprezqV6fU1tElMpH5Gj0#=
I get
AQA84TrJjJNQaib2qvhGSdrPIIwJoIlfs9ZABjhBO6H9vt2wSZuRedigWjgV8SMg7QafCq-0xgbvi5k1e-RtFNA1pbrcfSsIqBL__-YWWhVFFepTGUuJeXWPW8Z3orRl-fWJUqb2mnmAJ995VFVX3O9N4iDj_3mhgQLC0DVwegprezqV6fU1tElMpH5Gj0
I am using UTF-8 encoding, any help on this please?
I am using UTF-8 encoding
That doesn’t matter, since this is not a character encoding issue.
A hash # in an URL marks the start of the “fragment identifier”, and that does not get passed to the server.
I get truncated value for query paramter "code"
There is no truncation, because the value of the code parameter ends before the #.
If I have a webservice that returns an image, is there a standard way to also have it return some structured data (in the simplest case, an additional string or number)?
See this question for a PHP example of a webservice that returns an image.
(But my question now is not specific to PHP.)
Possible solutions (mostly not very satisfying):
Put the extra data in the metadata of the image.
Put the extra data in the HTTP headers.
Have the webservice return a nonce URL from which the image can be fetched for a limited amount of time.
Base64-encode the image and make it huge string field in a JSON or XML data structure. (Thanks to Carles and Tiago.)
How would you do it?
(I don't really want to just split the webservice into two separate calls because the webservice takes a ton of parameters and it seems wasteful to send them all twice.)
HTTP headers are a viable choice as they can be parsed easily server side and client side. Another thing you can do is setup a 302 that redirects it to a URL with the image and data in the URL (e.g ->
hit http://mysite.com/bestimageever.png
get 302 to http://mysite.com/realbestimage.png?supercoolinfo=42
That'd be transparent to the user and most API clients will work (since they handle redirects)
Return the image's binary data encoded in base64, and the additional field:
{ image: "mIIerhdkwje...", data: "data" }
Base64 encoding gives you an overhead of 33% (you need 4 bytes for each 3 original bytes). Depending on the size of your data it may be better to replace this with the url of the binary data and issue a second request...
Protocol buffers are another choice. Protocol buffers aren't self-describing like XML or JSON, but they are much more compact on the wire. The Google library (http://code.google.com/p/protobuf) provides C++, Java, and Python libraries, and contributors have provided libraries for a lot of other languages (http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns), including Javascript and PHP, so client writers should have an easy time working with the format.
isn't it possible to include the binary data to form the image inside the return json/xml? By this way, you could add as many fields as necessary and you could process this information in the client.