Predict AutoML google return INVALID_ARGUMENT on NodeJS - node.js

I have a problem with my AutoML code. I want to link it to a web project. I've used the Google tutorial but it doesn't work. I receive this error in my console :
payload : { row:
{ values:
[ [Object], [Object], [Object], [Object], [Object], [Object] ] } }
{ Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
at Object.callErrorFromStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call.js:30:26)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client.js:175:52)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client-interceptors.js:341:141)
at Object.onReceiveStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\client-interceptors.js:304:181)
at Http2CallStream.outputStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:116:74)
at Http2CallStream.maybeOutputStatus (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:155:22)
at Http2CallStream.endCall (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:141:18)
at Http2CallStream.handleTrailers (E:\Projects\SchoolProject\banking\api\node_modules#grpc\grpc-js\build\src\call-stream.js:273:14)
at ClientHttp2Stream.emit (events.js:198:13)
at emit (internal/http2/core.js:265:8)
code: 3,
details: 'Request contains an invalid argument.',
metadata:
Metadata {
internalRepr: Map { 'grpc-server-stats-bin' => [Array] },
options: {} } }
Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
My code looks like this
It Comes from this github repo
I've created the JSON credentials to use my ML code to website
On this project, I use Express (i've deleted the code for you)
// ========================================
// Config modules
// ========================================
const clientOptions = {
apiEndpoint: 'eu-automl.googleapis.com'
};
const client = new automl.v1beta1.PredictionServiceClient(clientOptions);
// =======================================
// Function for api route
// =======================================
const projectId = '*****'; // Project ID from GCP
const computeRegion = 'eu'; // eu (like my bucket)
const modelId = '******'; // modelID from my CGP Table ML
const modelFullId = client.modelPath(projectId, computeRegion, modelId);
console.log("modelFullId :", modelFullId)
const sendDataPredict = async (data) => {
let values = [];
for (const val in data) {
values.push({
[typeof val == 'string' ? 'stringValue' : 'numberValue']: val
});
}
const payload = {
row: {
values: values
},
};
I've tried with Postman but i have the same error.
Many thanks for all your help

Try to use this:
const clientOptions = {
apiEndpoint: 'eu-automl.googleapis.com',
port: '443'
};

Related

How can I fix update_mask.paths error on AnalyticsAdminServiceClient(GA4) Nodejs?

I tried to update "DataRetentionSettings" using Google Analytics Admin Client(GA4) in Nodejs, but I got the following error.
Error: 3 INVALID_ARGUMENT: One or more values in the field 'update_mask.paths_list' was invalid, but all values must be valid.eventDataRetention, resetUserDataOnNewActivity
at Object.callErrorFromStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\call.js:31:26)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client.js:189:52)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:365:141)
at Object.onReceiveStatus (C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\client-interceptors.js:328:181)
at C:\my_working_path\GA4_manager\node_modules\#grpc\grpc-js\build\src\call-stream.js:187:78
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 3,
details: "One or more values in the field 'update_mask.paths_list' was invalid, but all values must be valid.eventDataRetention, resetUserDataOnNewActivity",
metadata: Metadata {
internalRepr: Map(1) { 'grpc-server-stats-bin' => [Array] },
options: {}
},
note: 'Exception occurred in retry method that was not classified as transient'
}
The code is as follows.
const analyticsAdmin = require("#google-analytics/admin");
class Main {
constructor() {
this.analyticsAdminClient = new analyticsAdmin.AnalyticsAdminServiceClient({
keyFilename: "./mykeyfile.json",
});
}
async updateDataRetentionSettings() {
const name = "properties/*********/dataRetentionSettings";
const request = {
dataRetentionSettings: {
name: name,
eventDataRetention: "FOURTEEN_MONTHS",
resetUserDataOnNewActivity: true,
},
updateMask: {
paths: ["eventDataRetention", "resetUserDataOnNewActivity"],
},
};
let retention = {};
try {
retention = await this.analyticsAdminClient.updateDataRetentionSettings(request);
} catch (e) {
console.log(e);
process.exit(1);
}
return retention[0];
}
}
const client = new Main();
client.updateDataRetentionSettings();
I also added "name" to the paths property of updateMask and the result was the same.
Here is the document I referred to.
AnalyticsAdminServiceClient
And the client version is 4.0.0.
How can I update DataRetentionSettings via API?
To update property in GA 4 then you could try as follows :
const {AnalyticsAdminServiceClient} = require('#google-analytics/admin').v1alpha; // ---> This dependency should be installed
const credentialFile = '/usr/local/credentialFile.json';
const adminClient = new AnalyticsAdminServiceClient(
{keyFilename: credentialFile} // --> credentialFile will be the path of service account's detail json file in your local machine
);
async function callUpdateProperty() {
// Construct request
const updateMask = {
paths: ["display_name"] // --> Please keep in mind that name should in camel case. like I have added for 'displayName' as 'display_name'
};
const property = {
"name" : "properties/123",
"displayName": "New Display Name"
};
const request = {
property,
updateMask,
};
// Run request
const response = await adminClient.updateProperty(request);

FastifyError [Error]: Failed building the validation schema for POST

I am writing a web app with fastify in typescript. I have generated the project using fastify-cli.
fastify generate --lang=ts try-fastify-typescript
I have used #sinclair/typebox for schema validation. But I am getting the below error when running the app npm start.
FastifyError [Error]: Failed building the validation schema for POST:
/user, due to error strict mode: unknown keyword: "kind"
at Boot. (/Volumes/Segate Backup Plus Drive/projects/javascript/try-fastify-typescript/node_modules/fastify/lib/route.js:309:21)
at Object.onceWrapper (events.js:519:28)
at Boot.emit (events.js:412:35)
at /Volumes/Segate Backup Plus Drive/projects/javascript/try-fastify-typescript/node_modules/avvio/boot.js:160:12
at /Volumes/Segate Backup Plus Drive/projects/javascript/try-fastify-typescript/node_modules/avvio/plugin.js:276:7
at done (/Volumes/Segate Backup Plus Drive/projects/javascript/try-fastify-typescript/node_modules/avvio/plugin.js:201:5)
at check (/Volumes/Segate Backup Plus Drive/projects/javascript/try-fastify-typescript/node_modules/avvio/plugin.js:225:9)
at internal/process/task_queues.js:141:7
at AsyncResource.runInAsyncScope (async_hooks.js:197:9)
at AsyncResource.runMicrotask (internal/process/task_queues.js:138:8) { code:
'FST_ERR_SCH_VALIDATION_BUILD', statusCode: 500 }
Below is my code.
import { FastifyPluginAsync, RouteShorthandOptions } from 'fastify';
import { Static, Type } from '#sinclair/typebox';
const User = Type.Object({
name: Type.String(),
mail: Type.Optional(Type.String({ format: "email" })),
});
type UserType = Static<typeof User>;
const reqOpts: RouteShorthandOptions = {
schema: {
body: User
}
};
interface GetUserRequest {
Body: UserType,
Reply: UserType
}
const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.get('/', async function (request, reply) {
return { root: true }
});
fastify.post<GetUserRequest>('/user', reqOpts, async(request, reply)=> {
request.log.info("User Name: " + request.body.name);
request.log.info("User Mail: " + request.body.mail);
return {...request.body};
});
}
export default root;
Adding the full code repository here.

Cognito - Error: Invalid UserPoolId format

I am using AWS CDK to create a userpool and userpool client. I would like to be able to access the userpool id and userpool client id from a lambda once they have been created. I pass these two values to the lambda via environmental variables. Here is my code:
import { Construct } from 'constructs';
import {
IResource,
LambdaIntegration,
MockIntegration,
PassthroughBehavior,
RestApi,
} from 'aws-cdk-lib/aws-apigateway';
import {
NodejsFunction,
NodejsFunctionProps,
} from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import * as amplify from 'aws-cdk-lib/aws-amplify';
import {
aws_s3,
aws_ec2,
aws_rds,
aws_cognito,
aws_amplify,
Duration,
CfnOutput,
} from 'aws-cdk-lib';
export class FrontendService extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
const userPool = new aws_cognito.UserPool(this, 'userpool', {
userPoolName: 'frontend-userpool',
selfSignUpEnabled: true,
signInAliases: {
email: true,
},
autoVerify: { email: true },
});
const userPoolClient = new aws_cognito.UserPoolClient(
this,
'frontend-app-client',
{
userPool,
generateSecret: false,
}
);
const bucket = new aws_s3.Bucket(this, 'FrontendStore');
const nodeJsFunctionProps: NodejsFunctionProps = {
environment: {
BUCKET: bucket.bucketName,
DB_NAME: 'hospoFEDB',
AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
USER_POOL_ID: userPool.userPoolId,
USER_POOL_CLIENT_ID: userPoolClient.userPoolClientId,
},
runtime: Runtime.NODEJS_14_X,
};
const registerLambda = new NodejsFunction(this, 'registerFunction', {
entry: 'dist/lambda/register.js',
memorySize: 1024,
...nodeJsFunctionProps,
});
const registerIntegration = new LambdaIntegration(registerLambda);
const api = new RestApi(this, 'frontend-api', {
restApiName: 'Frontend Service',
description: 'This service serves the frontend.',
});
const registerResource = api.root.addResource('register');
registerResource.addMethod('POST', registerIntegration);
}
}
Here is my lambda function and how I intend to use the USER_POOL_ID and USER_POOL_CLIENT_ID env variables:
import {
CognitoUserPool,
} from 'amazon-cognito-identity-js';
export const handler = async (event: any, context: any) => {
try {
console.log(process.env.USER_POOL_ID);
console.log(process.env.USER_POOL_CLIENT_ID);
const userPool = new CognitoUserPool({
UserPoolId: process.env.USER_POOL_ID as string,
ClientId: process.env.USER_POOL_CLIENT_ID as string,
});
return {
statusCode: 200,
};
} catch (error) {
if (error instanceof Error) {
const body = error.stack || (JSON.stringify(error, null, 2) as any);
return {
statusCode: 400,
headers: {},
body: JSON.stringify(body),
};
}
return {
statusCode: 400,
};
}
};
The idea with this setup is that I would create a cognito user pool and client then be able to pass those id's directly down. Currently if I run this locally via sam local start-api it generates the following USER_POOL_ID : Frontenduserpool87772999. If I try and use this id in the new CognitoUserPool({... part of my lambda function I get the following error:
Error: Invalid UserPoolId format.
If I deploy the app however and execute the lambda function from the deployed environment with the exact same code I get a USER_POOL_ID that looks more like: us-east-1_HAjkUj9hP. This works fine and I do not get the error above.
Should I assume that I can not create a user pool locally and will always have to point to the deployed user pool?
Should I assume that I can not create a user pool locally and will always have to point to the deployed user pool
Yes. See the docs: start-api creates an emulated local API endpoint and Lambda for local testing. It does not deploy or emulate other resources.
You can reference previously deployed AWS resources by passing a JSON file with the deployed physical values using the --env-vars flag.

Sample Apollo Client code to test APQ (Automated Persistent Queries)

I was trying to test APQ with a server written in haskell. The following is the sample Apollo client code, I wrote to test it:
const { createPersistedQueryLink } = require("apollo-link-persisted-queries")
const { createHttpLink } = require("apollo-link-http")
const { InMemoryCache } = require("apollo-cache-inmemory")
const { ApolloClient } = require("apollo-client")
const { gql } = require('apollo-server');
const { ApolloLink } = require("apollo-link")
const fetch = require("node-fetch")
const link = ApolloLink.from([
createPersistedQueryLink(),
createHttpLink({
uri: "http://localhost:8080/v1/graphql",
fetch: fetch,
headers: {
"admin-secret":"password"
}
})
]);
const client = new ApolloClient({
cache: new InMemoryCache(),
link: link
})
async function main() {
const response = await client
.query({
query: gql`
query {
child {
name
}
}`
})
console.log(response.data)
}
main().catch(err => console.log("Err:", err))
But whenever I run this file, I get the following error:
graphQLErrors: [
{
extensions: [Object],
message: "the key 'query' was not present"
}
],
When I check the Request body sent in POST Body, I get the following thing:
{"operationName":null,"variables":{},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"0832c514aef4b1a6d84702e8b2fab452cbb0af61f0a1c4a4c30405e671d40527"}}}
It tells that the query is not sent in the Post Body. Which might be the reason I'm getting the above error.
Hence, I am confused at this point :see_no_evil:
I read through a tons of blogs, but It's not clear as to what HTTP method is used when { useGETForHashedQueries: true } option is not given. From my experiment above, it looks as if - POST method is used.
But if POST method is used, why isn't the query sent in the POST body.
BUT
When I use the { useGETForHashedQueries: true } option, it works correctly. What might I be doing wrong here?
It would be really great, if someone would clear this out for me.

Mock multiple api call inside one function using Moxios

I am writing a test case for my service class. I want to mock multiple calls inside one function as I am making two API calls from one function. I tried following but it is not working
it('should get store info', async done => {
const store: any = DealersAPIFixture.generateStoreInfo();
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: store
});
const nextRequest = moxios.requests.at(1);
nextRequest.respondWith({
status: 200,
response: DealersAPIFixture.generateLocation()
});
});
const params = {
dealerId: store.dealerId,
storeId: store.storeId,
uid: 'h0pw1p20'
};
return DealerServices.retrieveStoreInfo(params).then((data: IStore) => {
const expectedOutput = DealersFixture.generateStoreInfo(data);
expect(data).toMatchObject(expectedOutput);
});
});
const nextRequest is always undefined
it throw error TypeError: Cannot read property 'respondWith' of undefined
here is my service class
static async retrieveStoreInfo(
queryParam: IStoreQueryString
): Promise<IStore> {
const res = await request(getDealerStoreParams(queryParam));
try {
const locationResponse = await graphQlRequest({
query: locationQuery,
variables: { storeId: res.data.storeId }
});
res.data['inventoryLocationCode'] =
locationResponse.data?.location?.inventoryLocationCode;
} catch (e) {
res.data['inventoryLocationCode'] = 'N/A';
}
return res.data;
}
Late for the party, but I had to resolve this same problem just today.
My (not ideal) solution is to use moxios.stubRequest for each request except for the last one. This solution is based on the fact that moxios.stubRequest pushes requests to moxios.requests, so, you'll be able to analyze all requests after responding to the last call.
The code will look something like this (considering you have 3 requests to do):
moxios.stubRequest("get-dealer-store-params", {
status: 200,
response: {
name: "Audi",
location: "Berlin",
}
});
moxios.stubRequest("graph-ql-request", {
status: 204,
});
moxios.wait(() => {
const lastRequest = moxios.requests.mostRecent();
lastRequest.respondWith({
status: 200,
response: {
isEverythingWentFine: true,
},
});
// Here you can analyze any request you want
// Assert getDealerStoreParams's request
const dealerStoreParamsRequest = moxios.requests.first();
expect(dealerStoreParamsRequest.config.headers.Accept).toBe("application/x-www-form-urlencoded");
// Assert graphQlRequest
const graphQlRequest = moxios.requests.get("POST", "graph-ql-request");
...
// Assert last request
expect(lastRequest.config.url).toBe("status");
});

Resources