How to change endpoint address in SOAP requests with ZEEP - python-3.x

I am using ZEEP to make SOAP requests and it is easy and works great.
The problem is that the endpoint URL (in the WSDL) isn't correct.
I can solve the problem by editing the WSDL directly, but this isn't scalable.
I reviewed the ZEEP documentation about creating service proxies but I don't understand it and am having errors. Here is the part of the WSDL containing the bad URL:
</binding>
<service name="DeviceConfigurationService">
<port name="DeviceConfigurationPort"
binding="xrx:DeviceConfigurationBinding">
<soap:address
location="http://localhost/webservices/office/device_configuration/1"/>
</port>
</service>
the location is what I need to change. I need to change from "localhost" to a LAN IP address. This value may change frequently so I don't want to have to edit the WSDL every time.
Does anyone know how to do this with Zeep?
Any help is greatly appreciated!

I know this question is old, but I just had this same issue as I was accessing a third-party SOAP API with a WSDL that pointed to the wrong endpoint (the third party told me the correct endpoint but hadn't updated their WSDL). The accepted answer did point me in the right direction, but I'd like to offer some additional details that weren't immediately apparent to a fairly novice developer such as myself.
Start by noticing that Zeep's documentation shows that the method zeep.Client.create_service() has two parameters.
binding_name – The QName of the binding
address – The address of the endpoint
Figuring out the binding_name
Option 1 - Read through the WSDL
The binding_name comes from the attribute binding in the WSDL. The issue is that the value of that attribute usually includes a reference to a name elsewhere in the WSDL that you have to manually resolve before using it to create a custom service.
In the case of the excerpt from the OP's WSDL (slightly formatted and ***emphasis added
***)...
<service name="DeviceConfigurationService">
<port name="DeviceConfigurationPort" ***binding="xrx:DeviceConfigurationBinding"***>
<soap:address location="http://localhost/webservices/office/device_configuration/1"/>
</port>
</service>
... the value of binding is "xrx:DeviceConfigurationBinding".
While this is the binding_name used by Zeep, you can't just copy and paste it into the parameter of create_service() because it is partially comprised of xrx - a name defined locally within the WSDL. Zeep automatically resolves the value of this kind of name when it originally parses the WSDL, so when you tell Zeep to point an existing binding to a different endpoint you have to resolve the binding name yourself so Zeep knows which binding you are talking about (that's why #jeffgabhart used {https://path-to-xrx-namespace} in his answer). In the end you should end up with complete binding_name of the format {NAMESPACE}BINDING.
Note that xrx isn't the only possible name. For me, the name was tns and for you it may be something different. Whatever it is, you should be able to find the definition of that name somewhere in the WSDL.
Option 2 - Use Zeep's WSDL parsing utility
Another option is the one suggested by #576i. Running the command python -mzeep WSDL_URL will spit out the information Zeep gathers from the given WSDL. One heading should say "Bindings" followed by a list (possibly of length 1) of binding_name's. From there you can copy the one you need to change the endpoint for.
Option 3 - Get it from the Zeep Client object
This one feels more like a hack, but list(zeep_client.wsdl.port_types) gives a list of all binding names that Zeep found in the WSDL used to create the zeep_client.
Figuring out the address
Lastly, for the sake of completeness, the address is simply the new endpoint you want to use instead of the one defined in the WSDL.
I hope this helps smooth out the learning curve for someone!

client = Client('http://localhost/webservices/office/device_configuration/1?wsdl')
service = client.create_service(
'{http://path-to-xrx-namespace}DeviceConfigurationBinding',
'http://127.0.0.1/webservices/office/device_configuration/1')
service.submit('something')

Related

How to test a rdfa parser?

I'm trying to find a way to check if my rdfa-parser (written in nodejs) is working.
So I have an rdfa-parser, which should print all triples, found in a file or url (with rdfa-syntax).
So far I know, that there are testsuits for RDFa-parsing (http://rdfa.info/test-suite/rdfa1.1/html5/manifest), but I'm not sure how to use them.
Is there a good webpage, where this is described? Or can anyone help me in another way?
There should be some information at the rdfa.info/tests site. Basically, you need a service that will accept a GET request, where the "uri" query parameter points to the input file. The service then parses the file, and returns some other form of RDF, typically N-Triples. More information on the Github page: https://github.com/rdfa/rdfa-website/blob/master/README.md

How to handle urls in load runner?

I have created/recorded a script in Vugen, however the the URL of the site has been changed recently. Is there any way just by replacing the url with a parameter works?
I have tried by replacing url with parameters, the new URL is
http://xsx.xxx.xsx.xxx/test99
Yhe parameters I have tried are below:
NewUrl: http://xsx.xxx.xsx.xxx/
Newhos: test99
I have replaced all in the script and when I run it I get the following error:
Error -27651: Attempted read from an unconnected socket (empty response, no HTTP headers received). URL="http://xsx.xxx.xsx.xxx/scripts/uiServer.dll"
What is the solution for this? Should i record again with the new URL ?
Thanks.
Hope I've understood what you're asking for, so here goes. If it's only the URL that has changed and not the content of the site which you might require later on in your script that this is fairly simple to do.
As you have created the new parameters ensure that they are getting the data from the same DAT file. I.e. newurl.dat which contains the following:
newurl,newhost
http://xsx.xxx.xsx.xxx/,test99
and assign the parameters to the correct column and have the newhost set to sameline as newurl. This way it’s easier to maintain I believe.
Now that the parameters have been created and properly assigned in your script you’ll need to change the url your trying to change from:
http://xsx.xxx.xsx.xxx/oldtest to {newurl}{newhost}
this needs to be done for all instances where the change has occurred.
Hope this helps with your problem you’re having.
Are you certain that the build level has not also changed at the same time as the host? If so then your new instance may be out of synch with the request model of the scripts built using an earlier build. Developers have a habit of including items below the scenes that do affect the site visually but change the structure of the requests. The error you are receiving is common when you attempt to continue a conversation on a dead connection resulting from a missed dynamic session component which may have been added in the last build.
When in doubt quickly record the second site and take a look at the differences in the requests, even to the point of using WinDiff (included in LoadRunner) for this purpose.

Adding a Reference to System.Web

I am trying to create some cookies as I cannot fetch the cookies and a normal way so I will run through the whole header and just create the cookie manually. However whenever I try to use Response.Cookies and HttpCookie I get an error:
The name Response does not exist in the current content
and
The type or namespace name 'HttpCookie' could not be found (are you missing a using directive or an assembly reference?).
I read around and understood I will need to reference
System.Web
So I am clicking on Project -> Add Reference -> .NET and select System.Web. Then I add using System.Web;.
And still I am unable to access them.
From what code are you trying to access the item?
There are essentially two steps that need to be taken to reference a class:
Add a reference to the class' assembly in the project.
Add a using directive to the class' namespace in the code file.
It sounds like you're performed the first step. What about the second? That's what this error means:
The type or namespace name 'HttpCookie' could not be found (are you missing a using directive or an assembly reference?).
To perform step 2 above, you actually have a couple of options:
Fully-qualify the class name. So, instead of using HttpCookie you would use System.Web.HttpCookie.
Add a using directive to the code file. At the top of the file (and this would need to be done for any file which uses classes in this namespace), you would add using System.Web. Then you could just reference HttpCookie directly.
Additionally, the first part of your question brings up a separate issue entirely:
The name Response does not exist in the current context
This again goes back to my question about where you're accessing this value. When you're writing code in, say, the code-behind for an ASPX page, you have access to the various bits of ASP.NET web contexts by default. These are provided by the base Page class. Things like Request and Response are readily available.
However, if you're trying to access these objects from outside of that context (such as from a custom class or another assembly), you'll need to reference that context manually. This can be done by using a factory on the System.Web.HttpContext class:
Request becomes System.Web.HttpContext.Current.Request
Response becomes System.Web.HttpContext.Current.Response
This is because Request and Response aren't actual classes. They're properties on the current web context which are of type HttpRequest and HttpResponse. Those properties are mapped for you when you're in the same context, but outside of that context you'd need to reference them fully as demonstrated above.
One thing to note is that it's not generally considered good practice to have dependencies on the web context outside of where it's already available. So if you're creating a custom class or another assembly then you might want to take a step back and think about the design.
If your custom classes depend on the existence of a current instance of HttpContext then that code can never be used outside of a fully-aware web application context. So the code is less re-usable. So, depending on what you need from that context, you can re-factor the code to not need the context itself but only to require that the necessary items from the context be provided.
This isn't necessary to get you past your current issue, but it's something to keep in mind going forward.

Can I make it customize display of my GET request on service stack?

When I make GET request on my service stack it is working fine.
Thanks to service stack, to make a developer work very easy.
On the page, I am having two queries. May be some one can help me. according to me it is always better to know for what you are working and how the internal thing works.
see the above image, when I send GET request on service stack, it displays me this kind of layout.
1>I want to know can I make it customize display. i.e. can I remove the sentence "SnapShot of ....." (the big header)
2>I want to know, why it takes space in header of table (the result table) for every capital character define in property.
i.e. in my project the name of property in class is -> instanceName, which is represented as "instance Name" in header .
Can anyone tell me what is the reason behind this?
The implementation of the HtmlFormat is in a single class at:
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/WebHost.Endpoints/Formats/HtmlFormat.cs
It allows some customization, e.g:
HtmlFormat.TitleFormat = "";
HtmlFormat.HtmlTitleFormat = "";
The default behavior like splitting the case of the header labels was specifically added to make it more readable. To change this you are going to have to download the source code, make changes to the class yourself and cut a new build. This is the line that does the split-camel-casing:
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/WebHost.EndPoints/Formats/HtmlFormat.cs#L289
You can read more about the JSON HTML Report Format used at:
https://github.com/ServiceStack/ServiceStack/wiki/HTML5ReportFormat

Suggest list in google maps search input

We need to create search input field like it is on _http://maps.google.com
The key functionality is suggest list with appropriate results. We
have not found this feature in API.
Analyzing maps.google.com we see that suggest list is received
from get request to this url
https://maps-api-ssl.google.com/maps/suggest?q=%D0%BC%D0%BE%D1%81&cp=...
There are many parameters, including data from search field. This get
request returns our suggest list.
Is there a possibility to use this url in our needs with our data. Or
how can we make it in some other way.
Similar to our needs: _http://cdn.michaelhart.me/mh/instant/maps/
check this out:
http://tech.cibul.net/geocode-with-google-maps-api-v3/
Theoretically you shouldn't use maps-api-ssl.google.com/maps/suggest as it might not be legal. I found this quote from google employee:
'Endpoints like this that are used by Google Maps but not documented as
part of the Maps API should be considered private interfaces.
Consequently use of those end points is a breach of the Terms of
Service. In addition any existing API credentials you may have are
completely unrelated to these end points because they are not served
by API infrastructure'

Resources