BigchainDB issue with send_commit - bigchaindb

I am learning BigchainDB and I am trying to store a payload on the blockchain with the following code:
alice = generate_keypair()
metadata = {'planet': 'earth'}
bicycle = {
'data': {
'bicycle': {
'serial_number': 'abcd1234',
'manufacturer': 'bkfab',
},
},
}
tx = bdb.transactions.prepare(
operation='CREATE',
signers=alice.public_key,
asset=bicycle,
metadata=metadata,
)
signed_tx = bdb.transactions.fulfill(tx,private_keys=alice.private_key)
sent_creation_tx = bdb.transactions.send_commit(signed_tx)
return sent_creation_tx
I got a 500 from the send_commit.
What I am doing wrong?

Related

AWS Lex v2 bot response card giving error on twilio

Problem statement: I want to access Lex V2 chatbot with response card buttons on WhatsApp.
I created a Lex V2 bot, and created a channel for Twilio. Connected Twilio through WhatsApp, and able to use my bot fine for plaintext responses. But in my bot, I also return a response card with buttons for one of the slot values. This works fine on AWS console, but when I run it through Twilio, it gives error saying response body is empty, or too big. Sharing my lambda code below. Please help on how to make it work?
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
//console.log("EVENT = ", event);
const sessionState = event['sessionState'];
const sessionAttributes = sessionState['sessionAttributes'];
const location = get_slot(event, 'Location');
const checkInDate = get_slot(event, "CheckInDate");
const nights = get_slot(event, "Nights");
const roomType = get_slot(event, "RoomType");
const response = "Booking completed for location = " + location +
", checkInDate = " + checkInDate +
", nights = " + nights +
", roomType = " + roomType;
console.log('slots = ', response);
if(!roomType){
const message = {
'contentType': 'ImageResponseCard',
"imageResponseCard": {
"title": "Room Type",
"subtitle": "Select your room preference",
//"imageUrl": "",
"buttons": [
{
"text": "King",
"value": "king"
},
{
"text": "Queen",
"value": "queen"
},
{
"text": "Deluxe",
"value": "deluxe"
}
]
}
};
/*const message = {
'contentType': 'PlainText',
'content': 'select room king.q'
};*/
return elicit_intent(event, sessionAttributes, message);
}
const message = {
'contentType': 'PlainText',
'content': response
};
return close(event, sessionAttributes, message);
};
function close(intent_request, session_attributes, message) {
intent_request['sessionState']['intent']['state'] = "Fulfilled";
return {
'sessionState': {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Close'
},
'intent': intent_request['sessionState']['intent']
},
'messages': [message],
'sessionId': intent_request['sessionId'],
'requestAttributes': intent_request['requestAttributes']
};
}
function elicit_intent(intent_request, session_attributes, message){
intent_request['sessionState']['intent']['state'] = "InProgress";
return {
'sessionState': {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'ElicitSlot',
"slotToElicit": "RoomType",
},
'intent': intent_request['sessionState']['intent']
},
'messages': [message],
'sessionId': intent_request['sessionId'],
'requestAttributes': intent_request['requestAttributes']
};
}
function get_slot(intent_request, slotName) {
const slots = intent_request['sessionState']['intent']['slots'];
if(slots[slotName] && slots[slotName].value && slots[slotName].value.interpretedValue){
return slots[slotName].value.interpretedValue;
}
return null;
}
Twilio developer evangelist here.
The Twilio API for WhatsApp currently only supports messages with buttons via registered template messages.
Once your template with buttons has been approved, you can send buttons as part of your WhatsApp messages. To send a button, you need to send a message that contains the body of the template. The buttons are automatically appended to the message.
In your case, you will need to send a message body so that the template can be matched and include the buttons.

Bittrex REST API for Python, I want to create an order using API v3 https://api.bittrex.com/v3/orders

I need help to create orders using the bittrex version 3 REST API. I have the code below and I can't understand what is missing to work.
I can make other GET calls, but I cannot make this POST request.
I don't know how to deal with the passing of parameters.
Official documentation at https://bittrex.github.io/api/v3#tag-Orders.
def NewOrder(market, amount, price):
#print 'open sell v3', market
market = 'HEDG-BTC'#'BTC-'+market
uri = 'https://api.bittrex.com/v3/orders?'
params = {
'marketSymbol': 'BTC-HEDG',#'HEDG-BTC', #market
'direction': 'BUY',
'type': 'LIMIT',
'quantity': amount,
'limit': price,
'timeInForce': 'POST_ONLY_GOOD_TIL_CANCELLED',
'useAwards': True
}
timestamp = str(int(time.time()*1000))
Content = ""
contentHash = hashlib.sha512(Content.encode()).hexdigest()
Method = 'POST'
uri2 = buildURI(uri, params)
#uri2 = 'https://api.bittrex.com/v3/orders?direction=BUY&limit=0.00021&marketSymbol=HEDG-BTC&quantity=1.1&timeInForce=POST_ONLY_GOOD_TIL_CANCELLED&type=LIMIT&useAwards=True'
#print uri2
PreSign = timestamp + uri2 + Method + contentHash# + subaccountId
#print PreSign
Signature = hmac.new(apisecret, PreSign.encode(), hashlib.sha512).hexdigest()
headers = {
'Api-Key' : apikey,
'Api-Timestamp' : timestamp,
'Api-Content-Hash': contentHash,
'Api-Signature' : Signature
}
r = requests.post(uri2, data={}, headers=headers, timeout=11)
return json.loads(r.content)
NewOrder('HEDG', 1.1, 0.00021)
And my error message:
{u'code': u'BAD_REQUEST', u'data': {u'invalidRequestParameter': u'direction'}, u'detail': u'Refer to the data field for specific field validation failures.'}
It seems from the documentation that this body is expected by the api as json data:
{
"marketSymbol": "string",
"direction": "string",
"type": "string",
"quantity": "number (double)",
"ceiling": "number (double)",
"limit": "number (double)",
"timeInForce": "string",
"clientOrderId": "string (uuid)",
"useAwards": "boolean"
}
and you are setting these values as url params that's the issue.
you need to do this:
uri = 'https://api.bittrex.com/v3/orders'
# NOTE >>>> please check that you provide all the required fields.
payload = {
'marketSymbol': 'BTC-HEDG',#'HEDG-BTC', #market
'direction': 'BUY',
'type': 'LIMIT',
'quantity': amount,
'limit': price,
'timeInForce': 'POST_ONLY_GOOD_TIL_CANCELLED',
'useAwards': True
}
# do rest of the stuffs as you are doing
# post payload as json data with the url given in doc
r = requests.post(uri, json=payload, headers=headers, timeout=11)
print(r.json())
If you still have issues let us know. If it works then please mark answer as accepted.
Hope this helps.
I made the following modifications to the code but started to give error in 'Content-Hash'
I'm assuming that some parameters are optional so they are commented.
def NewOrder(market, amount, price):
market = 'BTC-'+market
uri = 'https://api.bittrex.com/v3/orders'
payload = {
'marketSymbol': market,
'direction': 'BUY',
'type': 'LIMIT',
'quantity': amount,
#"ceiling": "number (double)",
'limit': price,
'timeInForce': 'POST_ONLY_GOOD_TIL_CANCELLED',
#"clientOrderId": "string (uuid)",
'useAwards': True
}
#ceiling (optional, must be included for ceiling orders and excluded for non-ceiling orders)
#clientOrderId (optional) client-provided identifier for advanced order tracking
timestamp = str(int(time.time()*1000))
Content = ''+json.dumps(payload, separators=(',',':'))
print Content
contentHash = hashlib.sha512(Content.encode()).hexdigest()
Method = 'POST'
#uri2 = buildURI(uri, payload)#line not used
print uri
#PreSign = timestamp + uri2 + Method + contentHash# + subaccountId
PreSign = timestamp + uri + Method + contentHash# + subaccountId
print PreSign
Signature = hmac.new(apisecret, PreSign.encode(), hashlib.sha512).hexdigest()
headers = {
'Api-Key' : apikey,
'Api-Timestamp' : timestamp,
'Api-Content-Hash': contentHash,
'Api-Signature' : Signature
}
r = requests.post(uri, json=payload, headers=headers, timeout=11)
print(r.json())
return json.loads(r.content)
NewOrder('HEDG', 1.5, 0.00021)
{u'code': u'INVALID_CONTENT_HASH'}
Bittrex API via requests package PYTHON
import hmac
import hashlib
import time, requests
nonce = str(int(time.time() * 1000))
content_hash = hashlib.sha512(''.encode()).hexdigest()
signature = hmac.new(
'<SECRET_KEY>'.encode(),
''.join([nonce, url, 'GET', content_hash]).encode(),
hashlib.sha512
).hexdigest()
headers = {
'Api-Timestamp': nonce,
'Api-Key': '<API_KEY>',
'Content-Type': 'application/json',
'Api-Content-Hash': content_hash,
'Api-Signature': signature
}
result = requests.get(url=url, headers=headers)

How to stop Graphql + Django-Filters to return All Objects when Filter String is Empty?

Using:
Django 3.x [ Django-Filters 2.2.0, graphene-django 2.8.0, graphql-relay 2.0.1 ]
Vue 2.x [ Vue-Apollo ]
I have a simple Birds Django-Model with Fields like name, habitat and applied different Filters on these Fields like icontains or iexact. My Goal was to apply a simple search field in my Frontend (Vue). So far it works, but whenever this Filter Value is empty or has blanks (see Example 3), Graphql returns all Objects.
My first approach was on the FrontEnd and to use some kind of logic on my input value, like when String is Empty/blank send isnull=true . But then i thought that Django should handle this in the first place.
I guess this Issue relates to my filters (see Django < relay_schema.py) or in other words do i have to apply some kind of logic on these Filters?
In the moment i try to customize some filterset_class but it feels like this would maybe too much, maybe i missed something? So i ask here if maybe someone has some hints, therefore my question is:
How to stop Graphql + Django-Filters to return All Objects when Filter String is Empty?
GraphiQL IDE
Example 1
query {birdsNodeFilter (name_Iexact: "finch") {
edges {
node {
id
name
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}
Fine for me!
Example 2
query {birdsNodeFilter (name_Iexact: "Unicorns") {
edges {
node {
id
name
habitat
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": []
}
}
}
No Unicorns there - good
Example 3
query {birdsNodeFilter (name_Iexact: "") {
edges {
node {
id
name
}
}
}
}
Return
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
},
{
"node": {
"id": "QmlyZHNOb2RlOjI=",
"name": "Bald Eagle",
"habitat": "USA"
}
},
<...And so on...>
Not fine for me!
Django
relay_schema.py
class BirdsNode(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['iexact'],
'name': ['iexact', 'icontains', 'istartswith', 'isnull'],
'habitat': ['iexact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
class BirdQuery(graphene.ObjectType):
birdConNode = relay.Node.Field(BirdsNode)
birdsNodeFilter = DjangoFilterConnectionField(BirdsNode)
This is my Solution which worked in GraphiQL and in my Frontend VUE.
I added a logic to the Birds2Query with def resolve_all_birds2 for each Filter (for testing purpose not on all Filter ) .
Besides that i also added a ExtendedConnection for counting.
Note: i changed the class names from my former Question.
Update: This Solution works on the python side. But the apollo client provides also the Apollo manager - also known as Dollar Apollo - there you can also use the this.$apollo.queries.tags.skip property as an static or dynamic solution to start and stop queries.
relay_schema.py
class ExtendedConnection(Connection):
class Meta:
abstract = True
total_count = Int()
edge_count = Int()
name_check = ""
def resolve_total_count(root, info, **kwargs):
return root.length
def resolve_edge_count(root, info, **kwargs):
return len(root.edges)
class Birds2Node(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['exact', 'icontains'],
'name': ['exact', 'icontains', 'istartswith', 'iendswith'],
}
interfaces = (relay.Node, )
connection_class = ExtendedConnection
class Birds2Query(ObjectType):
birds2 = relay.Node.Field(Birds2Node)
all_birds2 = DjangoFilterConnectionField(Birds2Node)
def resolve_all_birds2(self, info, **kwargs):
# Filtering for Empty/ Blank Values in Filter.Key.Value before returning queryset
if 'name__icontains' in kwargs:
nameIcon = kwargs['name__icontains']
nameIconBool = bool(nameIcon.strip()) # if blanks turns False
if nameIconBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
if 'name__istartswith' in kwargs:
nameIsta = kwargs['name__istartswith']
nameIstaBool = bool(nameIsta.strip()) # if blanks turns False
if nameIstaBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
return
GraphiQL
Blockquote
Example 1
query {allBirds2 (name_Icontains:""){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
Stopped to return all Objects while Filter is blank.
{
"data": {
"allBirds2": {
"totalCount": 0,
"edgeCount": 0,
"edges": []
}
}
}
Example 2 with blanks and one letter
query {allBirds2 (name_Icontains:" f "){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
return - exactly what i wanted
{
"data": {
"allBirds2": {
"totalCount": 1,
"edgeCount": 1,
"edges": [
{
"node": {
"id": "QmlyZHMyTm9kZTox",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}

AWS RDS Data API executeStatement not return column names

I'm playing with the New Data API for Amazon Aurora Serverless
Is it possible to get the table column names in the response?
If for example I run the following query in a user table with the columns id, first_name, last_name, email, phone:
const sqlStatement = `
SELECT *
FROM user
WHERE id = :id
`;
const params = {
secretArn: <mySecretArn>,
resourceArn: <myResourceArn>,
database: <myDatabase>,
sql: sqlStatement,
parameters: [
{
name: "id",
value: {
"stringValue": 1
}
}
]
};
let res = await this.RDS.executeStatement(params)
console.log(res);
I'm getting a response like this one, So I need to guess which column corresponds with each value:
{
"numberOfRecordsUpdated": 0,
"records": [
[
{
"longValue": 1
},
{
"stringValue": "Nicolas"
},
{
"stringValue": "Perez"
},
{
"stringValue": "example#example.com"
},
{
"isNull": true
}
]
]
}
I would like to have a response like this one:
{
id: 1,
first_name: "Nicolas",
last_name: "Perez",
email: "example#example.com",
phone: null
}
update1
I have found an npm module that wrap Aurora Serverless Data API and simplify the development
We decided to take the current approach because we were trying to cut down on the response size and including column information with each record was redundant.
You can explicitly choose to include column metadata in the result. See the parameter: "includeResultMetadata".
https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html#API_ExecuteStatement_RequestSyntax
Agree with the consensus here that there should be an out of the box way to do this from the data service API. Because there is not, here's a JavaScript function that will parse the response.
const parseDataServiceResponse = res => {
let columns = res.columnMetadata.map(c => c.name);
let data = res.records.map(r => {
let obj = {};
r.map((v, i) => {
obj[columns[i]] = Object.values(v)[0]
});
return obj
})
return data
}
I understand the pain but it looks like this is reasonable based on the fact that select statement can join multiple tables and duplicated column names may exist.
Similar to the answer above from #C.Slack but I used a combination of map and reduce to parse response from Aurora Postgres.
// declarative column names in array
const columns = ['a.id', 'u.id', 'u.username', 'g.id', 'g.name'];
// execute sql statement
const params = {
database: AWS_PROVIDER_STAGE,
resourceArn: AWS_DATABASE_CLUSTER,
secretArn: AWS_SECRET_STORE_ARN,
// includeResultMetadata: true,
sql: `
SELECT ${columns.join()} FROM accounts a
FULL OUTER JOIN users u ON u.id = a.user_id
FULL OUTER JOIN groups g ON g.id = a.group_id
WHERE u.username=:username;
`,
parameters: [
{
name: 'username',
value: {
stringValue: 'rick.cha',
},
},
],
};
const rds = new AWS.RDSDataService();
const response = await rds.executeStatement(params).promise();
// parse response into json array
const data = response.records.map((record) => {
return record.reduce((prev, val, index) => {
return { ...prev, [columns[index]]: Object.values(val)[0] };
}, {});
});
Hope this code snippet helps someone.
And here is the response
[
{
'a.id': '8bfc547c-3c42-4203-aa2a-d0ee35996e60',
'u.id': '01129aaf-736a-4e86-93a9-0ab3e08b3d11',
'u.username': 'rick.cha',
'g.id': 'ff6ebd78-a1cf-452c-91e0-ed5d0aaaa624',
'g.name': 'valentree',
},
{
'a.id': '983f2919-1b52-4544-9f58-c3de61925647',
'u.id': '01129aaf-736a-4e86-93a9-0ab3e08b3d11',
'u.username': 'rick.cha',
'g.id': '2f1858b4-1468-447f-ba94-330de76de5d1',
'g.name': 'ensightful',
},
]
Similar to the other answers, but if you are using Python/Boto3:
def parse_data_service_response(res):
columns = [column['name'] for column in res['columnMetadata']]
parsed_records = []
for record in res['records']:
parsed_record = {}
for i, cell in enumerate(record):
key = columns[i]
value = list(cell.values())[0]
parsed_record[key] = value
parsed_records.append(parsed_record)
return parsed_records
I've added to the great answer already provided by C. Slack to deal with AWS handling empty nullable character fields by giving the response { "isNull": true } in the JSON.
Here's my function to handle this by returning an empty string value - this is what I would expect anyway.
const parseRDSdata = (input) => {
let columns = input.columnMetadata.map(c => { return { name: c.name, typeName: c.typeName}; });
let parsedData = input.records.map(row => {
let response = {};
row.map((v, i) => {
//test the typeName in the column metadata, and also the keyName in the values - we need to cater for a return value of { "isNull": true } - pflangan
if ((columns[i].typeName == 'VARCHAR' || columns[i].typeName == 'CHAR') && Object.keys(v)[0] == 'isNull' && Object.values(v)[0] == true)
response[columns[i].name] = '';
else
response[columns[i].name] = Object.values(v)[0];
}
);
return response;
}
);
return parsedData;
}

Google Maps Geolocation API returns the latitude and longitude of my server

During my testing the Geolocation API use to return proper result.
But in deployment on AWS it is returning me the IP address of Virginia where my EC2 instances are located.
"cellId": 27193,
"locationAreaCode": 17007,
"mobileCountryCode": 404,
"mobileNetworkCode": 20
Result:
"lat": 19.2019619,
"lng": 73.1063466
But on AWs it returns:
"lat": 39.043756699999996
"lng": -77.4874416
params = {
"key": SERVER_KEY
}
data = json.dumps({
"cellTowers": [
{
"cellId": cid,
"locationAreaCode": lac,
"mobileCountryCode": mcc,
"mobileNetworkCode": mnc
}
]
})
log.info(params)
log.info(data)
request = requests.post(HOST_URL, params=params, data=data)
# print(request.text)
# print(request.status_code)
if request.status_code == 200:
response = json.loads(request.text)
latitude = response["location"]["lat"]
longitude = response["location"]["lng"]
return {
"latitude": latitude,
"longitude": longitude
}
else:
error_data = request.text
log.error("Error Occurred in Finding Cell Tower Location")
log.error(request.text)
log.error(json.dumps(params))
send_error_notification(error_data)
return None
Answer is so simple and how silly of me assuming that not adding header would not affect me.
By just adding the header with application/json everything is working like a charm.
params = {
"key": SERVER_KEY
}
data = json.dumps({
"considerIp": False,
"cellTowers": [
{
"cellId": cid,
"locationAreaCode": lac,
"mobileCountryCode": mcc,
"mobileNetworkCode": mnc
}
]
})
headers = {
'content-type': "application/json",
'cache-control': "no-cache"
}
log.info(params)
log.info(data)
request = requests.post(HOST_URL, params=params, data=data, headers=headers)