Can't access to python social auth's data - python

I am using Django 1.9.5 and have a problem with the data that python social auth gives. I got the data, but I cant' access it. This is my code
def save_auth_data_session(request):
if request.user:
twitter = request.user.social_auth.get(provider ='twitter')
print twitter.extra_data['access_token']
The terminal gives me this error
""TypeError: string indices must be integers""
If I do a "print vars(twitter)", this the data I get
{'user_id': 123, 'uid': u'2413671427750', '_user_cache': <User: quintana>, '_state': <django.db.models.base.ModelState object at 0x7fa3d86fc2d0>, 'provider': u'twitter', 'extra_data': u'{"access_token": {"oauth_token_secret": "Afkasdasdas21zxbxcbn", "oauth_token": "2468cxcpqsldkenI56", "x_auth_expires": "0", "user_id": "455793463", "screen_name": "puertoRico"}, "id": 455793463}', 'id': 123}

As i can see from output of print vars(twitter) - extra_data stores serialized dictionary (string) 'extra_data': u'{...}'.
So you need to deserialize it first.
import json
twitter = request.user.social_auth.get(provider ='twitter')
extra_data = json.loads(twitter.extra_data) # will give you a python dictionary
print extra_data['access_token']

Related

How to use my original key for identifying a doc in Cloudant db from Python client?

I'm working on a python client program to Cloundant.
I'd like to retrieve a doc, not based on "_id",but on my own field.
Still, it does not work causing Key Error. Any help to solve this error is highly appreciated!
Here is my code:
from cloudant.client import Cloudant
from cloudant.error import CloudantException
from cloudant.result import Result,ResultByKey
...
client.connect()
databaseName = "mydata1"
myDatabase = client[databaseName]
# As direct access like 'doc = myDatabase[<_id>]' cannot work for my key,
# let's check on by one ...
for document in myDatabase:
# if document['_id']== "20170928chibikasmall": <= if I use _id it's ok
if document['gokigenField']== 111:
This cause
KeyError :'gokigenField'
In advance, I've created gokigenField index using dashboard, then confirm the result via my postman with REST API
GET https://....bluemix.cloudant.com/mydata1/_index
the result is as follows:
{"total_rows":2,"indexes":[{"ddoc":null,"name":"_all_docs","type":"special","def":{"fields":[{"_id":"asc"}]}},{"ddoc":"_design/f7fb53912eb005771b736422f41c24cd26c7f06a","name":"gokigen-index","type":"text","def":{"default_analyzer":"keyword","default_field":{},"selector":{},"fields":[{"gokigenField":"number"}],"index_array_lengths":true}}]}
Also, I've confirmed I can use this gokigenField as query index nicely on cloudant dashboard as well as POST query .
My newly created "gokigenField" is not included in all the document in DB, as there are automatically created doc ("_design/xxx) without that field.
I guess this might cause KeyError, when I call this from my Python client.
I cannot find Cloudant API for checking 'if a specific key exists or not in a document', in the reference.. So, cannot have any idea how to by-pass such docs...
This is how to index an query data from the Python client. Let's assume we already have the library imported and have a database client in myDatabase.
First of all I created some data:
#create some data
data = { 'name': 'Julia', 'age': 30, 'pets': ['cat', 'dog', 'frog'], 'gokigenField': 'a' }
myDatabase.create_document(data)
data = { 'name': 'Fred', 'age': 30, 'pets': ['dog'], 'gokigenField': 'b' }
myDatabase.create_document(data)
data = { 'name': 'Laura', 'age': 31, 'pets': ['cat'], 'gokigenField': 'c' }
myDatabase.create_document(data)
data = { 'name': 'Emma', 'age': 32, 'pets': ['cat', 'parrot', 'hamster'], 'gokigenField': 'c' }
myDatabase.create_document(data)
We can check the data is there in the Cloudant dashboard or by doing:
# check the data is there
for document in myDatabase:
print(document)
Next we can opt to index the field gokigenField like so:
# create an index on the field 'gokigenField'
mydb.create_query_index(fields=['gokigenField'])
Then we can query the database:
# do a query
selector = {'gokigenField': {'$eq': 'c'}}
docs = mydb.get_query_result(selector)
for doc in docs:
print (doc)
which outputs the two matching documents.
The python-cloudant documentation is here.

How to convert neomodel object into json? (is not JSON serializable)

I use Falcon framework and neomodel in order to communicate with neo4j database.
I have some nodes in DB and I try to return information about them via API (get methon) as a JSON object.
In order to retrive information I use the code people = Person.nodes
I iterate throu people:
for p in people:
print(p)
and I get:
{'name': 'John', 'id': 0, 'uid': '584d9b0517584b8194f222052bf177ff'}
{'name': 'Paul', 'id': 1, 'uid': 'f5763c01704e449885f846e87e1fcb6d'}
When I do json.dumps() on single entity I get an error:
TypeError: <Person: {'name': 'John', 'id': 0, 'uid': '584d9b0517584b8194f222052bf177ff'}> is not JSON serializable
How can I convert neomodel object into json object?
Using json.dumps(p.__properties__) does the trick. Using p.__dict__ tries to encode the neomodel property classes, which will throw an error.
It seems like every p in your people is an object.
Try something like json.dumps(p.__dict__). If it's a common neomodel node object then this should work.
A bit of an old question but this is how I work with this..
Creating a function on the class so I can control what data to return. With __properies__ instead of the .to_json funtion you will get all properties.
class Player(StructuredNode):
mid = IntegerProperty(unique_index=True)
f_name = StringProperty()
l_name = StringProperty()
email = StringProperty()
team = RelationshipFrom('Team', 'PLAYER', model=PlayerRel)
def to_json(self):
return {
"id": self.mid,
"firstName": self.f_name,
"lastName": self.l_name,
"email": self.email,
"fullName": self.f_name + ' ' + self.l_name
}
Then I have a node with has several Players connected and I just do this to return an array of players that can be serialized:
...
team = Team.nodes.get(team_id=id)
return ([player.to_json() for player in team.players])

String indices must be integers - Django

I have a pretty big dictionary which looks like this:
{
'startIndex': 1,
'username': 'myemail#gmail.com',
'items': [{
'id': '67022006',
'name': 'Adopt-a-Hydrant',
'kind': 'analytics#accountSummary',
'webProperties': [{
'id': 'UA-67522226-1',
'name': 'Adopt-a-Hydrant',
'websiteUrl': 'https://www.udemy.com/,
'internalWebPropertyId': '104343473',
'profiles': [{
'id': '108333146',
'name': 'Adopt a Hydrant (Udemy)',
'type': 'WEB',
'kind': 'analytics#profileSummary'
}, {
'id': '132099908',
'name': 'Unfiltered view',
'type': 'WEB',
'kind': 'analytics#profileSummary'
}],
'level': 'STANDARD',
'kind': 'analytics#webPropertySummary'
}]
}, {
'id': '44222959',
'name': 'A223n',
'kind': 'analytics#accountSummary',
And so on....
When I copy this dictionary on my Jupyter notebook and I run the exact same function I run on my django code it runs as expected, everything is literarily the same, in my django code I'm even printing the dictionary out then I copy it to the notebook and run it and I get what I'm expecting.
Just for more info this is the function:
google_profile = gp.google_profile # Get google_profile from DB
print(google_profile)
all_properties = []
for properties in google_profile['items']:
all_properties.append(properties)
site_selection=[]
for single_property in all_properties:
single_propery_name=single_property['name']
for single_view in single_property['webProperties'][0]['profiles']:
single_view_id = single_view['id']
single_view_name = (single_view['name'])
selections = single_propery_name + ' (View: '+single_view_name+' ID: '+single_view_id+')'
site_selection.append(selections)
print (site_selection)
So my guess is that my notebook has some sort of json parser installed or something like that? Is that possible? Why in django I can't access dictionaries the same way I can on my ipython notebooks?
EDITS
More info:
The error is at the line: for properties in google_profile['items']:
Django debug is: TypeError at /gconnect/ string indices must be integers
Local Vars are:
all_properties =[]
current_user = 'myemail#gmail.com'
google_profile = `the above dictionary`
So just to make it clear for who finds this question:
If you save a dictionary in a database django will save it as a string, so you won't be able to access it after.
To solve this you can re-convert it to a dictionary:
The answer from this post worked perfectly for me, in other words:
import json
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_acceptable_string = s.replace("'", "\"")
d = json.loads(json_acceptable_string)
# d = {u'muffin': u'lolz', u'foo': u'kitty'}
There are many ways to convert a string to a dictionary, this is only one. If you stumbled in this problem you can quickly check if it's a string instead of a dictionary with:
print(type(var))
In my case I had:
<class 'str'>
before converting it with the above method and then I got
<class 'dict'>
and everything worked as supposed to

writing json-ish list to csv, line by line, in python for bitcoin addresses

I'm querying the onename api in an effort to get the bitcoin addresses of all the users.
At the moment I'm getting all the user information as a json-esque list, and then piping the output to a file, it looks like this:
[{'0': {'owner_address': '1Q2Tv6f9vXbdoxRmGwNrHbjrrK4Hv6jCsz', 'zone_file': '{"avatar": {"url": "https://s3.amazonaws.com/kd4/111"}, "bitcoin": {"address": "1NmLvYVEZqPGeQNcgFS3DdghpoqaH4r5Xh"}, "cover": {"url": "https://s3.amazonaws.com/dx3/111"}, "facebook": {"proof": {"url": "https://facebook.com/jasondrake1978/posts/10152769170542776"}, "username": "jasondrake1978"}, "graph": {"url": "https://s3.amazonaws.com/grph/111"}, "location": {"formatted": "Mechanicsville, Va"}, "name": {"formatted": "Jason Drake"}, "twitter": {"username": "000001"}, "v": "0.2", "website": "http://1642.com"}', 'verifications': [{'proof_url': 'https://facebook.com/jasondrake1978/posts/10152769170542776', 'service': 'facebook', 'valid': False, 'identifier': 'jasondrake1978'}], 'profile': {'website': 'http://1642.com', 'cover': {'url': 'https://s3.amazonaws.com/dx3/111'}, 'facebook': {'proof': {'url': 'https://facebook.com/jasondrake1978/posts/10152769170542776'}, 'username': 'jasondrake1978'}, 'twitter': {'username': '000001'}, 'bitcoin': {'address': '1NmLvYVEZqPGeQNcgFS3DdghpoqaH4r5Xh'}, 'name': {'formatted': 'Jason Drake'}, 'graph': {'url': 'https://s3.amazonaws.com/grph/111'}, 'location': {'formatted': 'Mechanicsville, Va'}, 'avatar': {'url': 'https://s3.amazonaws.com/kd4/111'}, 'v': '0.2'}}}]
what I'm really interested in is the field {"address": "1NmLvYVEZqPGeQNcgFS3DdghpoqaH4r5Xh"}, the rest of the stuff I don't need, I just want the addresses of every user.
Is there a way that I can just write only the addresses to a file using python?
I'm trying to write it as something like:
1NmLvYVEZqPGeQNcgFS3DdghpoqaH4r5Xh,
1GA9RVZHuEE8zm4ooMTiqLicfnvymhzRVm,
1BJdMS9E5TUXxJcAvBriwvDoXmVeJfKiFV,
1NmLvYVEZqPGeQNcgFS3DdghpoqaH4r5Xh,
...
and so on.
I've tried a number of different ways using dump, dumps, etc. but I haven't yet been able to pin it down.
My code looks like this:
import os
import json
import requests
#import py2neo
import csv
# set up authentication parameters
#py2neo.authenticate("46.101.180.63:7474", "neo4j", "uni-bonn")
# Connect to graph and add constraints.
neo4jUrl = os.environ.get('NEO4J_URL',"http://46.101.180.63:7474/db/data/")
#graph = py2neo.Graph(neo4jUrl)
# Add uniqueness constraints.
#graph.run("CREATE CONSTRAINT ON (q:Person) ASSERT q.id IS UNIQUE;")
# Build URL.
apiUrl = "https://api.onename.com/v1/users"
# apiUrl = "https://raw.githubusercontent.com/s-matthew-english/26.04/master/test.json"
# Send GET request.
Allusersjson = requests.get(apiUrl, headers = {"accept":"application/json"}).json()
#print(json)])
UsersDetails=[]
for username in Allusersjson['usernames']:
usernamex= username[:-3]
apiUrl2="https://api.onename.com/v1/users/"+usernamex+"?app-id=demo-app-id&app-secret=demo-app-secret"
userinfo=requests.get(apiUrl2, headers = {"accept":"application/json"}).json()
# try:
# if('bitcoin' not in userinfo[usernamex]['profile']):
# continue
# else:
# UsersDetails.append(userinfo)
# except:
# continue
try:
address = userinfo[usernamex]["profile"]["bitcoin"]["address"]
UsersDetails.append(address)
except KeyError:
pass # no address
out = "\n".join(UsersDetails)
print(out)
open("out.csv", "w").write(out)
# f = csv.writer(open("test.csv", "wb+"))
# Build query.
query = """
RETURN {json}
"""
# Send Cypher query.
# py2neo.CypherQuery(graph, query).run(json=json)
# graph.run(query).run(json=json)
#graph.run(query,json=json)
anyway, in such a situation, what's the best way to write out those addresses as csv :/
UPDATE
I ran it, and at first it worked, but then I got the following error:
Instead of adding all the information to the UsersDetails list
UsersDetails.append(userinfo)
you can add just the relevant part (address)
try:
address = userinfo[usernamex]["profile"]["bitcoin"]["address"]
UsersDetails.append(address)
except KeyError:
pass # no address
except TypeError:
pass # illformed data
To print the values to the screen:
out = "\n".join(UsersDetails)
print(out)
(replace "\n" with "," for comma separated output, instead of one per line)
To save to a file:
open("out.csv", "w").write(out)
You need to reformat the list, either through map() or a list comprehension, to get it down to just the information you want. For example, if the top-level key used in the response from the api.onename.com API is always 0, you can do something like this
UsersAddresses = [user['0']['profile']['bitcoin']['address'] for user in UsersDetails]

What Promoted Object should I use when creating an AdSet with lead_generation optimization goal?

I'm using facebookads python api, v2.6.
I'm trying to create an AdSet with optimization goal = lead_generation.
This is my code:
ad_set = AdSet(parent_id = 'act_%s' % FB_ACCOUNT)
ad_set[AdSet.Field.name]= 'Teste AdSet'
ad_set[AdSet.Field.campaign_id]='6043402838999'
ad_set[AdSet.Field.status]=AdSet.Status.paused
ad_set[AdSet.Field.billing_event] = AdSet.BillingEvent.impressions
ad_set[AdSet.Field.optimization_goal] = AdSet.OptimizationGoal.lead_generation
ad_set[AdSet.Field.daily_budget]= 100
ad_set[AdSet.Field.bid_amount]= 1
ad_set[AdSet.Field.start_time]= '2016-07-01'
ad_set[AdSet.Field.promoted_object]=
ad_set[AdSet.Field.targeting]= {Targeting.Field.geo_locations: { 'countries': ['BR']},Targeting.Field.genders: [1],Targeting.Field.age_min: 20,Targeting.Field.age_max: 24}
ad_set.remote_create()
But when I run this I get this error:
Status: 400
Response:
{
"error": {
"code": 100,
"is_transient": false,
"error_subcode": 1885024,
"error_user_msg": "When creating an ad set within a campaign using the Body of an error/warning message. Title is: Promoted Object Missing objective, a promoted object must be specified.",
"error_user_title": "Promoted Object Missing",
"message": "Invalid parameter",
"type": "OAuthException",
"fbtrace_id": "B9hyZlpzS7O"
}
}
I tried to find any documentation about this, but could not. On the official docs I don't see LEAD_GENERATION on the promoted objects options:
https://developers.facebook.com/docs/marketing-api/reference/ad-campaign#Creating
Anyone had this problem?
In case anyone has the same issue, you have to use page_id.
The ad set must have its promoted_object set to the corresponding <PAGE_ID>.
reference:
https://developers.facebook.com/docs/marketing-api/guides/lead-ads/create#create
you have to specify your associated page_id
promoted_object={"page_id": "<PAGE_ID>"}
Below code may help u
from facebook_business.adobjects.adaccount import AdAccount
from facebook_business.adobjects.adset import AdSet
from facebook_business.api import FacebookAdsApi
access_token = '<ACCESS_TOKEN>'
app_secret = '<APP_SECRET>'
app_id = '<APP_ID>'
id = '<AD_ACCOUNT_ID>'
FacebookAdsApi.init(access_token=access_token)
fields = [
]
params = {
'name': 'A CPA Ad Set',
'campaign_id': '<adCampaignLinkClicksID>',
'daily_budget': '5000',
'start_time': '2019-01-09T21:31:19-0800',
'end_time': '2019-01-16T21:31:19-0800',
'billing_event': 'IMPRESSIONS',
'optimization_goal': 'REACH',
'bid_amount': '1000',
'promoted_object': {'page_id':'<pageID>'},
'targeting': {'geo_locations':{'countries':['US']}},
'user_os': 'iOS',
'publisher_platforms': 'facebook',
'device_platforms': 'mobile',
}
print AdAccount(id).create_ad_set(
fields=fields,
params=params,
)

Categories

Resources