How to get the request.post string that im sending? - python-requests

hope you can help me on with this issue that i've been trying to solve within the last 2 weeks and i finallly gave up on reading the requests documentation. I happen to think that what i need is very simple, but somehow i have not been able to solve it.
I have the following code:
import requests
a=requests.post(url, params)
How do i know the http string that im sending?
What i need to do is to get the string so I can make a signature with a secret key, add it to the parameters and make the post with the signature as a new parameter. So, i know the methods and the paremeters in order to post, but I dont know that the request.post makes to those objects. It would be something like this:
what_i_send=request.post(url, params)
signature=signature_method(what_i_send)
params["signature"]=signature
final_request=request.post(url,params)
thanks a lot!

You can use this answer's neat function and print something like this:
def print_request(req):
print('{}\r\n{}\r\n\r\n{}'.format(
req.method + ' ' + req.url,
'\r\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
req.body,
))
a = requests.post(url, params)
print_request(a.request)

Related

?How can I mock a manual redirect using python requests_mock?

I have a function where I'm doing a http request to a site that should do an automatic redirect but I'm doing this manually using allow_redirects=False. I have the function itself working something like this:
def make_redirect_request(self):
url = https://some.url.com
response = requests.get(url, headers={"header": "some header"}, status_code=302, allow_redirects=False)
redirected_response = requests.get(response.next.url, headers={"header": "some other header"}, status_code=200)
self.publish(redirected_response.content) # some publishing function for publishing content on page
This works as I would like it to, but I'm struggling to make a unittest that checks this correctly. I have tried something like this:
#unittest.mock.patch("publish")
#unittest.mock.patch("url", "mock_url")
def test_redirect_url(self, mock_publish):
with patch('requests.get', self.session.get) #predefined session with parameters I don't use in this function
mock_response = b"some byte response"
next_url = "mock_redirected_url"
self.adapter.register_uri("GET", "mock_url", status_code=302, allow_redirects=False, next=next_url)
#I want the next parameter to give me the url that I'm being redirected to, which is given by response.next.url in the actual function, but this doesn't work here and it also doesn't understand the allow_redirects parameter
self.adapter.register_uri("GET", next_url, content=mock_response, status_code=200)
self.session.mount("mock", self.adapter)
self.make_redirect_request()
mock_publish.assert_called_once()
I'm not sure how to get the first request to pass the url given by response.next.url to the second request, as the adapter doesn't seem to take the next and allows_redirects arguments.

How to pass custom query parameters in Retrofit?

Trying to implement a custom solution for interacting with TestRail API(http://docs.gurock.com/testrail-api2/accessing), I'm kind of stuck in the following situation:
Api calls are made like this: /index.php?/api/v2/get_case/1, meaning that after anything "?" is a query string param. Is there a way to parametrize this with Retrofit?
If I do something like this:
#GET("index.php?/api/v2/get_case/{id}")
Call<TestCase> getTestCase(#Query("id") int id);
I get this exception:
java.lang.IllegalArgumentException: URL query string "/api/v2/get_case/{id}" must not have replace block. For dynamic query parameters use #Query.
Got that...but how can I proceed further using Retrofit?
Solved this through interceptor
Request currentRequest = chain.request();
String finalURL = currentRequest.url().toString().replace("index.php/", "index.php?/");
Request.Builder request = currentRequest.newBuilder()
.addHeader("Authorization", authToken)
.addHeader("Content-Type", ContentType.JSON.toString())
.url(finalURL);

Using Campaign Monitor's API

I am looking for a way to use Campaign Monitor's API in my ASP.NET/VB Web application.
I have not used any API before, thus reading their documentation is very difficult to understand.
If anyone has used it and is able to provide some instructions I would appreciate it; or if someone has some general usage instructions (if applied on any APi), be my guest! :)
I know this is not the typical "I have a problem and this is my problem and here's my effort so far" but any help would be much appreciated.
You can also use the Campaign Monitor API client library which is available on Nuget:
AuthenticationDetails auth = new ApiKeyAuthenticationDetails(apiKey);
var fields = new List<SubscriberCustomField>() {
new SubscriberCustomField() { Key = "MyCustomField", Value = myVal }
};
var subscriber = new Subscriber(auth, listId);
subscriber.Add(email, fullName, fields, false);
I use campaign monitor for populating subscriber lists.
There are two methods to post your subscribers to lists. I'm going to stick to the simplest one. Let's round up somethings you need first.
You'll need an API key (which I am sure you have).
You'll need to create a subscribers list and after you create this
list you'll need the list ID. To get the ID (which is wierd).You'll
need to click into your subscriber list. This look for this towards
the top. Single opt-in list (change name/type) Note: You are not
going to change the name or edit anything but you have to click in
here to get the ID. On the third section you will see this: API
Subscriber List ID. If you're using the API, you'll need this ID to
access this list. 000x0000xx0x0xx00x00xx (just an example.)
You'll need a form to capture Name and Email. You'll need your listid which
you got in the previous point.
Then you'll need to code a communication object.
If you are doing a straight forward call you'll need the name, email, and listid.
ListID ="000x0000xx0x0xx00x00xx";
Email ="JoeM#somethingemail.com";
Name = "Joe Middle";
APIKey = yourAPIKey;
APIURL = "http://api.createsend.com/";
ApiCall = variables.APIURL;
ApiCall &= "api/api.asmx/Subscriber.Add?ApiKey=" & variables.APIKey;
ApiCall &= "&ListID=" & URLEncodedFormat(arguments.ListID);
ApiCall &= "&Email=" & URLEncodedFormat(arguments.Email);
ApiCall &= "&Name=" & URLEncodedFormat(arguments.Name);
Once you have your url build you use whatever method .net uses to post http.
Then you'll want to code for success or fail and do something with that info. post to http and call the result. apiResult.
apiResult = xmlParse(apiResult.fileContent);
try {intCount = ArrayLen(apiResult.Result.XMLChildren);}
catch(Any e){intCount = 0;}
if (intCount gt 0){apiResult = apiResult.Result.xmlChildren;}
// Error handling
if ( apiResult[1].xmlName eq "Code" and apiResult[2].xmlName eq "Message" ){
returnStruct['blnSuccess'] = 0;
returnStruct['errorCode'] = apiResult[1].xmlText;
returnStruct['errorMessage'] = apiResult[2].xmlText;
}
// Success
else {
// Return str
returnStruct['blnSuccess'] = 1;
returnStruct['returnString'] = apiResult.Result.xmlText;
}
The code above was adapted from coldfusion and I didn't build it but it is cfscript which is not CFML and you can kind of interpret what is happening.
If you adapt this to .NET then all you are missing is your HTTP call stuff method.
To check log into Campaign Monitor and click on your list. You should see additions showing up, if not it is either you API key (not usually the case), your listID (could be the case), your code (most likely culprit).
This was hammered out in a hurry so apologies if the flow is weird.
Good luck!

Passing a Dynamics enumeration in .NET to BusinessConnector call

I am trying to understand how to access dynamics enums to be able to pass these into BusinessConnector calls. For instance, you can call the following:
pobj = (AxaptaObject)ax.CreateAxaptaObject("PurchFormLetter", [ENUM]);
But, I have no idea how to pass in the correct value of [ENUM]. In X++, the enum is DocumentStatus::PurchaseOrder, but I don't seem to be able to access this from anywhere. Can anyone possibly assist in finding out how to pass in the value?
Passing in the numeric value of the enum does not work unfortunately (in this case the value I need is 2). It returns an XPPException of 'Function PurchQuantity::construct has been used incorrectly.'
AxaptaObject pobj = (AxaptaObject)ax.CreateAxaptaObject("PurchFormLetter", 2);
If anyone could please be of assistance that would be greatly appreciated.
Regards,
Steve
Others have the same problem. And they have found a solution by creating an enum proxy.
Ok, this is for everyone else who hits this problem:
If you want to access the enum values from .NET purely without using X++:
string enumName = "DocumentStatus", enumValue = "PurchaseOrder";
object enumObj = (int)axa.CallStaticClassMethod("Global", "enumName2Id", enumName);
AxaptaObject dict = (AxaptaObject)axa.CreateAxaptaObject("DictEnum", enumObj);
object res = dict.Call("symbol2Value", enumValue);
The above can be made into a function very easily if reuse is required.
Still, doing the following won't work:
AxaptaObject pur = (AxaptaObject)axa.CreateAxaptaObject("PurchFormLetter", res);
However, you can do it this way:
AxaptaObject pur = (AxaptaObject)axa.CallStaticClassMethod("PurchFormLetter", "construct", res);
This will allow you to pass in the integer value of the enum (in this case, the variable 'res'). You can then use this object to post the purchase order.
Hope this helps someone.
Regards,
Steve

Modify request querystring parameters to build a new link without resorting to string manipulation

I want to dynamically populate a link with the URI of the current request, but set one specific query string parameter. All other querystring paramaters (if there are any) should be left untouched. And I don't know in advance what they might be.
Eg, imagine I want to build a link back to the current page, but with the querystring parameter "valueOfInterest" always set to be "wibble" (I'm doing this from the code-behind of an aspx page, .Net 3.5 in C# FWIW).
Eg, a request for either of these two:
/somepage.aspx
/somepage.aspx?valueOfInterest=sausages
would become:
/somepage.aspx?valueOfInterest=wibble
And most importantly (perhaps) a request for:
/somepage.aspx?boring=something
/somepage.aspx?boring=something&valueOfInterest=sausages
would preserve the boring params to become:
/somepage.aspx?boring=something&valueOfInterest=wibble
Caveats: I'd like to avoid string manipulation if there's something more elegant in asp.net that is more robust. However if there isn't something more elegant, so be it.
I've done (a little) homework:
I found a blog post which suggested copying the request into a local HttpRequest object, but that still has a read-only collection for the querystring params. I've also had a look at using a URI object, but that doesn't seem to have a querystring
This will work as long as [1] you have a valid URL to begin with (which seems reasonable) [2] you make sure that your new value ('sausages') is properly escaped. There's no parsing, the only string manipulation is to concatenate the parameters.
Edit
Here's the C#:
UriBuilder u = new UriBuilder(Request.Url);
NameValueCollection nv = new NameValueCollection(Request.QueryString);
/* A NameValueColllection automatically makes room if this is a new
name. You don't have to check for NULL.
*/
nv["valueOfInterest"] = "sausages";
/* Appending to u.Query doesn't quite work, it
overloaded to add an extra '?' each time. Have to
use StringBuilder instead.
*/
StringBuilder newQuery = new StringBuilder();
foreach (string k in nv.Keys)
newQuery.AppendFormat("&{0}={1}", k, nv[k]);
u.Query = newQuery.ToString();
Response.Redirect(u.Uri.ToString());
UriBuilder u = new UriBuilder(Request.Url);
NameValueCollection nv = new NameValueCollection(Request.QueryString);
nv["valueofinterest"] = "wibble";
string newQuery = "";
foreach (string k in nv.Keys)
{
newQuery += k + "=" + nv[k] + "&";
}
u.Query = newQuery.Substring(0,newQuery.Length-1);
Response.Redirect(u.ToString());
that should do it
If you can't find something that exists to do it, then build a bullet-proof function to do it that is thoroughly tested and can be relied upon. If this uses string manipulation, but is efficient and fully tested, then in reality it will be little different to what you may find any way.

Resources