Generate descriptions in OpenAPI docs using Google Cloud Endpoints Framework - google-app-engine

I'm building an API using Google Cloud Endpoints Framework v2 on Python App Engine Standard.
Using Endpoints Framework means you can automatically generate OpenAPI / Swagger documentation directly from the code.
However I am unable to work out how to generate descriptions for each of the parameters (each field in a message) in the API directly from the code.
It's possible to generate a description for the entire API but not for each individual parameter.
Using Cloud Endpoints Framework Echo as an example:
"""This is a sample Hello World API implemented using Google Cloud
Endpoints."""
# [START imports]
import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote
# [END imports]
# [START messages]
class EchoRequest(messages.Message):
content = messages.StringField(1)
class EchoResponse(messages.Message):
"""A proto Message that contains a simple string field."""
content = messages.StringField(1)
ECHO_RESOURCE = endpoints.ResourceContainer(
EchoRequest,
n=messages.IntegerField(2, default=1))
# [END messages]
# [START echo_api]
#endpoints.api(name='echo', version='v1')
class EchoApi(remote.Service):
#endpoints.method(
# This method takes a ResourceContainer defined above.
ECHO_RESOURCE,
# This method returns an Echo message.
EchoResponse,
path='echo',
http_method='POST',
name='echo')
def echo(self, request):
output_content = ' '.join([request.content] * request.n)
return EchoResponse(content=output_content)
#endpoints.method(
# This method takes a ResourceContainer defined above.
ECHO_RESOURCE,
# This method returns an Echo message.
EchoResponse,
path='echo/{n}',
http_method='POST',
name='echo_path_parameter')
def echo_path_parameter(self, request):
output_content = ' '.join([request.content] * request.n)
return EchoResponse(content=output_content)
#endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='echo/getApiKey',
http_method='GET',
name='echo_api_key')
def echo_api_key(self, request):
return EchoResponse(content=request.get_unrecognized_field_info('key'))
#endpoints.method(
# This method takes an empty request body.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='echo/getUserEmail',
http_method='GET',
# Require auth tokens to have the following scopes to access this API.
scopes=[endpoints.EMAIL_SCOPE],
# OAuth2 audiences allowed in incoming tokens.
audiences=['your-oauth-client-id.com'])
def get_user_email(self, request):
user = endpoints.get_current_user()
# If there's no user defined, the request was unauthenticated, so we
# raise 401 Unauthorized.
if not user:
raise endpoints.UnauthorizedException
return EchoResponse(content=user.email())
# [END echo_api]
# [START api_server]
api = endpoints.api_server([EchoApi])
# [END api_server]
This is the accompanying swagger documentation that has been generated:
{
"basePath": "/_ah/api",
"consumes": [
"application/json"
],
"definitions": {
"MainEchoRequest": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
},
"MainEchoResponse": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
}
},
"host": "echo-api.endpoints.8085-dot-3333519-dot-5002-dot-devshell.appspot.com",
"info": {
"title": "echo",
"version": "v1"
},
"paths": {
"/echo/v1/echo": {
"post": {
"operationId": "EchoApi_echo",
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/MainEchoRequest"
}
},
{
"default": 1,
"format": "int64",
"in": "query",
"name": "n",
"type": "string"
}
],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
},
"/echo/v1/echo/getApiKey": {
"get": {
"operationId": "EchoApi_echoApiKey",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
},
"/echo/v1/echo/getUserEmail": {
"get": {
"operationId": "EchoApi_getUserEmail",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
},
"security": [
{
"google_id_token-c0b0c9d9": []
}
]
}
},
"/echo/v1/echo/{n}": {
"post": {
"operationId": "EchoApi_echoPathParameter",
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/MainEchoRequest"
}
},
{
"default": 1,
"format": "int64",
"in": "path",
"name": "n",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
}
},
"produces": [
"application/json"
],
"schemes": [
"https"
],
"securityDefinitions": {
"google_id_token": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v3/certs"
},
"google_id_token-c0b0c9d9": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-audiences": "your-oauth-client-id.com",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v3/certs"
}
},
"swagger": "2.0"
}
In the example above I'm looking to try and include a description for the content field in the EchoResponse and EchoRequest message types.
This could be done manually by navigating the OpenAPI specification path --> /echo/v1/echo --> parameters and adding in a description key/field there -
but can it be generated through the code?

Unfortunately, Endpoints Frameworks does not currently support this. The alternative you suggested of manually adding the description is the only way right now.

Related

Cores fail when trying to add requestHandler in Solr

I am new to Solr and am trying to add the Suggest Search Component via the Config API.
My Solr 9.0.0 setup is as follows:
bin/solr start -e cloud with _default config
Add the search component with a POST request to http://localhost:8983/api/collections/collection_name/config:
{
"add-searchcomponent": {
"name": "suggest",
"class": "solr.SuggestComponent",
"lookupImpl": "FuzzyLookupFactory",
"dictionaryImpl": "DocumentDictionaryFactory",
"field": "name",
"suggestAnalyzerFieldType": "string",
"buildOnStartup": "false"
}
}
Until here everything is fine and I receive a responseHeader with status 0.
Add the request handler with a POST request to http://localhost:8983/api/collections/collection_name/config:
{
"add-requesthandler": {
"name": "/suggest",
"class": "solr.SearchHandler",
"defaults": {
"suggest": "true",
"rows": "10"
},
"components": "suggest"
}
}
In step 3 I receive a responseHeader with status 500 and the following error message:
1 out of 2 the property overlay to be of version 4 within 30 seconds! Failed cores: [http://localhost:8983/solr/collection_name1_replica_n1/]
What am I doing wrong?
I could solve it. My error was not adding “components” in the add-requesthandler as an array.
original:
{
"add-requesthandler": {
"name": "/suggest",
"class": "solr.SearchHandler",
"defaults": {
"suggest": "true",
"rows": "10"
},
"components": "suggest"
}
}
correct:
{
"add-requesthandler": {
"name": "/suggest",
"class": "solr.SearchHandler",
"defaults": {
"suggest": "true",
"rows": "10"
},
"components": [“suggest"]
}
}

Alexa skills events not firing when hosted in web service

I have custom skill that calls web service i created. I am able to launch and get other intent, but i am not getting notification when permission for notification is changed by user of my skill. I need he notification event to get user id for sending push notifications later by other service.
Below is my json file:
{
"manifest": {
"apis": {
"custom": {
"endpoint": {
"uri": "https://pathToMyService",
"sslCertificateType": "Wildcard"
},
"interfaces": []
}
},
"events": {
"publications": [
{ "eventName": "AMAZON.TrashCollectionAlert.Activated" },
{ "eventName": "AMAZON.MessageAlert.Activated" }
],
"subscriptions": [
{ "eventName": "SKILL_PROACTIVE_SUBSCRIPTION_CHANGED" },
{ "eventName": "SKILL_ENABLED" },
{ "eventName": "SKILL_DISABLED" },
{ "eventName": "SKILL_PERMISSION_ACCEPTED" },
{ "eventName": "SKILL_PERMISSION_CHANGED" },
],
"regions": {
"NA": {
"endpoint": {
"uri": "https://pathToMyService",
"sslCertificateType": "Wildcard"
}
}
},
"endpoint": {
"uri": "https://pathToMyService",
"sslCertificateType": "Wildcard"
}
},
"manifestVersion": "1.0",
"permissions": [
{ "name": "alexa::devices:all:notifications:write" }
],
"publishingInformation": {
"locales": {
"en-US": { "name": "Test Events" }
}
}
}
}
Below is the Launch request: I have truncated applicatioId, userID, consentToken, deviceId, apiAccessToken
{"version":"1.0","session":{"new":true,"sessionId":"amzn1.echo-api.session.60ad1e76-0872-4e10-b79d-7144cdf3e1c9","application":{"applicationId":"amzn1.ask.skill.59d60703"},"user":{"userId":"amzn1.ask.account.AGB7EOY","permissions":{"consentToken":"eyJ0eXAiOiJKV1"}}},"context":{"System":{"application":{"applicationId":"amzn1.ask.skill.59d60703"},"user":{"userId":"amzn1.ask.account.AGB7EOY","permissions":{"consentToken":"eyJ0eXAiOiJKV1Qi"}},"device":{"deviceId":"amzn1.ask.device.AFNXDZOAEMFDFKK","supportedInterfaces":{}},"apiEndpoint":"https://api.amazonalexa.com","apiAccessToken":"eyJ0eXAiOiJKV1Qi"}},"request":{"type":"LaunchRequest","requestId":"amzn1.echo-api.request.adb318af-1977-4b36-b8ad-0bb4352fa563","timestamp":"2020-03-22T23:37:55Z","locale":"en-US","shouldLinkResultBeReturned":false}}
Thanks
I resolved the issue: When I updated by skill.json file using
ask api update-skill -s amzn1.ask.skill.59d6 -f Test.json
it didn't update properly. I noticed today when I got latest
ask api get-skill -s amzn1.ask.skill.59d6 >Test2.json
the event section was missing. I added back and reapplied and it's working now.

Internal Server Error when creating Conditional Access Policy

I referred to this documentation to make a POST request.
Below is the error while making a POST request to create a conditional access policy
{
"message": "There was an internal server error while processing the request. Error ID: 2dbb1530-4ce6-44f5-9c63-08de28d7218a",
"innerError": {
"request-id": "2dbb1530-4ce6-44f5-9c63-08de28d7218a"
}
}
Payload being passed with the request is below:
{
"displayName": "Test Policy",
"state": "enabled",
"conditions": {
"clientAppTypes": ["modern", "browser"],
"applications": {
"includeApplications": ["None"]
},
"users": {
"includeUsers": [
"08290005-23ba-46b4-a377-b381d651a2fb"
]
},
"locations": {
"includeLocations": ["All"],
"excludeLocations": ["AllTrusted"]
}
},
"grantControls": {
"operator": "OR",
"builtInControls": ["approvedApplication"]
}
}
I've tried using this endpoint to get a policy:
https://graph.microsoft.com/beta/{tenant_id}/conditionalAccess/policies
Which successfully returns an existing policy. However, the above POST request is not working.
The "approvedApplication" requirement only supports the iOS and Android for device platform condition. See details here.
You need to add "includePlatforms" iOS and android into the json body.
{
"displayName": "Test Policy",
"state": "enabled",
"conditions": {
"clientAppTypes": ["modern", "browser"],
"applications": {
"includeApplications": ["None"]
},
"users": {
"includeUsers": [
"08290005-23ba-46b4-a377-b381d651a2fb"
]
},
"platforms": {
"includePlatforms": [
"iOS", "android"
]
},
"locations": {
"includeLocations": ["All"],
"excludeLocations": ["AllTrusted"]
}
},
"grantControls": {
"operator": "OR",
"builtInControls": ["approvedApplication"]
}
}

IBM CLOUD function action took too long to respond in IBM watson chat dialog

Hi, I am creating a chatbot. I developed a IBM cloud function(action) in IBM.
This is the action code..
{
"context": {
"my_creds": {
"user": "ssssssssssssssssss",
"password": "sssssssssssssssssssssss"
}
},
"output": {
"generic": [
{
"values": [
{
"text": ""
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"actions": [
{
"name": "ssssssssssss/user-detail",
"type": "server",
"parameters": {
"name": "<?input.text?>",
"lastname": "<?input.text?>"
},
"credentials": "$my_creds",
"result_variable": "$my_result"
}
]
}
Now my action user detail is giving response when i am invoking the code.
But when i am checking the output with my chatbot I am getting execution of cloud functions action took too long.
There is currently a 5 second limitation on processing time for a cloud function being called from a dialog node. If your process will need longer than this, you'll need to do it client side through your application layer.

Retrieve inline images from gmail api?

I'm retrieving messages from my Gmail using Gmail API. specifically, the email with Hangouts conversations using this url: https://www.googleapis.com/gmail/v1/users/me/messages?q=in:chats
When I enter in a message, I see this structure
{
"id": "1555561f7b8e1sdf56b",
"threadId": "155552511dfsd83ce98",
"labelIds": [
"CHAT"
],
"snippet": "df",
"historyId": "270812",
"internalDate": "1466016331704",
"payload": {
"partId": "",
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "From",
"value": "\"Oscar J. Irún\" <Oscarjiv91#gmail.com>"
}
],
"body": {
"size": 2,
"data": "ZGY="
}
},
"sizeEstimate": 100
}
as you can see, the body message is "df". Everything it's ok so far.
The problem comes when the Hangout message is an image. The snippet field is empty, and it doesnt show any attachment in the message. This is an example:
{
"id": "155558233274d78c91",
"threadId": "15fd5552511d83ce98",
"labelIds": [
"CHAT"
],
"snippet": "",
"historyId": "27sd0827",
"internalDate": "1466018445133",
"payload": {
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "From",
"value": "\"Oscar J. Irún\" <Oscarjiv91#gmail.com>"
}
],
"body": {
"size": 0,
"data": ""
}
},
"sizeEstimate": 100
}
I need to retrieve this inline images. Any help will be appreciated!
You can retrieve attachments by using Users.messages.attachments:get. Take note that this request requires authorization. All requests to the Gmail API must be authorized by an authenticated user. Gmail uses the OAuth 2.0 protocol for authenticating a Google account and authorizing access to user data.
HTTP request
GET https://www.googleapis.com/gmail/v1/users/userId/messages/messageId/attachments/id
public static void getAttachments(Gmail service, String userId, String messageId)
throws IOException {
Message message = service.users().messages().get(userId, messageId).execute();
List<MessagePart> parts = message.getPayload().getParts();
for (MessagePart part : parts) {
if (part.getFilename() != null && part.getFilename().length() > 0) {
String filename = part.getFilename();
String attId = part.getBody().getAttachmentId();
MessagePartBody attachPart = service.users().messages().attachment().
get(userId, messageId, attId).execute();
byte[] fileByteArray = Base64.decodeBase64(attachPart.getData());
FileOutputStream fileOutFile =
new FileOutputStream("directory_to_store_attachments" + filename);
fileOutFile.write(fileByteArray);
file OutFile.close();
}
}
}
JUST FYI for PHP the solution is something similar to this:
base64_decode(strtr($gmail->service->users_messages_attachments->get('me', $message->id, $arrPart['body']['attachmentId'])->data,'-_', '+/'));

Resources