I have usual happstack case in which we have ServerPart Response MonadPlus in list and. Then msum Chooses the one that does not fail and response generated and returned.
I have opinion that some actions - like cheking cookies - preparing connection context (authorising authenticated user, implementing counts, etc...) should be done in any incoming request - without any path info even defined yet.
Maybe there's some buzzy word I still not knowing yet, specially for such kinds of staff. Could someone advice please?
If you want to take certain actions for every request, you can add them in the do statement before your routing code. For example:
module Main where
import Happstack.Server
main = simpleHTTP nullConf $ do incCounter
mUser <- checkUserAuth
resp <- msum [ part1
, part2
, part3 mUser
]
logResponse resp
return resp
That will always run incCounter and checkUserAuth. Then it will try the various routes.
If one of the routes matches, it will then call logResponse, and then finally return the resp which will be sent to the user.
Note that while incCounter and checkUserAuth will always be run, logResponse will only be run if one of the parts matches. If none do, then I am pretty sure the code will escape and return a 404. If you wanted logResponse to always run, then you could add a handler to the msum that always matches. For example:
resp <- msum [ part1
, part2
, part3 mUser
, notFound $ toResponse "Sorry, page not found."
]
That will almost always run. If one of the parts matches, but explicitly calls 'escape', then I am pretty sure logResponse still won't be run. There are ways of dealing with that as well.
But, the short answer is, if you want something to happen even time, just put it before your msum code.
Related
I'm fairly new to Haskell, though not to programming, and I've been using the req library to perform HTTPS requests.
In order to retain some generality, there will be two types of request - one to create a document (via HTTP POST) and another to update a document (via HTTP PATCH, using a non-empty monoid in the updateMask parameter).
I can infer the HTTP verb from whether updateMask == mempty, but this won't compile because POST and PATCH are different data declarations (although both are valid as the first parameter of req because they are instances of HttpMethod.
getSaveEventRequestResponse :: Text -> Option Https -> Document -> IO IgnoreResponse
getSaveEventRequestResponse authToken updateMask document =
runReq defaultHttpConfig $
req
(if updateMask == mempty
then POST
else PATCH)
(https "test.example.com" /: "api" /: "projects" /: "myproject")
(ReqBodyJson document)
ignoreResponse $
oAuth2Bearer (encodeUtf8 authToken) <> updateMask
If I swap out the if conditional for either one of POST or PATCH the code compiles without error.
Is there a way to make the compiler allow this conditional response or do I have to duplicate this function, one using the POST variant and another using the PATCH?
Edit for the benefit of anyone who comes to this and tries to use the same code:
The condition I used (updateMask == mempty) is not actually valid here, but that's not relevant to the question. The question stands if this condition is replaced by True or False.
Edit 2 regarding the linked question. While I now, having got the answer, see how closely linked it is, it relies on having already considered partial application. While the principle is the same, the introduction of partial application makes it difficult for a beginner with Haskell to apply the answer there to this context.
A possible solution is to use
(if updateMask == mempty then req POST else req PATCH) other args here
This is because
req :: (MonadHttp m, HttpMethod method, HttpBody body,
HttpResponse response,
HttpBodyAllowed (AllowsBody method) (ProvidesBody body))
=> method
-> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Now, AllowsBody POST and AllowsBody PATCH are equal, since both are defined as 'CanHaveBody. Therefore, both req POST and req PATCH can share a common type:
req POST, req PATCH
:: (MonadHttp m, HttpBody body,
HttpResponse response,
HttpBodyAllowed 'CanHaveBody (ProvidesBody body))
=> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Having the same type, they can be used in the two branches of the same if then else.
I want to resend the initialized cookies from the first call in the second call, so that the session is not changing. This is not working.
Why? And how can I solve it. Sorry, new in python
https_url = "www.google.com"
r = requests.get(https_url)
print(r.cookies.get_dict())
#cookie = {id: abc}
response = requests.get(https_url, cookies=response.cookies.get_dict())
print(response.cookies.get_dict())
#cookie = {id: def}
You aren't necessarily doing it wrong with the way you're passing the cookies from the last response to the next request, except that:
"www.google.com" is not a valid URL.
Even you had used http://www.google.com as the URL, the cookies returned by Google in such a GET request aren't meant to be session cookies and won't be persistent across requests.
You used the variable r to receive the returning value from the first requests.get, and yet you used response.cookies when you make the second requests.get. A possible typo?
If all of the above are due to your trying to mock up your real code, you should really consider using requests.Session to avoid micro-managing session cookies.
Please read requests.Session's documentation for more details.
import requests
with requests.Session() as s:
r = s.get(https_url)
# cookies from the first s.get are automatically passed on to the second s.get
r = s.get(https_url)
...
Haskell beginner here, trying to wrap a HTTP REST API in a safe way and with automatic Aeson decoding of return values. I started with a Haskell function for every API call. It was a bit boilerplateish, but ok.
Looking to improve things I wanted to turn each API call into a data type of its own. For example for logging in, I would model that as Login type that specifies the method, Credentials type for method parameters and LoginReponse for the result of the API call. Parameters and response types of course have corresponding FromJSON and ToJSON instances.
For two API calls it looks something like this (using GADTs):
data Void = Void
data Credentials = Credentials {...}
data LoginResponse = LoginResponse {...}
data LogoutResponse = LogoutResponse {...}
data Command a where
Login :: Credentials -> Command LoginResponse
Logout :: Void -> Command LogoutResponse
execute :: FromJSON a => Command a -> IO a
execute cmd = do
manager <- newManager tlsManagerSettings
let request = buildHttpRequest cmd
result <- httpLbs request manager
let body = responseBody result
let parsed = fromJust $ decode body
return parsed
This works great for my use case - I can introspect Commands before executing them, I can't construct invalid API calls and Aeson knows how to decode the return values!
Only problem with this approach is that I have to keep all of my Commands in a single file under single data declaration.
I'd like to move method definitions (in my example Login and Logout) to separate modules, but to keep the execute function similar, and of course keep the type safety and Aeson decoding.
I've tried to make something using type classes, but got nowhere.
Any tips how to do that are welcome!
Since the only thing you do differently in execute for different commands is call buildHttpRequest, I propose the following alternate data type:
type Command a = Tagged a HttpRequest
(I don't know the return type of buildHttpRequest, so I made something up and assumed it returned an HttpRequest. Hopefully the idea will be clear enough even though I'm sure I got this part wrong.) The Tagged type comes from tagged, and lets you attach a type to a value; it is the urphantom type. In our case, we will use the attached type to decide how to decode JSON in the execute step.
The type of execute needs a slight modification to demand that the attached type can be decoded:
execute :: FromJSON a => Command a -> IO a
However, its implementation remains basically unchanged; simply replace buildHttpRequest with untag. These commands are not conveniently introspectable, but you will be able to split things up along module boundaries; e.g.
module FancyApp.Login (Credentials(..), LoginResponse(..), login) where
import FancyApp.Types
data Credentials = Credentials
data LoginResponse = LoginResponse
login :: Credentials -> Command LoginResponse
login = {- the old implementation of buildHttpRequest for Login -}
module FancyApp.Logout (LogoutResponse(..), logout) where
import FancyApp.Types
data LogoutResponse = LogoutResponse
logout :: Command LogoutResponse
logout = {- the old implementation of buildHttpRequest for Logout -}
I have a SoapUI Mock Service with multiple responses. I want to define a custom sequence for my responses and I do not necessarily use all of the responses in this particular test.
I have actually managed to get this to work in the past, but I think something changed in a newer version of the product and the feature stopped working. That was with a SOAP web service. Now I am mocking a RESTful web service and I have the same requirement to help me do my tests.
The SEQUENCE dispatch option is not what I want, because it will return all of the defined responses in the order in which they were created. The SCRIPT option is what I used previously but now all I can achieve with this is define one response to be generated. For this test I have no interest in examining some content of the request to decide which response to send back.
For example, if I have 8 responses defined, I just want to be able to specify that the following responses are returned:-
Response #2, then Response #3, then Response #4, then finally Response #7; so that Responses #1, #5, #6 and #8 are not used.
My question is posed in detail in the SmartBear forum here:-
simple scripting in a Mock Service - no longer works
I try as you post in the SOAPUI forum using consecutive returns statements with the response order an it doesn't work.
Instead of your groovy code as a DISPATCH script I purpose to use the follow groovy code as workaround, which consist in a use of a list to keep your responses in the desired order and keeping this list in the context an updating it each time using the following code:
// get the list from the context
def myRespList = context.myRespList
// if list is null or empty reinitalize it
if(!myRespList || !myRespList?.size){
// list in the desired output order using the response names that your
// create in your mockservice
myRespList = ["Response 2","Response 3","Response 4","Response 7"]
}
// take the first element from the list
def resp = myRespList.take(1)
// update the context with the list without this element
context.myRespList = myRespList.drop(1)
// return the response
log.info "-->"+resp
return resp
This code works as you expect, since context is keeping the list and each time this script returns the next response and when the list is empty it repopulate it an restart the loop again in the same order.
As an illustration when I use this mockService I get the follow script log:
EDIT
If as OP you've problems with your SOAPUI version because the returned string is between square brackets as ie: [Response 1], change the way that element is taken from the array using:
// take the first element from the list
def resp = myRespList.take(1)[0]
instead of:
// take the first element from the list
def resp = myRespList.take(1)
Note the [0].
With this change the return string will be Response 1 instead of [Response 1].
In this case the script will be:
// get the list from the context
def myRespList = context.myRespList
// if list is null or empty reinitalize it
if(!myRespList || !myRespList?.size){
// list in the desired output order using the response names that your
// create in your mockservice
myRespList = ["Response 2","Response 3","Response 4","Response 7"]
}
// take the first element from the list
def resp = myRespList.take(1)[0]
// update the context with the list without this element
context.myRespList = myRespList.drop(1)
// return the response
log.info "-->"+resp
return resp
Hope this helps,
Here is how I am sending a get request:
import Network.HTTP.Conduit
import Control.Applicative ((<$>))
import Network.HTTP.Types
request <- parseUrl $ "someUrl"
res <- withManager $ httpLbs request
putStrLn $ show $ responseCookieJar res
Instead of printing responseCookieJar I want to get a value from it. This http://hackage.haskell.org/package/http-conduit-2.1.2/docs/Network-HTTP-Conduit.html#t:CookieJar implies that it's not possible. So I figure I have to parse (by regexp) it as a string. But there must a standard way like getting a value by its key.
Isn't there?
You can call destroyCookieJar to break it into the individual Cookies, and then search that list.
You can use destroyCookieJar to turn it into a list of Cookies, which you can then inspect via various field accessors.
The two most useful for keys are probably cookie_name and cookie_path. So you might do something like
filter (\c -> cookie_name c == pack "foo") . destroyCookieJar
(using pack from Data.Bytestring.Char8)
Or if there are a lot of cookies and you want to do multiple queries, you may want to build something like a Map from name to cookie first.