passing file attachments in SOAP using suds - python

We are working on a project where the python client makes RPC call on a Java method
String uploadFile(String name, String Id)
Now, this client code has to send an attachment!
def sendFile(self, Id, filePath):
uploadFileMethod = getattr(self.client.service, "uploadFile")
attachment_id = Id
attachment_content = (filePath, attachment_id)
with_soap_attachment(uploadFileMethod, attachment_content)
Since, suds does not support attachments and I luckily found a scrpit mentioned that it does. The script is mentioned here
Now, when I execute, I am getting the error
AttributeError: 'Client' object has no attribute 'location'
line 75, in with_soap_attachment
Can anyone help me why its coming and how to fix it?
thanks

what worked for me was to replace
request = Request(suds_method.client.location(), request_text)
with
request = Request(soap_method.location(), request_text)

Related

Extract outlook email body and recipient email address using python

I am trying to extract outlook email body, recipient address, subject and received date.
I was able to extract subject and received date but unable to extract body and recipient address:
Below is my code for subject and received date:
outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
namespace = outlook.Session
recipient = namespace.CreateRecipient("abc#xyz.com")
inbox = outlook.GetSharedDefaultFolder(recipient, 6)
messages = inbox.Items
email_subject = []
email_date = []
email_date_time = []
for x in messages:
sub = x.Subject
received_date = x.senton.date()
received_date_time = str(x.ReceivedTime)
email_subject.append(sub)
email_date.append(received_date)
email_date_time.append(received_date_time)
For body i am trying:
for x in messages:
body = x.Body
print(body)
but this is not working and i am getting the error below:
Traceback (most recent call last):
File "<ipython-input-85-d79967933b99>", line 2, in <module>
sub = x.Body
File "C:\ProgramData\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 516, in __getattr__
ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
com_error: (-2147467259, 'Unspecified error', None, None)
I've just run similar code on my computer, in an inbox with 3,000+ items of mixed type (skype message notifications, calendar invites/notifications, emails, etc.) and I cannot replicate this error, even for items where not m.Body -- I thought that was a possible culprit, maybe a certain type of item doesn't have a body would throw an error -- but that appears to not be the case:
>>> for m in messages:
... if not m.body:
... print(m.Subject)
... print(m.Body)
...
Accepted: Tables discussion
Message Recall Failure: tables/ new data status
Message Recall Failure: A few issues with the data
You should probably add a print(m.Class) because I still think that maybe certain types of items do not have a Body property.
This thread suggests that there may be a user/security setting that prevents programmatic access to Outlook, so you might want to double-check on that (though I think if not allowed, none of your code would work -- still, worth looking in to!).
I have figured out the source of this error. We are running into issues with the comObjectModelGaurd. Our group policy recently changed to disallow programatic access to protected mailItem objects.
Modifying Outlook Users Trust settings or the registry will fix the problem.
Since I can't replicate the error, perhaps I can still help you debug and identify the source of the problem, from which we can probably come up with a good solution.
Use a function to get the item's body, and use try/except to identify which items are causing error.
def getBody(m):
s = ""
try:
s = m.Body
except COMError:
s = '\t'.join(('Error!', m.Class, m.senton.date(), m.Subject))
return s
for m in messages:
print(getBody(m))
I think that I found a solution that worked. For me it was an issue with permissions, but I made the registry edits in https://www.slipstick.com/developer/change-programmatic-access-options/ and it worked a treat.
EDIT: I think this worked by unblocking some lower level permissions that enabled an outside program to access the outlook client.
Recalled Emails would have no Body hence we can find that via the MessageClass and exclude that particular Class
for i in messages:
if email.MessageClass != "IPM.Outlook.Recall":

AWS SQS boto3 send_message returns 'dict' object has no attribute 'send_message'

I am new to python and I am still learning it.
I am writing a python code to send a message to AWS SQS
Following is the code I have written
from boto3.session import Session
session = Session(aws_access_key_id='**', aws_secret_access_key='**',
region_name='us-west-2')
clientz = session.client('sqs')
queue = clientz.get_queue_url(QueueName='queue_name')
print queue responses = queue.send_message(MessageBody='Test')
print(response.get('MessageId'))
On running this code it returns
{u'QueueUrl': 'https://us-west-2.queue.amazonaws.com/##/queue_name', ' ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '##'}}
Traceback (most recent call last):
File "publisher_dropbox.py", line 77, in
responses = queue.send_message(MessageBody='Test')
AttributeError: 'dict' object has no attribute 'send_message'
I am not sure what the 'dict' object is, since I haven't specified that anywhere.
I think you mix up the boto3 client send_mesasge Boto3 client send_message with the boto3.resource.sqs ability.
First, for boto3.client.sqs.send_message, you need to specify QueueUrl. Secondly, the the error message appear because you write incorrect print statement.
# print() function think anything follow by the "queue" are some dictionary attributes
print queue responses = queue.send_message(MessageBody='Test')
In addition, I don't need to use boto3.session unless I need to explicitly define alternate profile or access other than setup inside aws credential files.
import boto3
sqs = boto3.client('sqs')
queue = sqs.get_queue_url(QueueName='queue_name')
# get_queue_url will return a dict e.g.
# {'QueueUrl':'......'}
# You cannot mix dict and string in print. Use the handy string formatter
# will fix the problem
print "Queue info : {}".format(queue)
responses = sqs.send_message(QueueUrl= queue['QueueUrl'], MessageBody='Test')
# send_message() response will return dictionary
print "Message send response : {} ".format(response)

JIRA Python add_attachment() 405 Method Not Allowed

I am trying to upload a file to JIRA via its REST API using the python lib found here: jira python documentation
It seems pretty straight forward I wrote a method that allows me to pass an issue and then it attaches a filename. and one that lets me retrieve an issue from JIRA.
from jira.client import JIRA
class JIRAReport (object):
def attach(self,issue):
print 'Attaching... '
attachment = self.jira.add_attachment(issue, attachment=self.reportpath, filename='Report.xlsx')
print 'Success!'
def getissue(self):
if not self.issue == None:
return self.jira.issue(self.issue)
return None
then in my main script I am getting the issue and attaching the file to an issue I retrieved from JIRA
report = JiraReport()
report.issue = 'ProjectKey-1'
report.reportpath = '../report_upload/tmp/' + filename
issue = report.getissue()
if not issue == None:
report.attach(issue)
else:
print "No Issue with Key Found"
I am able to get the issue/create issues if needed but when using the self.jira.add_attachment() method I am getting 405 Method Not Allowed.
The file exists and is able to be opened.
Here is the add_attachment() method from the source code:
def add_attachment(self, issue, attachment, filename=None):
"""
Attach an attachment to an issue and returns a Resource for it.
The client will *not* attempt to open or validate the attachment; it expects a file-like object to be ready
for its use. The user is still responsible for tidying up (e.g., closing the file, killing the socket, etc.)
:param issue: the issue to attach the attachment to
:param attachment: file-like object to attach to the issue, also works if it is a string with the filename.
:param filename: optional name for the attached file. If omitted, the file object's ``name`` attribute
is used. If you aquired the file-like object by any other method than ``open()``, make sure
that a name is specified in one way or the other.
:rtype: an Attachment Resource
"""
if isinstance(attachment, string_types):
attachment = open(attachment, "rb")
# TODO: Support attaching multiple files at once?
url = self._get_url('issue/' + str(issue) + '/attachments')
fname = filename
if not fname:
fname = os.path.basename(attachment.name)
content_type = mimetypes.guess_type(fname)[0]
if not content_type:
content_type = 'application/octet-stream'
files = {
'file': (fname, attachment, content_type)
}
r = self._session.post(url, files=files, headers=self._options['headers'])
raise_on_error(r)
attachment = Attachment(self._options, self._session, json.loads(r.text)[0])
return attachment
It is mentioned in documentation that as a argument they expect file-like object.
Try to do something like :
file_obj = open('test.txt','rb')
jira.add_attachment(issue,file_obj,'test.txt')
file_obj.close()
Check that the URL that you are specifying for JIRA (if using the on-demand service) is https://instance.atlassian.net.
I just hit this as well, and it sends a POST request to http://instance.atlassian.net and gets redirected to https://instance.atlassian.net, but the client sends a GET request to the redirected address (see: https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect for more information)

How do I return the Instagram Realtime subscription challenge?

I'm trying to subscribe to a tag. It appears that the callback URL is being called correctly with a hub.challenge and hub.mode, and I figured out how to access the challenge using self.request.get('hub.challenge'). I thought I was just supposed to echo the challenge, but that doesn't appear to work since I receive the following errors in the GAE logs:
InstagramAPIError: (400) APISubscriptionError-Challenge verification failed. Sent "647bf6dbed31465093ee970577ce1b72", received "
647bf6dbed31465093ee970577ce1b72
".
Here is the full handler:
class InstagramHandler(BaseHandler):
def get(self):
def process_tag_update(update):
update = update
mode = self.request.get('hub.mode')
challenge = self.request.get('hub.challenge')
verify_token = self.request.get('hub.verify_token')
if challenge:
template_values = {'challenge':challenge}
path = os.path.join(os.path.dirname(__file__), '../templates/instagram.html')
html = template.render(path, template_values)
self.response.out.write(html)
else:
reactor = subscriptions.SubscriptionsReactor()
reactor.register_callback(subscriptions.SubscriptionType.TAG, process_tag_update)
x_hub_signature = self.request.headers.get('X-Hub-Signature')
raw_response = self.request.data
try:
reactor.process('INSTAGRAM_SECRET', raw_response, x_hub_signature)
except subscriptions.SubscriptionVerifyError:
logging.error('Instagram signature mismatch')
So returning it as a string worked. I should have payed closer attention to the error message, but it took a helpful person on the Python IRC to point out the extra line breaks in the message. Once I put the template files on one line, it seemed to work. I can now confirm that my app is authorized via Instagram's list subscription URL.

XML parser syntax error

So I'm working with a block of code which communicates with the Flickr API.
I'm getting a 'syntax error' in xml.parsers.expat.ExpatError (below). Now I can't figure out how it'd be a syntax error in a Python module.
I saw another similar question on SO regarding the Wikipedia API which seemed to return HTML intead of XML. Flickr API returns XML; and I'm also getting the same error when there shouldn't be a response from Flickr (such as flickr.galleries.addPhoto)
CODE:
def _dopost(method, auth=False, **params):
#uncomment to check you aren't killing the flickr server
#print "***** do post %s" % method
params = _prepare_params(params)
url = '%s%s/%s' % (HOST, API, _get_auth_url_suffix(method, auth, params))
payload = 'api_key=%s&method=%s&%s'% \
(API_KEY, method, urlencode(params))
#another useful debug print statement
#print url
#print payload
return _get_data(minidom.parse(urlopen(url, payload)))
TRACEBACK:
Traceback (most recent call last):
File "TESTING.py", line 30, in <module>
flickr.galleries_create('test_title', 'test_descriptionn goes here.')
File "/home/vlad/Documents/Computers/Programming/LEARNING/curatr/flickr.py", line 1006, in galleries_create
primary_photo_id=primary_photo_id)
File "/home/vlad/Documents/Computers/Programming/LEARNING/curatr/flickr.py", line 1066, in _dopost
return _get_data(minidom.parse(urlopen(url, payload)))
File "/usr/lib/python2.6/xml/dom/minidom.py", line 1918, in parse
return expatbuilder.parse(file)
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 928, in parse
result = builder.parseFile(file)
File "/usr/lib/python2.6/xml/dom/expatbuilder.py", line 207, in parseFile
parser.Parse(buffer, 0)
xml.parsers.expat.ExpatError: syntax error: line 1, column 62
(Code from http://code.google.com/p/flickrpy/ under New BSD licence)
UPDATE:
print urlopen(url, payload) == <addinfourl at 43340936 whose fp = <socket._fileobject object at 0x29400d0>>
Doing a urlopen(url, payload).read() returns HTML which is hard to read in a terminal :P but I managed to make out a 'You are not signed in.'
The strange part is that Flickr shouldn't return anything here, or if permissions are a problem, it should return a 99: User not logged in / Insufficient permissions error as it does with the GET function (which I'd expect would be in valid XML).
I'm signed in to Flickr (in the browser) and the program is properly authenticated with delete permissions (dangerous, but I wanted to avoid permission problems.)
SyntaxError normally means an error in Python syntax, but I think here that expatbuilder is overloading it to mean an XML syntax error. Put a try:except block around it, and print out the contents of payload and to work out what's wrong with the first line of it.
My guess would be that flickr is rejecting your request for some reason and giving back a plain-text error message, which has an invalid xml character at column 62, but it could be any number of things. You probably want to check the http status code before parsing it.
Also, it's a bit strange this method is called _dopost but you seem to actually be sending an http GET. Perhaps that's why it's failing.
This seems to fix my problem:
url = '%s%s/?api_key=%s&method=%s&%s'% \
(HOST, API, API_KEY, method, _get_auth_url_suffix(method, auth, params))
payload = '%s' % (urlencode(params))
It seems that the API key and method had to be in the URL not in the payload. (Or maybe only one needed to be there, but anyways, it works :-)

Categories

Resources