I desperatly try to set parameters in a
dialogflow.types.EventInput
in python.
This doc says the parameters need to be of type Struct.
I read here that the parameters needs to be a google.protobuf.Struct.
But it does not work for me.
Is there another Struct type equivalent in python?
If i send the EventInput without parameters, the intent is detected correctly.
I tried this so far:
import dialogflow_v2 as dialogflow
session_client = dialogflow.SessionsClient()
session = session_client.session_path(project_id, session_id)
parameters = struct_pb2.Struct()
parameters['given-name'] = 'Jeff'
parameters['last-name'] = 'Bridges'
event_input = dialogflow.types.EventInput(
name='greetPerson',
language_code='de',
parameters=parameters)
query_input = dialogflow.types.QueryInput(event=event_input)
response = session_client.detect_intent(
session=session, query_input=query_input)
Anybody having experience with this usecase?
Things i also tried:
Pass a class named p yields:
Parameter to MergeFrom() must be instance of same class: expected
Struct got p. for field EventInput.parameters
Pass a dict:
parameters = {
'given-name': 'Jeff',
'last-name': 'Bridges'}
yields:
Protocol message Struct has no "given-name" field.
Generate Struct with constructor:
from google.protobuf.struct_pb2 import Struct, Value
parameters = Struct(fields={
'given-name':Value(string_value='Jeff'),
'last-name':Value(string_value='Bidges')
})
yields sometimes:
Exception in thread ptvsd.stopping (most likely raised during
interpreter shutdown):
/EventInput
This is how I did this:
import dialogflow
from google.protobuf import struct_pb2
session_client = dialogflow.SessionsClient()
session = session_client.session_path(project_id, session_id)
parameters = struct_pb2.Struct()
parameters["given-name"] = 'Jeff'
parameters["last-name"] = 'Bridges'
query_input = {
'event': {
"name": "greetPerson",
"parameters": parameters,
"language_code": "de"
}
}
response = session_client.detect_intent(
session=session,
query_input=query_input)
Note:
In dialogflow console, you must give default values of parameters as #even_name.parameter_name.
In this case for parameter given-name it would be #greetPerson.given-name and for last-name it would be #greetPerson.last-name.
Docs Reference:
We are using DetectIntent, in which we are using QueryInput, in which finally we are using EvenInput
Hope it helps.
Information in accepted answer is incorrect.
You don't have to provide default values.
You can reference event parameters directly in Value column of Parameters table.
To reference an event parameter in the parameter table or a response,
use the following format: #event-name.parameter-name.
dialogflow docs
Therefore, putting #greetPerson.given-name in Value would be enough.
Related
I want to get the Default value of OnlineAvailability as True. By default, all Doctors will have all Slot Timings Available.
If I give the JSON Body data in Postman and POST the data:
http://127.0.0.1:8000/online
{
"OnlineTimeSlot": "18:30"
}
Here, OnlineAvailability is being set to true by default and I get the message:
{
"message": "New Time Slot, 18:30 added!"
}
When I GET the data, it shows:
http://127.0.0.1:8000/online/16
{
"OnlineScheduleId": 16,
"OnlineTimeSlot": "18:30",
"OnlineAvailability": true
}
But,
If I want to give the OnlineAvailability as false and POST the data or If I want to update the existing Timings Data using the PUT method in Postman JSON body:
http://127.0.0.1:8000/online
{
"OnlineTimeSlot": "18:30",
"OnlineAvailability": false
}
Then, I am getting the error:
sqlalchemy.exc.StatementError: (builtins.TypeError) Not a boolean value: 'False'
[SQL: INSERT INTO "OnlineSchedules" ("OnlineTimeSlot", "OnlineAvailability") VALUES (?, ?)]
[parameters: [{'OnlineTimeSlot': '18:30', 'OnlineAvailability': 'False'}]]
// Werkzeug Debugger
How do I change the default value from true to false or upload a new Time Slot with OnlineAvailability as false without getting the above error? (The value should be recognised as a Boolean Value instead of a String)
online.py --> models
# omitted code
class OnlineScheduleModel(db.Model):
# omitted code
OnlineTimeSlot = db.Column(db.String(500), unique=True, nullable=False)
OnlineAvailability = db.Column(db.Boolean, nullable=False, default=True, server_default="true")
def __init__(self, OnlineTimeSlot, OnlineAvailability):
self.OnlineTimeSlot = OnlineTimeSlot
self.OnlineAvailability = OnlineAvailability
def json(self):
return {"OnlineScheduleId": self.OnlineScheduleId, "OnlineTimeSlot": self.OnlineTimeSlot, "OnlineAvailability": self.OnlineAvailability}
# ommitted code
online.py --> resources
# omitted code
class OnlineScheduleInfo(Resource):
parser = reqparse.RequestParser()
parser.add_argument("OnlineTimeSlot", required=True)
parser.add_argument("OnlineAvailability", required=False)
# omitted code
#cross_origin(supports_credentials=True)
def post(self):
data = OnlineScheduleInfo.parser.parse_args()
schedule = OnlineScheduleModel(**data)
if OnlineScheduleModel.find_by_timeslot(data['OnlineTimeSlot']):
return {"message": "A timeslot '{}' already exists".format(data['OnlineTimeSlot'])}, 400
# omitted code
schedule.save_to_db()
# omitted code
return {"message": "New Time Slot, {} added!".format(data['OnlineTimeSlot'])}, 200
#cross_origin(supports_credentials=True)
def put(self):
data = OnlineScheduleInfo.parser.parse_args()
schedule = OnlineScheduleModel.find_by_timeslot(data['OnlineTimeSlot'])
if schedule is None:
schedule = OnlineScheduleModel(**data)
else:
schedule.OnlineAvailability = data["OnlineAvailability"]
schedule.save_to_db()
return {"message": "schedule, {} Updated!".format(data['OnlineTimeSlot'])}, 200
Basically, My requirement is that I should be able to POST or PUT data with OnlineAvailability as false, and I should get the output in Postman for GET:
http://127.0.0.1:8000/online/16
{
"OnlineScheduleId": 16,
"OnlineTimeSlot": "18:00",
"OnlineAvailability": false
}
Just a small change in the code mentioned by nstvnsn,
Flask-RESTPlus is no longer being maintained.
So, instead, we can use flask_restx.
from flask_restx import inputs
parser.add_argument("OnlineAvailability", required=False, type=inputs.boolean)
When you are adding an argument to the parser, you can leave out the type argument for simple primitive types. For boolean, you may need to declare it for wider boolean handling. Different databases handle boolean values differently.
If you look at the docs for sqlite3, which is the engine your app is using, it stores boolean values as 0 for false and 1 for true. The parser needs to know that the added argument is a boolean so it can parse the python native boolean type.
from flask_restplus import inputs
parser.add_argument('OnlineAvailability', required=False, type=inputs.boolean)
To confirm this, I hacked together an app to reproduce the problem by using the code you provided:
I added the type argument to the parser.add_argument function call and the same post request through cURL works:
Also, looking through the docs for Flask_restplus.reqparse.RequestParser (which is considered deprecated past 2.0, their docs mention it being replaced with a better alternative like marshmallow):
Warning
The whole request parser part of Flask-RESTPlus is slated for removal and will be replaced by documentation on how to integrate with other packages that do the input/output stuff better (such as marshmallow). This means that it will be maintained until 2.0 but consider it deprecated. Don’t worry, if you have code using that now and wish to continue doing so, it’s not going to go away any time too soon.
https://flask-restplus.readthedocs.io/en/stable/parsing.html
I have looked through the FTX api documentation found here: https://docs.ftx.us/#overview
And I've looked at example code found in this repo: https://github.com/ftexchange/ftx/tree/master/rest
I can't 'get' or 'post' anything that requires the Authentication. I am using the api key on my account that has 'full trade permissions', and when I look at: print(request.headers) the headers look like they are in the right format.
I've tried: using google colab instead of vs code, updating all my libraries, generating a new api key, restarting kernel and computer. I can pull something like 'markets' because it doesn't need the Authentication.
Let me know if you need any more information, below is a portion of the code I have that isolates the problem and returns {'success': False, 'error': 'Not logged in'}
import time
import urllib.parse
from typing import Optional, Dict, Any, List
from requests import Request, Session, Response
import hmac
ep = 'https://ftx.us/api/wallet/balances'
ts = int(time.time() * 1000)
s = Session()
request = Request('GET', ep)
prepared = request.prepare()
signature_payload = f'{ts}{prepared.method}{prepared.path_url}'.encode()
if prepared.body:
signature_payload += prepared.body
signature = hmac.new(secret.encode(), signature_payload, 'sha256').hexdigest()
request.headers['FTX-KEY'] = key
request.headers['FTX-SIGN'] = signature
request.headers['FTX-TS'] = str(ts)
response = s.send(prepared)
data = response.json()
print(data)
I've faced with the same problem.
You need to change this part:
prepared.headers['FTX-KEY'] = key
prepared.headers['FTX-SIGN'] = signature
prepared.headers['FTX-TS'] = str(ts)
PS. I believe that the FTX needs to fix their API documentation
PSS. I've checked the a part of https://github.com/ftexchange/ftx/tree/master/rest code. I beleave FTX guys just do a copy-paste into docs this code but originally it belongs to more a sophisticated object oriented solution that will work correctly because they pass into method an already created request and use a prepared variable just to calculate path_url and method
For ftx.us, you need to use different headers:
prepared.headers['FTXUS-KEY'] = key
prepared.headers['FTXUS-TS'] = str(ts)
prepared.headers['FTXUS-SIGN'] = signature
I'm trying to "wrap" Google Python Client for AI Platform (Unified) into a Cloud Function.
import json
from google.cloud import aiplatform
from google.protobuf import json_format
from google.protobuf.struct_pb2 import Value
def infer(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
request_json = request.get_json()
project="simple-1234"
endpoint_id="7106293183897665536"
location="europe-west4"
api_endpoint = "europe-west4-aiplatform.googleapis.com"
# The AI Platform services require regional API endpoints.
client_options = {"api_endpoint": api_endpoint}
# Initialize client that will be used to create and send requests.
# This client only needs to be created once, and can be reused for multiple requests.
client = aiplatform.gapic.PredictionServiceClient(client_options=client_options)
# for more info on the instance schema, please use get_model_sample.py
# and look at the yaml found in instance_schema_uri
endpoint = client.endpoint_path(
project=project, location=location, endpoint=endpoint_id
)
instance = request.json["instances"]
instances = [instance]
parameters_dict = {}
parameters = json_format.ParseDict(parameters_dict, Value())
try:
response = client.predict(endpoint=endpoint, instances=instances, parameters=parameters)
if 'error' in response:
return (json.dumps({"msg": 'Error during prediction'}), 500)
except Exception as e:
print("Exception when calling predict: ", e)
return (json.dumps({"msg": 'Exception when calling predict'}), 500)
print(" deployed_model_id:", response.deployed_model_id)
# See gs://google-cloud-aiplatform/schema/predict/prediction/tables_classification.yaml for the format of the predictions.
predictions = response.predictions
for prediction in predictions:
print(" prediction:", dict(prediction))
return (json.dumps({"prediction": response['predictions']}), 200)
When calling client.predict() I'm getting exception 400
{"error": "Required property Values is not found"}
What am I doing wrong?
I believe your parameters variable is not correct, in the documentation example that variable is set like this, as an example:
parameters = predict.params.ImageClassificationPredictionParams(
confidence_threshold=0.5, max_predictions=5,
).to_value()
This is probably why the error says the properties are not found. You will have to set your own parameters and then call the predict method.
I'm trying to rename a ArangoDB collection using pyArango. This is what I have so far:
connection = pyArango.Connection('http://random-address', username='random-username', password='random-password')
test_db = Database(connection, 'test-db')
collection = test_db["new"]
collection.action("PUT", "rename", name="newname")
The code fails in line 4:
{'error': True, 'code': 400, 'errorNum': 1208, 'errorMessage': 'name
must be non-empty'}
I'm probably using the action method incorrectly but the documentation does not provide any examples. Anybody got an idea?
A JSON object {"name": "newname"} needs to be passed as request body. The new name can not be passed as URL path parameter. The problem is the implementation of collection.action():
def action(self, method, action, **params) :
"a generic fct for interacting everything that doesn't have an assigned fct"
fct = getattr(self.connection.session, method.lower())
r = fct(self.URL + "/" + action, params = params)
return r.json()
The keyword arguments end up as dict called params. This object is passed to the request function fct() as named parameter params. This parameter receives the dict and converts it to URL path parameters, e.g. ?name=newname which is not supported by the HTTP API of the server.
There is unfortunately no way to pass a payload via action(). You can write some custom code however:
from pyArango.connection import *
connection = Connection('http://localhost:8529', username='root', password='')
try:
connection.createDatabase('test-db')
except CreationError:
pass
test_db = Database(connection, 'test-db')
try:
test_db.createCollection(name='new')
except CreationError:
pass
collection = test_db['new']
r = connection.session.put(collection.URL + '/rename', data='{"name":"newname"}')
print(r.text)
collection = test_db['newname']
You can also use a dict for the payload and transform it to JSON if you want:
import json
...put(..., data=json.dumps({"name": "newname"}))
I've fixed it like this:
def rename_collection(arango_uri, username, password, database, collection, new_name):
url = '{}/_db/{}/_api/collection/{}/rename'.format(arango_uri, database, collection)
params = {"name": new_name}
response = requests.put(url, data=json.dumps(params), auth=HTTPBasicAuth(username, password))
return response
I'm trying to create my own jsonrpc client for a project, using python and requests. After an hour of searching online, Most errors are to do with people executing a get rather than a post or people getting a different error. According the the JSONRPC Spec (Found Here http://www.jsonrpc.org/specification) It should work. Any help would be most grateful. Thanks Sam.
Requests & Code Below:
Post Request Body:
{"method": "GudMethod", "params": {"ur": "HELLO"}, "jsonrpc": "2.0", "id": 1}
Request Response:
{
"jsonrpc": "2.0",
"result": {
"method": "GudMethod",
"success": false,
"error": "Invalid API parameter [jsonrpc] must be 2.0 [\"GudMethod\"]",
"extra": [],
"metrics": {
"st": "2018-05-24 22:16:37",
"sspt": 0.0006299018859863281
}
},
"id": null
}
Codes:
import json
import requests
class Client():
def __init__(self,url):
self.url = url
self.id = 0
def request(self,method,prms):
rq = Request(self,method,prms)
return rq
class Request():
def __init__(self,client,method,prms):
self.client = client
self.method = method
self.prms = prms
self.rq = None
def buildRequest(self):
self.client.id = self.client.id + 1
url = self.client.url + "?method={}".format(self.method)
jb = {}
jb["jsonrpc"] = "2.0"
jb["method"] = self.method
jb["params"] = self.prms
jb["id"] = self.client.id
body = json.dumps(jb)
return url,body
def execute(self):
url , body = self.buildRequest()
self.rq = requests.post(url,data=body)
print(body)
print(self.rq.text)
Also, dont ask me to use a ready made one. I was told that already, but due to where the project will be used, I can't install any librarys. Luckily requests will be installed, that would be painful otherwise
Your client's request looks fine.
The server must be parsing your request incorrectly, assigning the value GudMethod to the name jsonrpc.
Not only is the server parsing your request incorrectly, but the response also is not valid according to the JSON-RPC specification:
1) There should be no result field:
result
This member is REQUIRED on success.
This member MUST NOT exist if there was an error invoking the method.
The value of this member is determined by the method invoked on the Server.
2) There should be a top-level error field:
error
This member is REQUIRED on error.
This member MUST NOT exist if there was no error triggered during invocation.
The value for this member MUST be an Object as defined in section 5.1.
3) The error field should be a JSON Object with the following fields:
code
A Number that indicates the error type that occurred.
This MUST be an integer.
message
A String providing a short description of the error.
The message SHOULD be limited to a concise single sentence.
data
A Primitive or Structured value that contains additional information about the error.
This may be omitted.
The value of this member is defined by the Server (e.g. detailed error information, nested errors etc.).
As the server erroneously believes the jsonrpc field is not equal to 2.0, the error code field should be -32600 and the message field Invalid Request indicating
The JSON sent is not a valid Request object.