alexa skill local could not write to dynamodb - amazon-dynamodb

I am writing a node.js skill using ask-sdk and using alexa-skill-local to test the endpoint. I need to persist data to DynamoDb in one of the handler. But I keep getting "missing region error". Please find my code below:
'use strict';
// use 'ask-sdk' if standard SDK module is installed
const Alexa = require('ask-sdk');
const { launchRequestHandler, HelpIntentHandler, CancelAndStopIntentHandler, SessionEndedRequestHandler } = require('./commonHandlers');
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
return handlerInput.responseBuilder
.speak('Sorry, I can\'t understand the command. Please say again.')
.reprompt('Sorry, I can\'t understand the command. Please say again.')
.getResponse();
},
};
////////////////////////////////
// Code for the handlers here //
////////////////////////////////
exports.handler = Alexa.SkillBuilders
.standard()
.addRequestHandlers(
launchRequestHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
ErrorHandler
)
.withTableName('devtable')
.withDynamoDbClient()
.lambda();
And in one of the handler I am trying to get persisted attributes like below:
handlerInput.attributesManager.getPersistentAttributes().then((data) => {
console.log('--- the attributes are ----', data)
})
But I keep getting the following error:
(node:12528) UnhandledPromiseRejectionWarning: AskSdk.DynamoDbPersistenceAdapter Error: Could not read item (amzn1.ask.account.AHJECJ7DTOPSTT25R36BZKKET4TKTCGZ7HJWEJEBWTX6YYTLG5SJVLZH5QH257NFKHXLIG7KREDKWO4D4N36IT6GUHT3PNJ4QPOUE4FHT2OYNXHO6Z77FUGHH3EVAH3I2KG6OAFLV2HSO3VMDQTKNX4OVWBWUGJ7NP3F6JHRLWKF2F6BTWND7GSF7OVQM25YBH5H723VO123ABC) from table (EucerinSkinCareDev): Missing region in config
at Object.createAskSdkError (E:\projects\nodejs-alexa-sdk-v2-eucerin-skincare-dev\node_modules\ask-sdk-dynamodb-persistence-adapter\dist\utils\AskSdkUtils.js:22:17)
at DynamoDbPersistenceAdapter.<anonymous> (E:\projects\nodejs-alexa-sdk-v2-eucerin-skincare-dev\node_modules\ask-sdk-dynamodb-persistence-adapter\dist\attributes\persistence\DynamoDbPersistenceAdapter.js:121:45)
Can we read and write attributes from DynamoDb using alexa-skill-local ? Do we need some different setup to achieve this ?
Thanks

I know that this is a really old topic, but I had the same problem few days ago, and I'm gonna explain how I did it work.
You have to download DynamoDB Locally and follow the instructions from here
Once that you have configure your local DynamoDB and check that it is working. You have to pass it through your code, to DynamoDbPersistenceAdapter constructor.
Your code should look similar to:
var awsSdk = require('aws-sdk');
var myDynamoDB = new awsSdk.DynamoDB({
endpoint: 'http://localhost:8000', // If you change the default url, change it here
accessKeyId: <your-access-key-id>,
secretAccessKey: <your-secret-access-key>,
region: <your-region>,
apiVersion: 'latest'
});
const {DynamoDbPersistenceAdapter} = require('ask-sdk-dynamodb-persistence-adapter');
return new DynamoDbPersistenceAdapter({
tableName: tableName || 'my-table-name',
createTable: true,
dynamoDBClient: myDynamoDB
});
Where <your-acces-key-id>, <your-secrete-access-key> and <your-region> are defined at aws config and credentials files.
The next step is launch your server with alexa-skill-local command as always.
Hope this will be helpfull! =)

Presumably you have an AWS config profile that your skill is using when running locally.
You need to edit the .config file and set the default region (ie us-east-1) there. The region should match the region where your table exists.
Alternatively, if you want to be able to run completely isolated, you may need to write come conditional logic and swap the dynamo client with one targeting an instance of DynamoDB Local running on your machine.

Related

Firebase remote config returns an object

Trying to get Firebase remote config working. A remote config parameter "ab_placeholder_value" has been setup with a default value "abvertisement" in Firebase, published too.
React Native code:
remoteConfig().fetchAndActivate()
.then(fetchedRemotely => {
if (fetchedRemotely) {
console.log('Configs were retrieved from the backend and activated.')
} else {
console.log(
'No configs were fetched from the backend, and the local configs were already activated',
)
}
})
remoteConfig().fetch(0)
const val = remoteConfig().getValue('ab_placeholder_value')
console.log('The ab_placeholder_value: ')
console.log(val)
remoteConfig().fetch(1)
const all = remoteConfig().getAll()
console.log('All values: ')
console.log(all)
Output:
LOG The ab_placeholder_value:
LOG {"_source": "default", "_value": "disabled"}
LOG All values:
LOG {"ab_placeholder_value": {"_source": "default", "_value": "disabled"}}
LOG Configs were retrieved from the backend and activated.
Looks like the app is talking with the Firebase server, since the parameter name "ab_placeholder_value" has been retrieved. But why is the parameter value an object: {"_source": "default", "_value": "disabled"}?
How can I get the value set in Firebase remote config? Any help is appreciated!
remoteConfig().fetchAndActivate() returns an object. You can access values of it in your case by using ._value:
const val = remoteConfig().getValue('ab_placeholder_value')._value;
console.log('The ab_placeholder_value: ')
console.log(val)
I initially run everything through a function to create a remoteConfigValues object and then access values stored in that object throughout the code to make things a bit more readable:
remoteConfig.fetchAndActivate()
.then(() => {
remoteConfigAllObj = remoteConfig.getAll();
var remoteConfigValues = {};
for (let key in remoteConfigAllObj){
remoteConfigValues[key] = remoteConfigAllObj[key]._value;
}
})
The values from the remoteConfig object then become available using the dot notation from the created remoteConfigValues object.
console.log(remoteConfigValues.ab_placeholder_value);
NOTE – In my case I load the remoteConfig before app initialization at startup. The remoteConfigValues object will therefore contain whatever is activated at that time, so it may be a mix of values from static, remote, and default variables. If you want to know where the values came from originally, you'll find that information under remoteConfigAllObj[key]._source for each key in the remoteConfigAllObj that you gathered in the beginning.

How to send a file with RTK Query from Redux Toolkit?

I am trying to use RTK Query mutations to upload a file to the API. Here is my mutation code:
addBanner: builder.mutation({
query(body) {
return {
url: `/api/banners`,
method: 'POST',
body,
}
},
})
Here is how I generate the data for request.
const [addBanner, { isBannerLoading }] = useAddBannerMutation();
const new_banner = new FormData();
new_banner.append("file", my_file);
new_banner.append("type", my_type);
new_banner.append("title", my_title);
addBanner(new_banner).unwrap().then( () => ...
But I get an error:
A non-serializable value was detected in the state, in the path: `api.mutations.L-Mje7bYDfyNCC4NcxFD3.originalArgs.file`...
I know I can disable non-serializable check entirely through middleware, but I don't think it is an appropriate way of using Redux Toolkit and RTK. Without a file all works fine. Is there any right way of uploading files with RTK?
Edit: This has been fixed with #reduxjs/toolkit 1.6.1 - please update your package
I just opened an issue for this: https://github.com/reduxjs/redux-toolkit/issues/1239 - thanks for bringing it up!
For now, you'll probably have to disable that check (you can do so for a certain path in the state while keeping it for the rest with the ignoredPath option).

How to pass a parameter from the Jupyter backend to a frontend extension

I currently have a value that is stored as an environment variable the environment where a jupyter server is running. I would like to somehow pass that value to a frontend extension. It does not have to read the environment variable in real time, I am fine with just using the value of the variable at startup. Is there a canonical way to pass parameters a frontend extension on startup? Would appreciate an examples of both setting the parameter from the backend and accessing it from the frontend.
[update]
I have posted a solution that works for nbextentions, but I can't seem to find the equivalent pattern for labextensions (typescript), any help there would be much appreciated.
I was able to do this by adding the following code to my jupter_notebook_config.py
from notebook.services.config import ConfigManager
cm = ConfigManager()
cm.update('notebook', {'variable_being_set': value})
Then I had the parameters defined in my extension in my main.js
// define default values for config parameters
var params = {
variable_being_set : 'default'
};
// to be called once config is loaded, this updates default config vals
// with the ones specified by the server's config file
var update_params = function() {
var config = Jupyter.notebook.config;
for (var key in params) {
if (config.data.hasOwnProperty(key) ){
params[key] = config.data[key];
}
}
};
I also have the parameters declared in my main.yaml
Parameters:
- name: variable_being_set
description: ...
input_type: text
default: `default_value`
This took some trial and error to find out because there is very little documentation on the ConfigManager class and none of it has an end-to-end example.

AWS : dynamodb.restoreTableFromBackup is not a function

I'm trying to use lambda to restore a table in dynamoDB,
but keep getting this error message.
TypeError: dynamodb.restoreTableFromBackup is not a function
Could anyone tell me how to fix it?Thanks~
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#restoreTableFromBackup-property
'use strict';
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
const params = {
BackupArn: 'arn:aws:dynamodb:us-east-1/xxxxx',
TargetTableName: 'xxx',
};
dynamodb.restoreTableFromBackup(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
I ran the code you provided in my own lambda and got the same result.
It seems the AWS SDK that is provided natively in Lambda isn't the latest version, with the restoreTableFromBackup function.
If I do the same test while using the latest available in npm, it seems to work fine.
As a work around, I suggest uploading your lambda as a zip file, and including the the node_modules/aws-sdk along with your code.
This will ensure it uses the latest aws-sdk which includes the restoreTableFromBackup function.
To assist further, I've written a walk through of how to use On-Demand backups / restore and how to schedule these backups.
https://www.abhayachauhan.com/2017/12/dynamodb-scheduling-on-demand-backups
HTH
'npm install aws-sdk' in Cloud9 terminal for the Lambda

How to delete a large node in firebase

I have a Firebase child node with about 15,000,000 child objects with a total size of about 8 GB of data.
exampele data structure:
firebase.com/childNode/$pushKey
each $pushKey contains a small flat dictionary:
{a: 1.0, b: 2.0, c: 3.0}
I would like to delete this data as efficiently and easy as possible. How?
What i Tried:
My first try was a put request:
PUT firebase.com/childNode.json?auth=FIRE_SECRET
data-raw: null
response: {
"error": "Data requested exceeds the maximum size that can be accessed with a single request. Contact support#firebase.com for help."
}
So that didn't work, let's do a limit request:
PUT firebase.com/childNode.json?auth=FIRE_SECRET&orderBy="$key"&limitToFirst=100
data-raw: null
response: {
"error": "Querying related parameters not supported on this request type"
}
No luck so far :( What about writing a script that will get the first X number of keys and then create a patch request with each value set to null?
GET firebase.com/childNode.json?auth=FIRE_SECRET&shallow=true&orderBy="$key"&limitToLast=100
{
"error" : "Mixing 'shallow' and querying parameters is not supported"
}
It's really not going to be easy this one? I could remove the shallow requirement and get the keys, and finish the script. I was just hoping there would be a easier/more efficient way???
Another thing i tried were to create a node script that listen for childAdded and then directly tries to remove those children?
ref.authWithCustomToken(AUTH_TOKEN, function(error, authData) {
if (error) {console.log("Login Failed!", error)}
if (!error) {console.log("Login Succeeded!", authData)}
ref.child("childNode").on("child_added", function(snap) {
console.log(`found: ${snap.key()}`)
ref.child("childNode").child(snap.key()).remove( function(err) {
if (!err) {console.log(`deleted: ${snap.key()}`)}
})
})
})
This script actually hangs right now, but earlier I did receive somethings like a max stack limit warning from firebase. I know this is not a firebase problem, but I don't see any particular easy way to solve that problem.
Downloading a shallow tree, will download only the keys. So instead of asking the server to order and limit, you can download all keys.
Then you can order and limit it client-side, and send delete requests to Firebase in batches.
You can use this script for inspiration: https://gist.github.com/wilhuff/b78e7391396e09f6c614
Use firebase cli tool for this: firebase database:remove --project .
In Browser Console this is fastest way
database.ref('data').limitToFirst(10000).once('value', snap => {
var updates = {};
snap.forEach(snap => {
updates[snap.key] = null;
});
database.ref('data').update(updates);
});

Resources