How to create a new watson assistant session on exisiting session expiration in Flask? - ibm-watson

I am using watson assistant with flask framework. Once the session expires i get the following error
ApiException(response.status_code, error_message, http_response=response)
ibm_cloud_sdk_core.api_exception.ApiException: Error: NotFound: session id ba62bf14-87e-4c7b071b591e for agent instance 0e5c653c-9-b4e0-5a597c3e541e, Code: 404 , X-global-transaction-id: ffea409d54977b49
127.0.0.1 - - [03/Jul/2019 11:27:47] "GET / HTTP/1.1" 200
Refreshing the page does not create a new session
How to create a new session on this exception, so that I need not restart the local server ?

You mention a 5 minute session timeout.
Watson Plus trial has this set for just testing, and is not intended to be production level. It cannot be changed.
Standard version and lite can use session but both were originally stateless. You should use the V1 API for these. You will have to manage the state, but you will no longer have a time out.
If you are using the paid version of Watson Plus, or premium you can change the time out within the assistant settings.

You need to provide code, as any response will be blind and based on guesswork on what errors you have made, and there are many. But based on the fact that you failed to provide code, and still raised the question expecting someone to tell you what you did wrong then let's go with a rookie error.
I think you are creating the session as a global in your flask app, and maybe saving it it the app object. You probably have a route for the dialog, which makes use of the session. The code in this route, needs to catch the error, or test if the session is still valid, and recreate it. If you are catching the error, and trying to recreate the session, then you may have fallen foul of Python's global variable restrictions. Essentially if in a function you have a variable as the right side of an assignment, then its scope will be limited to the function.
Refreshing the web page, will not force the flask app to re-create the session. As you probably have that logic outside of any routes.

Related

Not able to create events using Microsoft Graph SDK

I am trying to create an Event using Microsoft Graph SDK, as following the document #
https://learn.microsoft.com/en-us/graph/api/user-post-events?view=graph-rest-beta&tabs=csharp
1.Created "authProvider"
2.Created GraphClient with above AuthProvider
3.Creating Event using
The event is not creating also no exception/error is throwing, Could any one help me here?
This is happening because this call is being made with same transactionId frequently. It avoids unnecessary retries on the server.
It is an optional parameter , just comment out this property and try again. It should work.
Note : This identifier specified by a client app for the server , to avoid redundant POST operations in case of client retries to create the same event and also useful when low network connectivity causes the client to time out before receiving a response from the server for the client's prior create-event request.
More info is required here, as the reply from Allen Wu stated. without any details I would focus my efforts on the authprovider piece and azure app registration piece. as the rest of the example is just sending a post request to graph api.
but what is recommended really depends on what type of application you are trying to build. eg. is it a service daemon, a web app, mobile app, desktop app, single page app, etc.

Is catch-all handler pointing to "auto" a bad idea?

My instance has little to no traffic but I have a min-idle instance set to 1. What I notice is that whenever there is a random url (via some bot) that doesn't exist is accessed, it is considered a dynamic request since my catch all handler is auto. This is fine, except I see these 404 errors (404 because there are no http handlers associated with these url patterns even though the yaml defines a catch all pattern) resulting in instance restarts. Why should the instance restart if it runs into 404 errors?
I have all my dynamic handlers follow "/api" pattern and then a few that don't. So, I can explicitly list all valid patterns and map them to the auto handler. Would that then consider these random links as static but not present and throw 404 error (which I am fine with)? I want to make sure the instance doesn't keep running just because of some rouge requests.
I just did a local experiment (I don't presently have any quickly deployable play app) and it looks like your quite interesting idea could work.
I replaced the .* pattern previously catching all stragglers and routing them to my default service script (I'm using the python runtime) with specific patterns, then added this handler after all others:
- url: /(.*)$
static_files: images/\1
upload: images/.*
My images directory is real, holding static images (but for which I already have another handler with a more specific pattern).
With this in place I made a request to /crap and got, as expected (there is no images/crap file):
INFO 2019-11-08 03:06:02,463 module.py:861] default: "GET /crap
HTTP/1.1" 404 -
I added logging calls in my script handler's get() and dispatch() calls to confirm they're not actually getting invoked (the development server request logging casts a bit of doubt).
I also checked on an already deployed GAE app that requesting an image that matches a static handler pattern but which doesn't actually exist gets the 404 answer without causing a service's instance to be started (no instance was running at the time), i.e. it comes directly from the GAE's static content CDN.
So I think it's well worth a try with the go runtime, this could save some significant instance time for an app without a lot of activity faced with random bot traffic.
As for the instance restarts, I suspect what you see is just a symptom of your min-idle instance set to 1. Unlike a dynamic instance the idle (aka resident) instance is not normally meant to handle traffic, it's just ready to do it if/when needed. Only when there is no dynamic instance running (and able to handle incoming traffic efficiently) and a new request comes in that request is immediately routed to the idle instance. At that moment:
the idle instance becomes a dynamic one and will continue to serve traffic until it shuts due to inactivity or dies
a fresh idle instance is started to meet the min-idle configuration, it will remain idle until another similar event occurs
Note: your idea will help with the instance hours portion used by the dynamic instances, but not with the idle instance portion.
According to the documentation which quotes the following:
"When an instance responds to the request /_ah/startwith an HTTP status code of 200–299 or 404, it is considered to have started correctly and that it can handle additional requests. Otherwise, App Engine cancels the instance. Instances with manual scale adjustment restart immediately, while instances with basic scale adjustment restart only when necessary to deliver traffic."
You can find more detail about how instances are managed for Standard App Engine environment for Go 1.12 on the link: https://cloud.google.com/appengine/docs/standard/go112/how-instances-are-managed
As well, I recommend you to read the document "How instances are managed", on which quotes the following:
"Secondary routing
If a request matches the part [YOUR_PROJECT_ID].appspot.comof the host name, but includes the name of a service, version, or instance that does not exist, the service is routed default. Secondary routing does not apply to custom domains; requests sent to these domains will show an HTTP status code 404if the hostname is not valid."
https://cloud.google.com/appengine/docs/standard/go112/how-instances-are-managed

AppEngine authentication through Node.js

I'm trying to write a VSCode extension where users could log into Google AppEngine with a google account, and I need to get their SACSID cookie to make appengine requests.
So I'm opening a browser window at
https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttp://localhost:3000/
(generated by google.appengine.api.users.create_login_url)
The user logs in and is redirected to my local webserver at
localhost:3000/_ah/conflogin/?state={state}
Now I try to forward the request to my AppEngine app (since it knows how to decode the state parameter), so I do a request to
https://my-app.appspot.com/_ah/conflogin/?state={state}
basically just replacing localhost with the actual app.
but it doesn't work, presumably because the domain is different. I assume this is on purpose, for security.
Is there any way I can make this work ?
Not ideal, but the only solution I've found is to have an endpoint on my GAE instance that does the redirection. Then I can set that as the continue url, when I'm starting the authentication process
https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttps://my-app.appspot.com/redirect?to=http://localhost:3000
I think you should center the attention on the protocols you are using, since it’s known that the cookie name is based on the http protocol (HTTP : ACSID, HTTPS:SACSID), and that’s the security perspective till this point for me.
Having the error you are facing now would be helpful to understand the problem better. Also, how are you performing the call to the API and the code you are using would be helpful too.

How to log per request / context - Golang

I'm trying to migrate an a web app from Google Appengine to a dedicated server and I've got stuck to the logging issue. Basically I would like to organise the logs per request/context(like on GAE) so that I can easily review the errors/trace on each request. The most advanced logging library I could find is the glog package but still I can't figure it out how to log per request/context.
Each request gives you a http.Request-object to work with.
If you're using sessions, then you'll have a sessions.Session-object to work with.
You will want to use those objects to help log per request/context, as they identify the request / session.

Laravel: Gracefully Fallback if Session Database is Not Avaiable

Is there a middware, package, or general approach for having Laravel gracefully fallback to a session-less state if the session storage engine isn't available?
That is, let's say you have you a system using the database session engine. If that database goes down, Laravel's going to throw an exception whenever it can't connect to the database. I'd like a way to, instead, have Laravel not throw an exception, and just continue on without a working session engine.
(I realize this will mean careful coding on the application level to never assume sessions are available, but a pre thank you for all the warnings)
Use Case to Correct For:
Session storage system goes down temporarily (maintenance window, unexpected outage, etc).
Logged in user hits a page, sees Laravel error page because session engine can't connect
User is sad
I'd rather the user see some sort of normal web-page instead of a generic error message, even if that means we can't include stateful session data on the page.
That depends, Laravel does not persistently require a session engine to work, only on pages that actually use it. So that means that a fallback would basically not help - in fact an exception is the best thing Laravel can actually do to help you here.
Why? Because an exception can be cought and, if that is what you want to do (even though it makes little to no sense), be ignored.
Maybe I'm understanding you wrong, what exactly do you want to fall back to?
For me it's really hard to imagine how could it work and what you need it for. For example when you need user to be logged to access some page what should happen if session db or whole db is down? For me the only solution is show the user info that something gone wrong because it will be hard to pretend that website is working if it's not. So application throw exception, you catch it and display error page for user (and send site admin e-mail or sms)
If you would try to pretend you probably make your users angry because they would try to log in and they wouldn't be logged in without any info, so they would try 2nd time, 3rd time and finally they would think that your site is broken and would never come back again. In my opinion it's better to tell them something is wrong and "hey, come back here in about 2 hours"

Resources