Duplicate Customer Created when using PUT endpoint - Square Connect - python

I created a helper function to update customer data in a class. When I call the function it updates all the information. If I try it again on my tests... it creates a new entry into the customer database, creating a duplicate..
I cant figure out if its my logic or what I am doing wrong. Can someone assist.
I am using the HTTP requests package
Initiate class
self.customer = Sq_Customer(
first_name = 'Testy',
last_name = 'McTesty',
email = 'McTesty#testy.com',
phone= '123-456-7890'
)
Update user JSON and Function call
self.data = {
'given_name': 'Dummy',
'email_address': dummy_account#testing.com',
'address': {
'address_line_1': '1234 Main Street',
'address_line_2': '',
'locality': 'New York',
'administrative_district_level_1': 'NY',
'postal_code': '11413',
'country': 'US'
}
}
self.update_customer = self.customer.update_customer_acct(Customer ID, self.data)
My Helper Function
def update_customer_acct(self, user_id, data):
'''
Update Customer information.
'''
self.customer = self.get_customer(user_id)
if self.customer['customer']['id'] == user_id:
self.update_customer_data = self.connect.put('/v2/customers/' + user_id, data)
return self.__sqware_json_decoder(self.update_customer_data)
else:
return '{}'.format('There is no account associated with that ID.')

I removed the email and there was no longer a duplicate. It's an issue with me creating a customer during the test. When the email is changed it creates a new account. Thanks again.

Related

Want to get twitter data using tweepy but in trouble

I am trying to retrieve Twitter data using Tweepy, using that below code, but I'm having difficulties in collecting media_fields data. Especially, I want to get the type of media, but I failed.
As you can see below, the value is copied and exists in the cell that should be empty.
[enter image description here][1]
import tweepy
from twitter_authentication import bearer_token
import time
import pandas as pd
client = tweepy.Client(bearer_token, wait_on_rate_limit=True)
hoax_tweets = []
for response in tweepy.Paginator(client.search_all_tweets,
query = 'Covid hoax -is:retweet lang:en',
user_fields = ['username', 'public_metrics', 'description', 'location','verified','entities'],
tweet_fields=['id', 'in_reply_to_user_id', 'referenced_tweets', 'context_annotations',
'source', 'created_at', 'entities', 'geo', 'withheld', 'public_metrics',
'text'],
media_fields=['media_key', 'type', 'url', 'alt_text',
'public_metrics','preview_image_url'],
expansions=['author_id', 'in_reply_to_user_id', 'geo.place_id',
'attachments.media_keys','referenced_tweets.id','referenced_tweets.id.author_id'],
place_fields=['id', 'name', 'country_code', 'place_type', 'full_name', 'country',
'geo', 'contained_within'],
start_time = '2021-01-20T00:00:00Z',
end_time = '2021-01-21T00:00:00Z',
max_results=100):
time.sleep(1)
hoax_tweets.append(response)
result = []
user_dict = {}
media_dict = {}
# Loop through each response object
for response in hoax_tweets:
# Take all of the users, and put them into a dictionary of dictionaries with the info we want to keep
for user in response.includes['users']:
user_dict[user.id] = {'username': user.username,
'followers': user.public_metrics['followers_count'],
'tweets': user.public_metrics['tweet_count'],
'description': user.description,
'location': user.location,
'verified': user.verified
}
for media in response.includes['media']:
media_dict[tweet.id] = {'media_key':media.media_key,
'type':media.type
}
for tweet in response.data:
# For each tweet, find the author's information
author_info = user_dict[tweet.author_id]
# Put all of the information we want to keep in a single dictionary for each tweet
result.append({'author_id': tweet.author_id,
'username': author_info['username'],
'author_followers': author_info['followers'],
'author_tweets': author_info['tweets'],
'author_description': author_info['description'],
'author_location': author_info['location'],
'author_verified':author_info['verified'],
'tweet_id': tweet.id,
'text': tweet.text,
'created_at': tweet.created_at,
'retweets': tweet.public_metrics['retweet_count'],
'replies': tweet.public_metrics['reply_count'],
'likes': tweet.public_metrics['like_count'],
'quote_count': tweet.public_metrics['quote_count'],
'in_reply_to_user_id':tweet.in_reply_to_user_id,
'media':tweet.attachments,
'media_type': media,
'conversation':tweet.referenced_tweets
})
# Change this list of dictionaries into a dataframe
df = pd.DataFrame(result)
Also, when I change the code ''media':tweet.attachments' to 'media':tweet.attachments[0] to get 'media_key' data, I get the following error message."TypeError: 'NoneType' object is not subscriptable"
What am I doing wrong? Any suggestions would be appreciated.
[1]: https://i.stack.imgur.com/AxCcl.png
The subscriptable error comes from the fact that tweet.attachments is None, from here the NoneType part. To make it work, you can add a check for None:
'media':tweet.attachments[0] if tweet.attachments else None
I have never used the twitter API, but one thing is to make sure the tweet attachments are always present or if they may be absent.

Way to store user input data to be called later in Python?

New to Python and am working on a task my friend gave me. The objective for this portion is to find user information that was previously added to a dictionary. I am trying to find a way that if the user is searching for a particular user, only that user's info will be returned. So far this is the code I have for this portion of the project:
selection = input('Please select an option 1 - 4:\t')
if selection == '1':
print('Add user - Enter the information for the new user:\t')
first_name = input('First name:\t')
last_name = input('Last name:\t')
hair_color = input('Hair color:\t')
eye_color = input('Eye color:\t')
age = input('Age:\t')
user_info = {}
user_info['First name'] = first_name
user_info['Last name'] = last_name
user_info['Hair color'] = hair_color
user_info['Eye color'] = eye_color
user_info['Age'] = age
Skipping code for sake of space on post
if selection == '3':
print('\nChoose how to look up a user')
print('1 - First name')
print('2 - Last name')
print('3 - Hair color')
print('4 - Eye color')
print('5 - Age')
print('6 - Exit to main menu\n')
search_option = input('Enter option:\t')
if search_option == '1' or search_option == 'First name' or search_option == 'first name':
input('Enter the first name of the user you are looking for:\t')
Any and all help is much appreciated!!
Depending on your project, using a dictionary might be difficult in the future. Let's not go down a dark road. Take a moment and assess the situation.
We know that we want to collect some information from the user, such as:
first name
last name
hair color
...etc
We also want to store the User object to retrieve later based on a particular ID. In your code, you search for other users based on attributes, but what if two or more users share the same attribute, for example, first name?
What your asking for are attributes associated with a particular user. Why not create a class called User?
class User:
def __init__(self, id, first_name, last_name, hair_color):
# You can also check if any attributes are blank and throw an exception.
self._id = id
self._first_name = first_name
self._last_name = last_name
self._hair_color = hair_color
# add more attributes if you want
# a getter to access the self._id property
#property
def id(self):
return self._id
def __str__(self):
return f"ID: {self._id} Name: {self._first_name} {self._last_name}
Hair Color: {self._hair_color}"
In your main function, you can now ask for the user details and store them in a class which you can append to a List.
from User import User
def ask_for_input(question):
answer = input(question)
return answer.strip() # strip any user created white space.
def main():
# Store our users
users = []
# Collect the user info
id = ask_for_input(question = "ID ")
first_name = ask_for_input(question = "First Name ")
last_name = ask_for_input(question = "Last Name ")
hair_color= ask_for_input(question = "Hair Color ")
# Create our user object
user = User(id=id, first_name=first_name, last_name=last_name, hair_color=hair_color)
print(user)
# accessing the id property
print(user.id)
users.append(user)
if __name__ == '__main__':
main()
You may also want to improve on the above class, for example, error checking, and adding type hints to make the code more readable.
If you're just storing the user information, a data class might be more appropriate.
If your looking for a broad suggestion, you could use mongob, it makes a great way to store data to be retrieved later, here is an example i built for another question. The prerequisites is that you'd have to get the mongod server running before you can use the pip install:
Here is an example of how to get it going and how easy it easy to retrieve data like yours
pip3 install pymongo
from pymongo import MongoClient
client = MongoClient()
client = MongoClient('localhost', 27017)
db = client.pymongo_test
posts = db.posts
post_data = {
'title': 'The title of this post',
'content': 'pymongo is awesome',
'author': 'Bill'
}
result = posts.insert_one(post_data)
print('One post: {0}'.format(result.inserted_id))
bills_post = posts.find_one({'author': 'Bill'})
print(bills_post)
#One post: 5dc61c0cc2b75ebc458da31f
#{'_id': ObjectId('5dc61bf76071bde943ca262b'), 'title': 'The title of this post', 'content': 'pymongo is awesome', 'author': 'Bill'}

How to get biddingStrategyConfiguration in Adwords API?

I'm trying to retrieve the field 'biddingStrategyConfiguration' via Adwords API for Python (3) using CampaignService(), but I always get an weird error. It's weird because the field does exist, as mentioned in the documentation found here.
account_id = 'any_id'
adwords = Adwords(account_id) # classes and objects already created, etc.
def get_bidding_strategy():
service = adwords.client.GetService('CampaignService', version = 'v201806')
selector = {
'fields': ['Id', 'Name', 'Status', 'biddingStrategyConfiguration']
}
results = service.get(selector)
data = []
if 'entries' in results:
for item in results['entries']:
if item['status'] == 'ENABLED':
data.append({
'id': item['id'],
'name': item['name'],
'status': item['status'] # i have to retrieve biddingStrategyConfiguration.biddingStrategyName (next line)
})
return results
This is the error:
Error summary:
{'faultMessage': "[SelectorError.INVALID_FIELD_NAME # serviceSelector; trigger:'biddingStrategyConfiguration']",
'requestId': '000581286e61247e0a376ac776062df4',
'serviceName': 'CampaignService',
'methodName': 'get',
'operations': '1',
'responseTime': '315'}
Notice that fields like "id" or "name" are easily retrievable, but the bidding configuration is not. In fact, I'm looking for the id/name of the biddingStrategies using .biddingStrategyID or .biddingStrategyName.
Can anyone help me? Thanks in advance.
How I solved it: biddingStrategyConfiguration is not a retrievable field, but biddingStrategyName is (part of the JSON).
account_id = 'any_id'
adwords = Adwords(account_id) # classes and objects already created, etc.
def get_bidding_strategy():
service = adwords.client.GetService('CampaignService', version = 'v201806')
selector = {
'fields': ['Id', 'Name', 'Status', 'biddingStrategyName']
}
results = service.get(selector)

Adapting odoo report for email - How to change env for current partner_id only

I have a odoo report from the OCA that I am trying to adapt to be able to be sent as an email to individual customers. The report is seen here Report and Github link
The below is the important part (as I see it). In this function 'data' is passed through from a wizard.
#api.multi
def render_html(self, docids, data):
company_id = data['company_id']
partner_ids = data['partner_ids']
date_start = data['date_start']
date_end = data['date_end']
today = fields.Date.today()
balance_start_to_display, buckets_to_display = {}, {}
lines_to_display, amount_due = {}, {}
currency_to_display = {}
today_display, date_start_display, date_end_display = {}, {}, {}
balance_start = self._get_account_initial_balance(
company_id, partner_ids, date_start)
When I attempt to add the report to an email template as an attachement, I do not know how to pass through parameters to it as well. So I did the following:
If Data is None...
data={
'date_start': str(date.today()-timedelta(days=120)),
'date_end': str(date.today()),
'company_id': self.env.user.company_id.id,
'partner_ids': self._context['active_ids'],
'show_aging_buckets': True,
'filter_non_due_partners': True,
}`
The problem is ' 'partner_ids': self._context['active_ids'], '
Returns every customers statement on the email to every customer. How do I make it so this is only for the current customer?
Thanks in advance for any assistance.

Stuck on Combining Functions, D.R.Y

I've been learning python for the last 10 mos. or so and I'm running programs which update objects in Salesforce. The fact that it's salesforce really doesn't matter.
What matters is that there are lots of little variations on the same procedure that I'm ending up with essentially the same function written but with slight modifications.
I'd like to consolidate as much as possible but I'm not sure exactly how.
I've put the code below with some descriptions
My questions revolve around how to make functions like this scalable. I'm having to repeat myself constantly but I'm not sure how to make this work.
Thanks!
def getSfdcAccounts(login,pw):
'''
This function queries Salesforce and pulls down a
list of accounts that meet the criteria of xyz, simple
'''
svc = beatbox.Client()
svc.login(login, pw)
qr = svc.query("select Id, Name, Website, type from Account where xyz")
for rec in qr[sf.records:]:
do something
def getSfdcAccounts2(login,pw):
'''
This function queries Salesforce and pulls down a
list of accounts that meet the criteria of xyz, zyx and abc, simple
However, This is almost identical to the original function but has
significant variations. Should I be combining these?
'''
svc = beatbox.Client()
svc.login(login, pw)
qr = svc.query("select Id, BillingAddress, Name, Website, type from Account where xyz, zyx, abc")
for rec in qr[sf.records:]:
do something
def updateSfdcOjbect(lowin,pw,object,info):
'''
This function pushes a dictionary into Salesforce
and updates the object based on the keys of the dict, simple
'''
svc = beatbox.Client()
svc.login(login, pw)
for i in info:
update_dict = {
'type': str(object),
'Id': info[0],
'Website': info[1]
'BillingAddress': info[2]
'NumberOfEmployees':info[3]
'Industry':info[4]
}
results2 = svc.update(update_dict)
def updateSfdcOjbect(lowin,pw,object,info):
'''
This function pushes a dictionary into Salesforce
and updates the object based on the keys of the dict, simple
However, the keys and values are slightly different. I want
to update the Shipping Address, not Billing Address
As well as the number of products rather than employees
'''
svc = beatbox.Client()
svc.login(login, pw)
for i in info:
update_dict = {
'type': str(object),
'Id': info[0],
'Website': info[1]
'ShippingAddress': info[2]
'Nummber_of_Products__c':info[3]
'Sic_Code__c':info[4]
}
results2 = svc.update(update_dict)
The basic principle is to take the parts that are the same between functions
and put them into a common function, and then pass in the parts that are
different. So, using two of your functions as an example:
def getSfdcAccounts(login,pw):
'''
This function queries Salesforce and pulls down a
list of accounts that meet the criteria of xyz, simple
'''
svc = beatbox.Client()
svc.login(login, pw)
qr = svc.query("select Id, Name, Website, type from Account where xyz")
for rec in qr[sf.records:]:
do something
def getSfdcAccounts2(login,pw):
'''
This function queries Salesforce and pulls down a
list of accounts that meet the criteria of xyz, zyx and abc, simple
However, This is almost identical to the original function but has
significant variations. Should I be combining these?
'''
svc = beatbox.Client()
svc.login(login, pw)
qr = svc.query("select Id, BillingAddress, Name, Website, type from Account where xyz, zyx, abc")
for rec in qr[sf.records:]:
do something
You could make a new function:
def getSfdcAccounts(login, pw, query):
svc = beatbox.Client()
svc.login(login, pw)
qr = svc.query(query)
for rec in qr[sf.records:]:
do something
And then you call it with the different queries:
getSfdcAccounts(login, pw, "select Id, Name, Website, type from Account where xyz"):
getSfdcAccounts(login, pw, "select Id, BillingAddress, Name, Website, type from Account where xyz, zyx, abc"):
Beyond that, I agree with the what the others have said about putting this into a class and handling the connection setup there.
These functions should all be declared as methods in the same class. In the constructor of the class, you can can share the beatbox setup:
self.svc = beatbox.Client()
self.svc.login(login, pw)
class BeatboxClient(object):
def __init__(self, login, pw):
self.svc = beatbox.Client()
self.svc.login(login, pw)
def processAccounts(self, query):
qr = self.svc.query(query)
for rec in qr[sf.records:]:
do something
def updateSfdcOjbect(object, info):
for i in info:
update_dict = {
'type': str(object),
'Id': info[0],
'Website': info[1]
'BillingAddress': info[2]
'NumberOfEmployees':info[3]
'Industry':info[4]
}
results2 = self.svc.update(update_dict)
def updateSfdcOjbect(object, info):
for i in info:
update_dict = {
'type': str(object),
'Id': info[0],
'Website': info[1]
'ShippingAddress': info[2]
'Nummber_of_Products__c':info[3]
'Sic_Code__c':info[4]
}
results2 = self.svc.update(update_dict)

Categories

Resources