getting status code from google admin sdk - python

I am calling to google admin sdk. I am successfully creating users and everything is working fine. I started testing the project and when I create a duplicate user the program crashes. Can you help me get the status code response from google so I can prevent my code from crashing?
in google im using the user.insert method
Error from creating duplicate user
googleapiclient.errors.HttpError: <HttpError 409 when requesting
https://admin.googleapis.com/admin/directory/v1/users?alt=json returned
"Entity already exists.". Details: "Entity already exists.">
So how do i capture the 409, or a 200 or any other code that would come across?
def create_google_user(first_name, last_name, department):
# all the set up code from google here.
new_email = first_name + '.' + last_name + '#company.com'
new_user = {
"name": {
"familyName": last_name, # Last name
"givenName": first_name, # First name
},
"password": "random_PassWord",
"primaryEmail": new_email,
"suspended": False,
"changePasswordAtNextLogin": True,
"organizations": [
{
"department": department
}
],
"phones": [
{
"value": "1997915801",
"type": "work"
}
],
}
result = service.users().insert(body=new_user).execute()
print('Result: ', result)
print 'User Created'

Related

TypeError when trying to set a DB value

I'm trying to get my Flask server to update to a Mongo Atlas DB on request. When a request is passed with the required arguments, it will post to a Discord webhook then attempt to update DB values.
Example: Going to https://(redacted for privacy)/(redacted for privacy)?iid=123&username=wow&price=22 with JUST the webhook code (doesn't touch DB) will do this:
(sent to discord webhook) and give a success message (outputs as 200 in the console).
But when I enable the DB code, the same link will through a 500 error. Anything I can do? The console outputs as;
balance = mycol.find_one({"UserID": uid})['balance']
TypeError: 'NoneType' object is not subscriptable
I don't understand why this won't work. Here's the code that works, but only posts to the webhook (commented stuff is DB related):
#balance = mycol.find_one({"UserID": uid})['balance']
#res = mycol.find_one({"UserID": uid})
#newvalues = { "$set": { "UserID": uid, "balance": int(balance) + int(cashback_amt)} }
#mycol.update_one(res, newvalues)
img_url = f"https://www.roblox.com/bust-thumbnail/image?userId={uid}&width=420&height=420&format=png"
data = {
"content" : "**New purchase!**",
"username" : "robate"
}
data["embeds"] = [
{
"description" : f"**ItemID**: `{item_id}`\n**Item Price**: `{price}`\n**Item Cashback**: `{cashback_amt}`",
"title" : "New purchase made",
"color": 65311,
"thumbnail": {"url": img_url}
}
]
result = requests.post(purclog, json = data)
return jsonify({"res": True})
And the non-working DB included code:
balance = mycol.find_one({"UserID": uid})['balance']
res = mycol.find_one({"UserID": uid})
newvalues = { "$set": { "UserID": uid, "balance": int(balance) + int(cashback_amt)} }
mycol.update_one(res, newvalues)
img_url = f"https://www.roblox.com/bust-thumbnail/image?userId={uid}&width=420&height=420&format=png"
data = {
"content" : "**New purchase!**",
"username" : "robate"
}
data["embeds"] = [
{
"description" : f"**ItemID**: `{item_id}`\n**Item Price**: `{price}`\n**Item Cashback**: `{cashback_amt}`",
"title" : "New purchase made",
"color": 65311,
"thumbnail": {"url": img_url}
}
]
result = requests.post(purclog, json = data)
return jsonify({"res": True})
Any help is severely appreciated. Have a good day!
EDIT: The UserID is defined here:
try:
uid = requests.get(f"https://api.roblox.com/users/get-by-username?username={username}").json()['Id']
except:
return
balance = mycol.find_one({"UserID": uid})['balance']

Delete contact function in People API not work: Method: people.deleteContact

Now i try to use python to code one CMS project for contacts, but i have some problems.
I code this def but it is not work with google people API.
https://developers.google.com/people/v1/contacts
The logs
File "/Users/nguyenngoclinh/.conda/envs/1z_vietnam/lib/python3.7/site-packages/googleapiclient/http.py", line 907, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 404 when requesting https://people.googleapis.com/v1/%7B'people/c9194159806299427121'%7D:deleteContact?alt=json returned "Not Found">
delete fuction is bellow
def delete_contacts_with_resourceName(creds,http,number_of_contact):
# Call the People API
service = build('people', 'v1', credentials=creds)
print('Ban dang xoa', number_of_contactcontact, 'contacts')
results = service.people().connections().list(
resourceName='people/me',
pageSize=number_of_contactofcontact,
personFields='names,emailAddresses,phoneNumbers,emailAddresses,addresses').execute()
service = discovery.build('people', 'v1', http=http,
discoveryServiceUrl='https://people.googleapis.com/$discovery/rest')
connections = results.get('connections', [])
for person in connections:
abcd = person.get('resourceName')
service.people().deleteContact(resourceName={abcd}).execute()
But the creat contact def bellow also work.
def creat_a_google_contact(http):
# POST / v1 / people: createContact
# HTTP / 1.1
# Body: {"names": [{"givenName": "John", "familyName": "Doe"}]}
# Host: people.googleapis.com
service = discovery.build('people', 'v1', http=http,
discoveryServiceUrl='https://people.googleapis.com/$discovery/rest')
service.people().createContact(body={
"names": [
{
'givenName': "Nguyen Ngoc Linh",
"familyName": "29N2359 BMW 325i"
}
],
"phoneNumbers": [
{
'value': "0979955664"
}
],
"emailAddresses": [
{
'value': "bk.nguyenlinh#gmail.com"
}
],
"addresses": [
{
"streetAddress": "So 1 ngo 85 Lang Ha",
"extendedAddress": "Ba Dinh",
"city": "Ha Noi",
"region": "Ha Noi",
"postalCode": "10000",
"country": "Vietnam",
"countryCode": "84"
}
]
}).execute()
The def main, please anyone help me
def main():
creds = get_credentials(FLOW)
# print_list_google_contact_with_number_of_contacts(creds,1000)
http=get_http(creds)
#creat_a_google_contact(http)
# print_result(creds)
delete_contacts_with_resourceName(creds,http,1000)
#print_resourceName(creds, 2000)
Resource name is not formatted correctly:
If you try deleting the contact via Try this API from this page, you will notice that the URL to access has this shape:
https://people.googleapis.com/v1/people/c7142462727258425368:deleteContact
Where people/c7142462727258425368 is the contact's resourceName. That is to say, the resource name does not have single quotes (' ') nor brakets ({ }) around it. Since the resource name is not probably formatted in the URL, the API is not recognizing it, causing the 404 error.
That's what's failing in your request:
https://people.googleapis.com/v1/%7B'people/c9194159806299427121'%7D:deleteContact
To fix this, just remove the brackets around abcd when you provide it as resource name. It should be like this:
service.people().deleteContact(resourceName=abcd).execute()
Reference:
Method: people.deleteContact

How to accept None for String type field when using Flask-RESTPlus

I am just starting develop with flask-restplus and I am not a native speaker,
but I will try to describe my question as clear as I can.
I know there is a fields module in flask that help us define and filter response data type,
such as String, Integer, List and so on.
Is there any way to allow NULL / None when using fields module?
the following is my code that using field module to catch the value,
add_group = api.model(
"add_group",
{"team_groups": fields.List(fields.Nested(api.model("team_groups", {
"name": fields.String(example="chicago bulls", description="name of add group"),
"display_name": fields.String(example="bulls", description="display name of add group")})))})
and if the data type of display_name is not String, there would be the following error raised,
{
"errors": {
"team_groups.0.display_name": "123 is not of type 'string'"
},
"message": "Input payload validation failed"
}
what I want is when entering display_name, I can enter bulls or None
It seems few of the reference data / questions can be found, and I only found one result related
to my question, but eventually converting as non-null value to solve the issue.
if there is any part of my question not much clear,
please let me know, thank you.
the following is my develop environment:
flask-restplus 0.13.0
Python 3.7.4
postman 7.18.1
The following is my updated code:
from flask_restplus import Namespace, fields
class NullableString(fields.String):
__schema_type__ = ['string', 'null']
__schema_example__ = 'nullable string'
class DeviceGroupDto:
api = Namespace("device/group", description="device groups")
header = api.parser().add_argument("Authorization", location="headers", help="Bearer ")
get_detail_group = api.model(
"getdetail",
{"team_groups": fields.List(fields.String(required=True,
description="team group id to get detail", example=1))})
add_group = api.model(
"add_group",
{"team_groups": fields.List(fields.Nested(api.model("team_groups", {
"name": fields.String(example="chicago bulls", description="name of add group"),
"display_name": NullableString(attribute='a')})))})
if I input the following payload: (by postman)
{
"team_groups": [
{
"name": "chicago bulls",
"display_name": null
}
]
}
It still returns:
{
"errors": {
"team_groups.0.display_name": "None is not of type 'string'"
},
"message": "Input payload validation failed"
}
Yes, you can create a child class and use it instead of default ones, which will accept None as well
class NullableString(fields.String):
__schema_type__ = ['string', 'null']
__schema_example__ = 'nullable string'
So your code will look like
{ "property": NullableString(attribute=value)}
Additionally you can visit the issue github.com/noirbizarre/flask-restplus/issues/179
if some of your fields are optional then make required=False
add_group = api.model(
"add_group",
{"team_groups": fields.List(fields.Nested(api.model("team_groups", {
"name": fields.String(example="chicago bulls", description="name of add group"),
"display_name": fields.String(example="bulls", description="display name of add group", required=False)})))})
Here's slightly evolved approach that I use. It lets you have fields of any type as nullable.
def nullable(fld, *args, **kwargs):
"""Makes any field nullable."""
class NullableField(fld):
"""Nullable wrapper."""
__schema_type__ = [fld.__schema_type__, "null"]
__schema_example__ = f"nullable {fld.__schema_type__}"
return NullableField(*args, **kwargs)
employee = api.model(
"Employee",
{
"office": nullable(fields.String),
"photo_key": nullable(fields.String, required=True),
},
)

Sync with ganache-cli in python

I want to test a simple Ethereum smart contract
ganache prints accounts in lower-case and web3 gives me an error:
web3.exceptions.InvalidAddress: ('Web3.py only accepts checksum addresses. The software that gave you this non-checksum address should be considered unsafe, please file it as a bug on their platform. Try using an ENS name instead. Or, if you must accept lower safety, use Web3.toChecksumAddress(lower_case_address).', '0xfcad0b19bb29d4674531d6f115237e16afce377c')
I then convert the address to mixed address using:
Web3.toChecksumAddress(the_lower_case_ganache_address)
and it rises an error:
File "/usr/local/lib/python3.7/site-packages/web3/contract.py", line 1385, in call_contract_function
raise BadFunctionCallOutput(msg) from e
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?
127.0.0.1 - - [25/Jan/2019 21:35:21] "POST /blockchain/user HTTP/1.1" 500 -
it's my python code:
def check_gender(data):
valid_list = ["male", "female"]
if data not in valid_list:
raise ValidationError(
'Invalid gender. Valid choices are'+ valid_list
)
class UserSchema(Schema):
name = fields.String(required=True)
gender = fields.String(required=True, validate=check_gender)
app = Flask(__name__)
# api to set new user every api call
#app.route("/blockchain/user", methods=['POST'])
def transaction():
w3.eth.defaultAccount = w3.eth.accounts[0]
with open("data.json", 'r') as f:
datastore = json.load(f)
abi = datastore["abi"]
contract_address = datastore["contract_address"]
# Create the contract instance with the newly-deployed address
user = w3.eth.contract(
address=contract_address, abi=abi,
)
body = request.get_json()
result, error = UserSchema().load(body)
if error:
return jsonify(error), 422
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
tx_hash = tx_hash.transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)
user_data = user.functions.getUser().call()
return jsonify({"data": user_data}), 200
if __name__ == '__main__':
app.run()
`
and the json file:
{
"abi": [
{
"constant": false,
"inputs": [
{
"name": "name",
"type": "string"
},
{
"name": "gender",
"type": "string"
}
],
"name": "setUser",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "getUser",
"outputs": [
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"contract_address": "0xFCAd0B19bB29D4674531d6f115237E16AfCE377c"
}
The error is stating that Ganache cannot find a deployed contract to interact with.
Your code seems valid, but the error likely occurs on this line:
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
The code attempts to set the user, but cannot find a contract to interact with (even if the ABI and contract instance are valid).
If you are using Ganache, it is likely that you are redeploying the contract each time you run the code, so the following line will likely not be working, provided you are pulling from a static file:
contract_address = datastore["contract_address"]
You will need to dynamically get the contract address from Ganache if you are deploying it each time.

Why is code not executing after response received

I'm running the code below and it takes the user to PayPal to make a payment and then returns them to the return_url as expected. However the code doesn't execute any further and it doesn't execute the payment.
I have based my code on https://github.com/paypal/rest-api-sdk-python:
class PayPalHandler(tornado.web.RequestHandler):
def get(self):
logging.basicConfig(level=logging.INFO)
paypal.configure({
"mode": PAYPAL_MODE,
"client_id": PAYPAL_CLIENT_ID,
"client_secret": PAYPAL_CLIENT_SECRET})
payment = paypal.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal" },
"redirect_urls": {
"return_url": "http://127.0.0.1:8000/ty",
"cancel_url": "http://127.0.0.1:8000/" },
"transactions": [ {
"item_list": {
"items": [{
"name": "membership",
"price": "2.00",
"currency": "GBP",
"quantity": 1 }]},
"amount": {
"total": "2.00",
"currency": "GBP" },
"description": "One of membership fee." } ] } )
redirect_url = ""
if payment.create():
print("Payment[%s] created successfully"%(payment.id))
for link in payment.links:
if link.method == "REDIRECT":
redirect_url = link.href
print("Redirect for approval: %s"%(redirect_url))
return self.redirect(redirect_url)
else:
print("Error while creating payment.")
print(payment.error)
response = payment.to_dict()
print response
payment = paypal.Payment.find(payment.id)
if payment.execute({"payer_id": response['payer_id']}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
print payment.to_dict()
print userData
So in the example at https://devtools-paypal.com/guide/pay_paypal/python?success=true&token=EC-8JL96732FP068791F&PayerID=QQGSRNHDACTLJ. Step 5 is not happening and no response is sent from PayPal?
This is Avi from PayPal here. I am not super familiar with Tornado, but after the line return self.redirect(redirect_url) happens in your code, and returns the user to the return_url, in payment.execute({"payer_id": response['payer_id']}) are you getting the payer_id correctly? Payer_id is returned appended to the return_url as one of the parameters in the format http://<return_url>?token=EC-60U79048BN7719609&PayerID=7E7MGXCWTTKK2. Also, what is the status of the payment after you execute payment = paypal.Payment.find(payment.id). The other suggestion I would have is to see if print payment.error prints a useful debug message and a debug_id which paypal merchant technical services can use to look at the issue.
You need other url where papypal redirects when the payment had been successful, where you will receive the token and the PayerID. In that GET method, you can put this part of the code (pseudocode):
payerid_param = request.get('PayerID')
payment = paypal.Payment.find(db_payment.id)
if payment.execute({"payer_id": payerid_param}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
You will need to save the payment_id between calls.
Why you use
return self.redirect(redirect_url)
I think you can use just
self.redirect(redirect_url)
I've never seen return statement in Tornado handlers.

Categories