Creating a new word doc

We consume a web service for various pieces of data including attachments. We would like to incorporate this functionality into ignition, so users could view documents within the app.

I go out, get the stream of data and save that binary as a word doc. This works fine in python (eclipse, idle, etc) obviously slightly different due to the ignition methods. However when we try and duplicate it in ignition we are unable to get the word doc to build correct, as it is always corrupted when we try and open it. I’m guessing this is some kind of encoding issue?

Does anyone have any ideas what I could be doing wrong?

from __future__ import with_statement

authUrl="https://examplehost.net/rest/auth/1/login"
getUrl="https://examplehost.net/api/v2/workspaces/53/files/142"

    
password='MYPASSWORD'
headers={"Content-Type" : "application/json", "Accept": "application/json", "userID" : "ME", "password" :password}
sesh=system.util.jsonDecode(system.net.httpPost(authUrl , headers))
#get authorization
token, sessionId= sesh['customerToken'], sesh['sessionid']

#get data
headers={"Accept" : "application/octet-stream", "Cookie": str("customer=%s; JSESSIONID=%s" % (token, sessionId))}
obj=system.net.httpGet(getUrl, headerValues=headers)

#try and write
path=r'C:\Users\USERNAME\Desktop\file.doc'
with open(path, 'wb') as f:
    #this writes but when you try and open it, it fails as corrupt
    f.write(obj)

Wait, are you trying to import functionality into Python from the future?

Just kidding, I had to say that.

The system.net.httpGet function returns a String, which might be the problem.

You could use Java’s http request functionality to get your binary data. Remember that Jython has access to and can use Java’s libraries.

Code for this in Java which can easily be converted to Jython is here: stackoverflow.com/questions/3221 … connection
And here: java2s.com/Tutorial/Java/032 … romURL.htm

You could also try using Python’s urllib2 library. Here is a tutorial on that which includes how to set the headers for a request: pythonforbeginners.com/pytho … in-python/

Best,

Thank you,

I can actually consume the service just fine, in both environments (I’m actually using urllib2 in eclipse) I return a string (what appears to be a identical string), it’s just for some reason when I create the document from ignition it’s corrupted.

This is why I think it’s some sort of encoding issue, but I’ve tried a bunch of different formats, none seem to work.

Have you tried using urllib2 in Ignition?

Maybe the string being returned by urllib2 is not identical to what is being returned by system.net.httpGet, and that is what I suspect.

I did try urllib2 initially (code below), but I get this error which drove me to the inductive methods.

[quote]urllib2.URLError: <urlopen error (-1, 'SSL exception: Differences between the SSL socket behaviour of cpython vs. jython are explained on the wiki: wiki.python.org/jython/NewSocket … L_Support’)>

[/quote]

I couldn’t get it to work (even after following the wiki instructions).

I then found a thread where Colby posted an SSL work around, but it failed in the wrapper function.

https://www.inductiveautomation.com/forum/viewtopic.php?f=70&t=11809&start=0&st=0&sk=t&sd=a&hilit=httpget

So yeah, this is where I’m at, super frustrating because I feel I’m super close!

from __future__ import with_statement

def wsGet(url, headers):  
    import urllib2;
    opener = urllib2.build_opener(urllib2.HTTPSHandler)
    request = urllib2.Request(url)
    for key, val in headers.iteritems():
        request.add_header(key, val)
    
    request.get_method = lambda: 'GET'
    result = opener.open(request)
    return (result.read())

authUrl="https://examplehost.net/rest/auth/1/login"
getUrl="https://examplehost.net/api/v2/workspaces/53/files/142"

    
password='MYPASSWORD'
headers={"Content-Type" : "application/json", "Accept": "application/json", "userID" : "ME", "password" :password}
sesh=system.util.jsonDecode(system.net.httpPost(authUrl , headers))
#get authorization
token, sessionId= sesh['customerToken'], sesh['sessionid']

#get data
headers={"Accept" : "application/octet-stream", "Cookie": str("customer=%s; JSESSIONID=%s" % (token, sessionId))}


input=wsGet(getUrl, headers)
path=r'C:\Users\USERNAME\Desktop\inductive.doc'

with open(path, 'wb+') as f:
 f.write(input)

f.close()

I see, you might want to try the Java approach then, using javax.net.ssl.HttpsURLConnection etc.

Look at this:
Java HttpsURLConnection example
mkyong.com/java/java-https-c … n-example/

FYI, I was able to get it working using some of the stuff you linked too.

Thanks again.

In case anyone ever needs to download an attachment from a web service in the future (I know I’ve used countless examples from here).


from __future__ import with_statement
from java.net import URL
from java.nio.file import Files, Path
import jarray, base64, subprocess

#urls
host="YOUR HOST"
authUrl=host+"LOGIN URL"
getUrl=host+"FILE URL"

#base64 of my password, do that somewhere else, so your pword isn't sitting out
password='PUT CRAZY BASE64 TEXT HERE'

#login to the api
headers={"Content-Type" : "application/json", "Accept": "application/json", "userID" : "this.guy", "password" : base64.b64decode(password)}
sesh=system.util.jsonDecode(system.net.httpPost(authUrl , headers))

#get authorization
token, sessionId= sesh['customerToken'], sesh['sessionid']
output=Path
path=Files.createTempFile(None, "inductivetempfile.doc")
output=Files.newOutputStream(path)

#open conn, add headers and get stream
url=URL(getUrl)
conn=url.openConnection()
conn.setRequestProperty("Accept", "application/octet-stream")
conn.setRequestProperty("Cookie", str("customer=%s; JSESSIONID=%s" % (token, sessionId)))
input=(conn.getInputStream())

#create buffer
buffer =jarray.zeros(4096, 'b')
n=input.read(buffer)

#until it's empty
while (n!=-1):
	output.write(buffer, 0, n);
	n=input.read(buffer)
	
#close input and output	
input.close()	
output.close()


#open the file
p=subprocess.Popen('start winword "' + str(path) +'"',  shell=True)
proc=p.wait()