I am trying to send a request to an api using suds client.
The request is formed like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v20="https://API">
<soapenv:Header>
<v20:apiHeader>
<v20:username>username</v20:username>
<v20:password>password</v20:password>
<!--Optional:-->
<v20:name>?</v20:name>
</v20:apiHeader>
</soapenv:Header>
<soapenv:Body>
<v20:getLoginDetails/>
</soapenv:Body>
</soapenv:Envelope>
I am sending the request for this like:
client = Client('https://wsdl', faults=False)
client.set_options(headers={'username': username 'authToken': auth_token, 'name': ''})
client.service.getLoginDetails()
the error I am receiving is:
(<HTTPStatus.INTERNAL_SERVER_ERROR: 500>, (Fault){
faultcode = "soap:Server"
faultstring = "apiHeader should not be null"
detail = ""
})
Is this how I should be sending the request? It is definitely something to do with the apiHeader I think; not sure what though, I get the same error using this:
username = Element('username').setText(name)
password= Element('password').setText(pass)
header_list = [username, pass]
self.client.set_options(soapheaders=header_list)
return self.client.service.getLoginDetails()
#Code for your server:
from spyne import Application, rpc, ServiceBase, Unicode
from spyne.model.complex import ComplexModel
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
import json
class RequestHeader(ComplexModel):
user_name = Unicode
user_pass = Unicode
class ServiceTest(ServiceBase):
__in_header__ = RequestHeader
#rpc(Unicode, _returns=Unicode)
def getLoginDetails(ctx, request):
values = json.loads(request)
values['user_name'] = ctx.in_header.user_name
values['user_pass'] = ctx.in_header.user_pass
return json.dumps(values)
application = WsgiApplication(Application([ServiceTest],
tns='yourcompany.request',
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11()
))
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 8000, application)
server.serve_forever()
#Code for your client:
import json
from suds.client import Client
#Prepare the request in a JSON format
request = json.dumps({})
#Create a client for the API and make the request
api_client = Client('http://localhost:8000/?wsdl')
header = api_client.factory.create("RequestHeader")
header.user_name = 'my_user_name'
header.user_pass = 'my_user_pass'
api_client.set_options(soapheaders=header)
response = api_client.service.getLoginDetails(request)
print(response)
#it would print:
#{"user_name": "my_user_name", "user_pass": "my_user_pass"}
I've made this work by using something similar to this:
from suds.sax.element import Element
from suds.sax.attribute import Attribute
code = Element('serviceCode').setText('PABB4BEIJING')
pwd = Element('servicePwd').setText('QWERTPABB')
reqsoapheader = Element('ReqSOAPHeader').insert(code)
reqsoap_attribute = Attribute('xmlns', "http://schemas.acme.eu/")
reqsoapheader.append(reqsoap_attribute)
client.set_options(soapheaders=reqsoapheader)
If you wish to add several elements to the SOAP header:
userName = Element('UserName').setText(config['fco.user'])
password = Element('Password').setText(config['fco.pwd'])
fdxns = Attribute('xmlns', "http://fdx.co.il/Authentication")
for field in userName, password:
field.append(fdxns)
soapheaders = [userName, password]
client.set_options(soapheaders=tuple(soapheaders))
This is working for me with Python 2.7, suds 0.4.
Related
Full disclosure: I am very new to coding and I really don't know what I'm doing. Currently trying to send multiple transactional emails using SendinBlue SMTP API based on the one I pick. I have already made the templates on SendinBlue, but how do I call a specific template?
My code
from __future__ import print_function
import sib_api_v3_sdk
import smtplib
from sib_api_v3_sdk.rest import ApiException
from pprint import pprint
from email.mime.text import MIMEText
from flask import request, render_template
from sql_helper import *
# Configuration of API key authorization:
api_config = sib_api_v3_sdk.Configuration()
api_config.api_key['api-key'] = 'api_key'
#If Partnership Account:
#api_config = sib_api_v3_sdk.Configuration()
#api_config.api_key['partner-key'] = 'API_Key'
api_instance = sib_api_v3_sdk.TransactionalEmailsApi(sib_api_v3_sdk.ApiClient(api_config))
subject = "My Subject"
html_content = "<html><body><h1>This is my first transactional email </h1></body></html>"
sender = {"name":"company name","email":"admin#company.com"}
to = [{"email":"example#example.com","name":"Jane Doe"}]
# cc = [{"email":"example2#example2.com","name":"Janice Doe"}]
# bcc = [{"name":"John Doe","email":"example#example.com"}]
reply_to = {"email":"admin#company.com","name":"John Doe"}
headers = {"Some-Custom-Name":"unique-id-1234"}
params = {"parameter":"My param value","subject":"New Subject"}
send_smtp_email = sib_api_v3_sdk.SendSmtpEmail(to=to, reply_to=reply_to, headers=headers, html_content=html_content, sender=sender, subject=subject)
def send_email(template, recipient, custom_message = None):
if template == "approve":
template_id = 1
elif template == "deny":
template_id = 2
elif template == "skip":
template_id = 3
try:
#send transactional email
api_response = api_instance.send_transac_email(send_smtp_email)
pprint(api_response)
except ApiException as e:
print("Exception when calling SMTPApi -> send_transac_email: %s\n" % e)
Any help would be appreciated.
I really am not quite sure what I'm doing, so anything would help. I'm sorry if the code is bad, I'm just starting out.
length of the password must be at least 6 characters while signing up using Dialogflow chatbot.
I have used system entity "any". But it is so generalized.
Webhook is written in flask python.
Also tried to do it by using [0-9]{6}$ as a regex entity. But unable to find a proper way to perform this task.
from dialogflow_fulfillment import QuickReplies, WebhookClient, Payload
from flask import Flask, request, Response, jsonify , make_response
import json
import requests
app = Flask(__name__)
def handler(agent: WebhookClient) :
"""Handle the webhook request.."""
req = request.get_json(force=True)
intent_name = req.get('queryResult').get('intent').get('displayName')
if intent_name == 'intro':
agent.add('I am the chatbot of this page. Ready to assist you with anything you need. What would you like to do?')
agent.add(QuickReplies(quick_replies=['START NOW','LOGIN']))
if intent_name == 'get_started':
url = 'http://**********.com/create_account'
userid = req.get('queryResult').get('parameters').get('email')
print(userid)
pwd = req.get('queryResult').get('parameters').get('pwd')
print(pwd)
name = req.get('queryResult').get('parameters').get('person')['name']
print(name)
age = req.get('queryResult').get('parameters').get('age')
print(age)
myobj = {'userid': userid, 'pwd': pwd , 'name' : name, 'age' : age}
x = requests.post(url, data = myobj)
result=x.text
agent.add(result)
if intent_name == 'login_screen' :
url = 'http://**********.com/auth_account'
userid = req.get('queryResult').get('parameters').get('email')
print(userid)
pwd = req.get('queryResult').get('parameters').get('pwd')
print(pwd)
myobj = {'userid': userid, 'pwd': pwd }
x = requests.post(url, data = myobj)
result = x.text
agent.add(result)
#app.route('/webhook', methods=['GET', 'POST'])
def webhook():
"""Handle webhook requests from Dialogflow."""
req = request.get_json(force=True)
agent = WebhookClient(req)
agent.handle_request(handler)
return agent.response
if __name__ == '__main__':
app.run(debug=True)
With regex :
Defined regex :
How to do this properly?
How to use regex in it?
Or should i use another approach?
I get Successful status code for my POST requests , Login is working fine , but the SMS is not sent
I have gone through all codes on internet, most of them are out-dated, as the site has changed its code.
import requests as req
def login_way2sms():
with req.Session() as mySession:
url = 'http://www.way2sms.com/re-login'
home_url = 'http://www.way2sms.com/'
mobile = [your registered mobile number]
password = [your password]
headers = dict(Referrer="http://www.way2sms.com/")
before = mySession.get(home_url)
login_data = dict(mobileNo=mobile, password=password, CatType='', redirectPage='', pid='')
mySession.post(url, data=login_data, headers=headers)
after = mySession.get(home_url)
return mySession
def send_msg(mysession): #saw sendsms-toss in Inspect under Network tab
url = 'http://www.way2sms.com/smstoss'
home_url = 'http://www.way2sms.com/'
sms_url = 'http://www.way2sms.com/send-sms'
group_contact_url = 'http://www.way2sms.com/GroupContacts'
web_msg_count_url = 'http://www.way2sms.com/CheckWebMsgCount'
headers = dict(Referrer="http://www.way2sms.com/send-sms")
before = mysession.get(home_url)
token = '2B7CF7C9D2F14935795B08DAD1729ACF'
message = 'How to make this work?'
mobile = '[a valid phone number]'
ssaction = 'undefined'
senderid = 'WAYSMS'
msg_data = dict(Token=token, message=message, toMobile=mobile, ssaction=ssaction, senderId=senderid)
mysession.post(url, data=msg_data, headers=headers)
after = mysession.get(home_url)
mysession.post(group_contact_url, headers=headers)
group_contacts = mysession.get(sms_url)
mysession.post(web_msg_count_url, headers=headers)
web_msg_count = mysession.get(sms_url)
# last 2 POST requests send after clicking the Send Msg button
def main():
login_way2sms() #login using username and password
send_msg(currsession) #send sms
main()
I finally got it right , Thanks for replying. We can do it without using the apikey and secret keys as well, Here take a look at this. And init is just another script where constant urls and login is defined, nothing much there.
import requests as req
import init
def login_way2sms(credential):
with req.Session() as mySession:
mobile = credential.username
password = credential.password
headers = dict(Referrer="http://www.way2sms.com/")
login_data = dict(mobileNo=mobile, password=password, CatType='', redirectPage='', pid='')
mySession.post(init.login_url, data=login_data, headers=headers)
return mySession
def get_token(mysession):
cookies = mysession.cookies['JSESSIONID']
token = cookies[4:]
return token
def send_msg(mysession, token):
"""
:rtype: req.Session()
"""
headers = dict(Referrer="http://www.way2sms.com/send-sms")
message = 'Hi, I am Upgraded a little!!!'
mobile = '[valid phone]'
msg_data = dict(Token=token, message=message, toMobile=mobile, ssaction=init.ssaction, senderId=init.senderid)
mysession.post(init.sms_url, data=msg_data, headers=headers)
def main():
credential = init.enter_credentials()
currsession = login_way2sms(credential)
reply = currsession.get(init.home_url)
page_content: str = str(reply.content)
if (reply.status_code == 200) and (page_content.find('send-sms', 10, 200) != -1):
print("Login Successful!\n")
else:
print("Login Failed , Try again\n")
credential = init.enter_credentials()
currsession = login_way2sms(credential)
token = get_token(currsession)
send_msg(currsession, token)
main()
The following method and code worked for me after creating a free account at way2sms (I hope you already did it). Then click on API tab then campaign at left. Then create test API and Secret Key (free with 25 message limit). Then use the following code--
import requests
import json
URL = 'http://www.way2sms.com/api/v1/sendCampaign'
# get request
def sendPostRequest(reqUrl, apiKey, secretKey, useType, phoneNo, senderId, textMessage):
req_params = {
'apikey':'your_apiKey',
'secret':'your_secretKey',
'usetype':'stage'
'phone': 'receiving_phone_number',
'message':'The textMessage I want to send',
'senderid':'Your Name'
}
return requests.post(reqUrl, req_params)
# get response
response = sendPostRequest(URL, 'provided-api-key', 'provided-secret', 'prod/stage', 'valid-to-mobile', 'active-sender-id', 'message-text' )
"""
Note:-
you must provide apikey, secretkey, usetype, mobile, senderid and message values
and then requst to api
"""
# print response if you want
print response.text
Just fill the fields and run in python 2.7. Working perfectly on any Indian number.
I have been having trouble figuring out how to add element types using a Suds factory. My code is below:
from xml.etree import cElementTree as ElementTree
from suds.client import Client
from suds.wsse import *
from suds.sax.text import Raw
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
username = 'username#tenant'
password = 'password'
url = 'https://wd2-impl-
services1.workday.com/ccx/service/[tenant]/Revenue_Management/v31.1?wsdl'
client = Client(url, username = username, password = password, faults = False)
CustomerObjectType = client.factory.create('ns0:CustomerObjectType')
CustomerObjectType.ID = 'CUS3466'
FinancialsBusinessProcess = client.factory.create('ns0:Financials_Business_Process_ParametersType')
FinancialsBusinessProcess.Auto_Complete = 'true'
CustomerData = client.factory.create('ns0:Customer_WWS_DataType')
CustomerData.Customer_Name = 'Test'
CustomerData.Worktag_Only = 'false'
CustomerData.Submit = 'true'
CustomerData.Payment_Terms_Reference.ID = ['NET30', 'Customer_ID']
CustomerData.Default_Payment_Type_Reference.ID = ['PTY_CHECK', 'Payment_Terms_ID']
CustomerData.Included_Children_Reference = ['CUS3029', 'Customer_ID']
CustomerData.Business_Entity_Data.Business_Entity_Name = 'Test'
security = Security()
token = UsernameToken(username, password)
security.tokens.append(token)
client.set_options(wsse=security)
client.service.Submit_Customer('true', CustomerObjectType, FinancialsBusinessProcess, CustomerData)
The error I am receiving is:
ERROR:suds.client:<suds.sax.document.Document instance at 0x10eb0e488>
With the output:
DEBUG:suds.client:headers = {'SOAPAction': '""', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.client:HTTP failed - 500 - Internal Server Error:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wd="urn:com.workday/bsvc">
<faultcode>SOAP-ENV:Client.validationError</faultcode>
<faultstring>Validation error occurred. Element 'ID' is missing attribute 'type'</faultstring>
<detail>
<wd:Validation_Fault>
<wd:Validation_Error>
<wd:Message>Element 'ID' is missing attribute 'type'</wd:Message>
<wd:Detail_Message>Element 'ID' is missing attribute 'type'</wd:Detail_Message>
<wd:Xpath>/ns0:Submit_Customer_Request[1]/ns0:Customer_Data[1]/ns0:Payment_Terms_Reference[1]/ns0:ID[2]</wd:Xpath>
</wd:Validation_Error>
</wd:Validation_Fault>
</detail>
</SOAP-ENV:Fault>
The formatting given back by the suds factory for the "Payment_Terms_Reference" element is as follows:
Payment_Terms_Reference =
(Payment_TermsObjectType){
ID[] =
"NET30",
"Customer_ID",
_Descriptor = ""
}
Where I am confused is that it looks like it is using the index
Payment_Terms_Reference[1]/ns0:ID[2]
to find the element type, but when I add more data to the list in the complex object type it doesn't solve the problem.
The current XML code that spits out for Payment_Terms_Reference when I run this code comes out as:
<ns0:Payment_Terms_Reference>
<ns0:ID>PTY_CHECK</ns0:ID>
<ns0:ID>Payment_Terms_ID</ns0:ID>
</ns0:Payment_Terms_Reference>
But I think I need it to format like:
<ns0:Payment_Terms_Reference>
<ns0:ID ns0:type="Payment_Terms_ID">ID</ns0:ID>
</ns0:Payment_Terms_Reference>
If anyone knows what might help me solve this problem, that would be much appreciated.
Thanks!
You need to create a factory for the Payment_TermsObjectType
paymenttype = client.factory.create('ns0:Payment_TermsObjectIDType')
paymenttype._type = "PTY_CHECK"
paymenttype.value = "Payment_Type_ID"
CustomerData.Payment_Terms_Reference.ID = paymenttype
Is there a way to modify user details (email in particular) using jenkins api?
Posting a modified json file to {root}/user/{username}/api/json does not seem to modify the underlying data:
import urllib2
import json
root = 'your_url'
username = 'your_username'
user_url = root +'/user/{username}/api/json'.format(username=username)
orig_d = json.loads((urllib2.urlopen(user_url).read()))
d = dict(orig_d)
d['fullName'] = 'XXXXX'
json_data = json.dumps(d)
request = urllib2.Request(user_url)
request.add_header('Content-type', 'application/json')
new_d = json.loads(urllib2.urlopen(request, json_data).read())
print new_d, '\n', orig_d
assert orig_d!=new_d, 'They are equal!'
After looking at jenkins source code model/User.java it looks like the only "POST" configuration that is supported on User model is done through doConfigSubmit() member function. So I eneded up faking web POST form at jenkins_url/user/{username}/configSubmit. The following snippet worked for me:
import urllib2, urllib
import json
root = jenkins_url
username = username
user_url = root +'/user/{username}/api/json'.format(username=username)
config_url = root + '/user/{username}/configSubmit'.format(username=username)
d = json.loads((urllib2.urlopen(user_url).read()))
fullname = d['fullName']
description = d['description']
new_email = 'new_user_email'
post_d = {"userProperty1": {"address": new_email}}
request = urllib2.Request(config_url)
values = {'json': json.dumps(post_d),
'fullName': fullname,
'email.address': new_email,
'description': description}
data = urllib.urlencode(values)
response = urllib2.urlopen(request, data).read()