I have a webhook, that call this function when
event["type"] == "payment_intent.amount_capturable_updated"
def capture_order(session):
ordered_uuid = uuid.UUID(session["metadata"]["pk_order"])
try:
order = Ordered.objects.filter(
pk=ordered_uuid
).prefetch_related(
"from_ordered", "from_ordered__to_product"
).get()
except Ordered.DoesNotExist:
stripe.PaymentIntent.cancel(session["id"])
return HttpResponse(status=400)
try:
products = set()
for ordered_product in order.from_ordered.all():
product = ordered_product.to_product
product.stock -= ordered_product.quantity
if product.stock < 0:
raise ValueError()
products.add(product)
with transaction.atomic():
Product.objects.bulk_update(list(products), ("stock",))
stripe.PaymentIntent.capture(session["id"])
except ValueError:
stripe.PaymentIntent.cancel(session["id"])
except IntegrityError:
stripe.PaymentIntent.cancel(session["id"])
return HttpResponse(status=200)
and I get this error:
This PaymentIntent could not be captured because it has a status of canceled. Only a PaymentIntent with one of the following statuses may be captured: requires_capture.
I had instantiate my checkout like this:
checkout_session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[
{
'price_data': {
'currency': 'eur',
'unit_amount_decimal': get_amount(self.object, with_delivery=True).quantize(TWO_PLACES),
'product_data': {
'name': f'Order #{self.object.pk}',
},
},
'quantity': 1,
},
],
payment_intent_data={
"capture_method": "manual",
"metadata": {
"pk_order": self.object.pk
}
})
any idea ?
You should inspect your dashboard logs - I suspect that one of your error paths is canceling the payment intent before you try to capture it. You'll need to trace through your login to figure out why that's happening.
Related
I am trying to retrieve some information about my ads in google. I have done the same for campaigns, adgroups and keywords and I haven't got a single issue, however, when it comes to ads and their metrics, I cannot manage to extract something other than adCost.
I have the following code to retrieve the info I need from google ads:
def ad_data(service, view_id, start_date, end_date):
# Initialize request with first page of results
request = {
'reportRequests': [
{
'viewId': view_id,
'dateRanges': [
{
'startDate': start_date,
'endDate': end_date
}
],
'metrics': [
{
'expression': 'ga:adCost'
},
{
'expression': 'ga:adClicks'
},
{
'expression': 'ga:adImpressions'
}
],
'dimensions': [
{
'name': 'ga:date'
},
{
'name': 'ga:campaign'
},
{
'name': 'ga:adContent'
}
],
'pageSize': 1000
}
]
}
all_data = []
while True:
# Make API call and get response
response = service.reports().batchGet(body=request).execute()
report = response.get('reports', [])[0]
rows = report.get('data', {}).get('rows', [])
all_data.extend(rows)
# Check if there are more pages of results
page_token = report.get('nextPageToken', None)
if not page_token:
break
# Update request with next page of results
request['reportRequests'][0]['pageToken'] = page_token
return all_data
The issue that I have is that for some reason I'm not being ale to retrieve metrics other than adCost, hence it shows me the following error:
HttpError: <HttpError 400 when requesting https://analyticsreporting.googleapis.com/v4/reports:batchGet?alt=json returned "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.". Details: "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.">
Could anyone help me out?
I am trying to update the parameters in SSM parameters store and got the below error. What mistake am I doing? pls clarify.
Lambda Code:
#Lambda code
logger = logging.getLogger()
logger.setLevel(logging.INFO)
ssm_client = boto3.client('ssm')
parameter_name = ''
def lambda_handler(event, context):
logger.info('Printing event: {}'.format(event))
process_sns_event(event)
return None
def process_sns_event(event):
for record in (event['Records']):
event_message = record['Sns']['Message']
# convert the event message to json
message_json = json.loads(event_message)
# obtain the image state
image_state = (message_json['state']['status'])
# obtain the image name
image_name = (message_json['name'])
# assign SSM parameter based on image_name
#parameter_name = f'/ec2-image-builder/{{image_name}}/latest'
def path(imagename):
first = "/ec2-image-builder/"
last = "/latest"
result = first + imagename + last
return result
parameter_name = path(image_name)
logger.info('image_name: {}'.format(image_name))
logger.info('ssm_parameter_name: {}'.format(parameter_name))
# update the SSM parameter if the image state is available
if (image_state == 'AVAILABLE'):
logger.info('Image is available')
# obtain ami id
ami = message_json['outputResources']['amis'][0]
recipe_name = message_json['name']
logger.info('AMI ID: {}'.format(ami['image']))
# update SSM parameter
response = ssm_client.put_parameter(
#Name=parameter_name,
Name='/ec2-image-builder/linux/latest',
Description='Latest AMI ID',
Value=ami['image'],
Type='String',
Overwrite=True,
Tier='Standard'
)
logger.info('SSM Updated: {}'.format(response))
# add tags to the SSM parameter
ssm_client.add_tags_to_resource(
ResourceType='Parameter',
ResourceId=ssm_parameter_namee,
Tags=[
{
'Key': 'Source',
'Value': 'EC2 Image Builder'
},
{
'Key': 'AMI_REGION',
'Value': ami['region']
},
{
'Key': 'AMI_ID',
'Value': ami['image']
},
{
'Key': 'AMI_NAME',
'Value': ami['name']
},
{
'Key': 'RECIPE_NAME',
'Value': recipe_name
},
{
'Key': 'SOURCE_PIPELINE_ARN',
'Value': message_json['sourcePipelineArn']
},
],
)
return None
Error output
Response on test:
{ "errorMessage": "name 'ssm_parameter_namee' is not defined",
"errorType": "NameError", "requestId":
"54ad245c-84f3-4c46-9e9b-1798f86a8bce", "stackTrace": [
" File "/var/task/lambda_function.py", line 19, in lambda_handler\n process_sns_event(event)\n",
" File "/var/task/lambda_function.py", line 71, in process_sns_event\n ResourceId=ssm_parameter_namee,\n" ] }
The answer is in your error ...
Typo name or namee ? Is it ssm_parameter_namee or ssm_parameter_name ?
I highly recommend using an IDE, that finger points you to such simple things :)
logger.info('ssm_parameter_name: {}'.format(parameter_name))
ResourceId=ssm_parameter_namee
I'm using the AWS lambda function to send alerts to our slack channel. But, due to some unknown issue, I'm not getting slack alert and not even getting any kind of error message from the AWS lambda function. Logs represent that the function ran successfully without any error but I do not receipt any alert
code:
import json, sys, csv, os
import requests
def lambda_handler(event, context):
def Send2Slack(message):
if __name__ == '__main__':
print('inside slack function')
url = "webhook_URL"
title = (f"New Incoming Message")
slack_data = {
"username": "abc",
"channel" : "xyz",
"attachments": [
{
"color": "#ECB22E",
"fields": [
{
"title": title,
"value": message,
"short": "false",
}
]
}
]
}
byte_length = str(sys.getsizeof(slack_data))
headers = {'Content-Type': "application/json", 'Content-Length': byte_length}
response = requests.post(url, data=json.dumps(slack_data), headers=headers)
if response.status_code != 200:
raise Exception(response.status_code, response.text)
output = "Hello Slack "
Send2Slack(output)
Please let me know where I'm doing wrong and help me fix this issue.
I'm able to answer this issue.
def Send2Slack(message):
if __name__ == '__main__':
Once I removed if __name__ == '__main__': from send2slack function the it worked.
Otherwise, I was not able to get into the function.
Thanks for all your help.
i have a model pruchase and a model transaction, transactions have a ForeignKey from pruchase and when a try run the tests success th first test_payment_request but the second test_payment_transaction_state faile an launch the next error:
django.db.utils.IntegrityError: The row in table 'transactions_transactionmodel' with primary key '0664aefce71447699d8ca9e7677ba4cc' has an invalid foreign key: transactions_transactionmodel.purchase_id contains a value 'ba7dc5ac0e1c4b9eb009e772f405f5db' that does not have a corresponding value in purchases_purchasemodel.id.
this is my test:
import datetime
import socket
from django.test import TestCase
from .payment import PaymentTransactions
from apps.purchases.models import PurchaseModel
class PaymentTransactionsTestCase(TestCase):
def setUp(self):
self.purchase = {"purchase":PurchaseModel( total_value = 124236,
products = [
{
"name": "Aretes",
"value": "6490"
},
{
"name": "Manilla",
"value": "6.000"
}
],
purchase_date = datetime.datetime.utcnow()
),
"value":124236,
"client_ip": socket.gethostbyname(socket.gethostname())
}
def test_payment_request(self):
error, payment, transaction = PaymentTransactions().\
payment_transaction_request(**self.purchase)
self.assertFalse(error)
self.assertTrue(payment)
self.assertIn("tpaga_payment_url", payment)
self.assertIn("token", payment)
self.assertEquals(transaction.token, payment["token"])
print("paso prueba 1")
def test_payment_transaction_state(self):
purchase = {"purchase":PurchaseModel( total_value = 124236,
products = [
{
"name": "Aretes",
"value": "6490"
},
{
"name": "Manilla",
"value": "6.000"
}
],
purchase_date = datetime.datetime.utcnow()
),
"value":124236,
"client_ip": socket.gethostbyname(socket.gethostname())
}
error, payment, transaction = PaymentTransactions().\
payment_transaction_request(**purchase)
self.assertFalse(error)
error, transaction_created = PaymentTransactions().\
payment_transaction_state(transaction.id)
self.assertFalse(error)
self.assertEquals(transaction_created.state, transaction.state)
but i don't know whatshappends if someone know, please can explain me.
Make change models.SOMETHING to models.CASCADE in your field of Model Payment.
I wrote some code to get data from a web API. I was able to parse the JSON data from the API, but the result I gets looks quite complex. Here is one example:
>>> my_json
{'name': 'ns1:timeSeriesResponseType', 'declaredType': 'org.cuahsi.waterml.TimeSeriesResponseType', 'scope': 'javax.xml.bind.JAXBElement$GlobalScope', 'value': {'queryInfo': {'creationTime': 1349724919000, 'queryURL': 'http://waterservices.usgs.gov/nwis/iv/', 'criteria': {'locationParam': '[ALL:103232434]', 'variableParam': '[00060, 00065]'}, 'note': [{'value': '[ALL:103232434]', 'title': 'filter:sites'}, {'value': '[mode=LATEST, modifiedSince=null]', 'title': 'filter:timeRange'}, {'value': 'sdas01', 'title': 'server'}]}}, 'nil': False, 'globalScope': True, 'typeSubstituted': False}
Looking through this data, I can see the specific data I want: the 1349724919000 value that is labelled as 'creationTime'.
How can I write code that directly gets this value?
I don't need any searching logic to find this value. I can see what I need when I look at the response; I just need to know how to translate that into specific code to extract the specific value, in a hard-coded way. I read some tutorials, so I understand that I need to use [] to access elements of the nested lists and dictionaries; but I can't figure out exactly how it works for a complex case.
More generally, how can I figure out what the "path" is to the data, and write the code for it?
For reference, let's see what the original JSON would look like, with pretty formatting:
>>> print(json.dumps(my_json, indent=4))
{
"name": "ns1:timeSeriesResponseType",
"declaredType": "org.cuahsi.waterml.TimeSeriesResponseType",
"scope": "javax.xml.bind.JAXBElement$GlobalScope",
"value": {
"queryInfo": {
"creationTime": 1349724919000,
"queryURL": "http://waterservices.usgs.gov/nwis/iv/",
"criteria": {
"locationParam": "[ALL:103232434]",
"variableParam": "[00060, 00065]"
},
"note": [
{
"value": "[ALL:103232434]",
"title": "filter:sites"
},
{
"value": "[mode=LATEST, modifiedSince=null]",
"title": "filter:timeRange"
},
{
"value": "sdas01",
"title": "server"
}
]
}
},
"nil": false,
"globalScope": true,
"typeSubstituted": false
}
That lets us see the structure of the data more clearly.
In the specific case, first we want to look at the corresponding value under the 'value' key in our parsed data. That is another dict; we can access the value of its 'queryInfo' key in the same way, and similarly the 'creationTime' from there.
To get the desired value, we simply put those accesses one after another:
my_json['value']['queryInfo']['creationTime'] # 1349724919000
I just need to know how to translate that into specific code to extract the specific value, in a hard-coded way.
If you access the API again, the new data might not match the code's expectation. You may find it useful to add some error handling. For example, use .get() to access dictionaries in the data, rather than indexing:
name = my_json.get('name') # will return None if 'name' doesn't exist
Another way is to test for a key explicitly:
if 'name' in resp_dict:
name = resp_dict['name']
else:
pass
However, these approaches may fail if further accesses are required. A placeholder result of None isn't a dictionary or a list, so attempts to access it that way will fail again (with TypeError). Since "Simple is better than complex" and "it's easier to ask for forgiveness than permission", the straightforward solution is to use exception handling:
try:
creation_time = my_json['value']['queryInfo']['creationTime']
except (TypeError, KeyError):
print("could not read the creation time!")
# or substitute a placeholder, or raise a new exception, etc.
Here is an example of loading a single value from simple JSON data, and converting back and forth to JSON:
import json
# load the data into an element
data={"test1": "1", "test2": "2", "test3": "3"}
# dumps the json object into an element
json_str = json.dumps(data)
# load the json to a string
resp = json.loads(json_str)
# print the resp
print(resp)
# extract an element in the response
print(resp['test1'])
Try this.
Here, I fetch only statecode from the COVID API (a JSON array).
import requests
r = requests.get('https://api.covid19india.org/data.json')
x = r.json()['statewise']
for i in x:
print(i['statecode'])
Try this:
from functools import reduce
import re
def deep_get_imps(data, key: str):
split_keys = re.split("[\\[\\]]", key)
out_data = data
for split_key in split_keys:
if split_key == "":
return out_data
elif isinstance(out_data, dict):
out_data = out_data.get(split_key)
elif isinstance(out_data, list):
try:
sub = int(split_key)
except ValueError:
return None
else:
length = len(out_data)
out_data = out_data[sub] if -length <= sub < length else None
else:
return None
return out_data
def deep_get(dictionary, keys):
return reduce(deep_get_imps, keys.split("."), dictionary)
Then you can use it like below:
res = {
"status": 200,
"info": {
"name": "Test",
"date": "2021-06-12"
},
"result": [{
"name": "test1",
"value": 2.5
}, {
"name": "test2",
"value": 1.9
},{
"name": "test1",
"value": 3.1
}]
}
>>> deep_get(res, "info")
{'name': 'Test', 'date': '2021-06-12'}
>>> deep_get(res, "info.date")
'2021-06-12'
>>> deep_get(res, "result")
[{'name': 'test1', 'value': 2.5}, {'name': 'test2', 'value': 1.9}, {'name': 'test1', 'value': 3.1}]
>>> deep_get(res, "result[2]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[-1]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[2].name")
'test1'