0

I am trying to pass a xml payload as an input to a function and in the payload objectZippedData field doesn't take string as an input, instead it needs the input to be in byte format.

def getSoapResponse(Envelope, url, action):
    try:
        envelope = Envelope
        # Create and register opener. Requires proxy when behind a firewall
        opener = urllib.request.build_opener(urllib.request.HTTPHandler(), urllib.request.HTTPSHandler(),
                                             urllib.request.ProxyHandler())
        urllib.request.install_opener(opener)
        # Create request for the service call
        request = urllib.request.Request(url)

        # Configure the request content type to be xml
        request.add_header("Content-Type", 'application/soap+xml;charset=utf-8')

        # Set the SOAP action to be invoked; while the call works without this, the value is expected to be set based on standards
        request.add_header("SOAPAction", action)

        # Write the xml payload to the request
        request.data = envelope.encode()
        
        handle = urllib.request.urlopen(request, cafile=certifi.where())
            
        # Get the response and process it
        xmlString = (handle.read(2000).decode('utf-8'))
        if action != "uploadObjectInSession":
            # Convert the response into XML tree structure
            sessionxml = fromstring(xmlString)
            # Get the session value from the XML tree
            ReturnVal = sessionxml[0][0][0].text if action == 'login' else 'Success'
            return (ReturnVal)
        else:
            return "Success"
    except Exception as err:
        print("getSoapResponse - Error occurred; Message ", str(err))
        print("===============================================================")
        return "Error"

def uploadSession(catFile, Target):
    try:
       with open(catFile, 'rb') as f:
           bytes_encoded = base64.b64encode(f.read())
           string_encoded = bytes_encoded.decode()
           f.close()
    except IOError:
       return "Error"

new_Envelope = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://xmlns.oracle.com/oxp/service/v2">
        <soapenv:Header/>
        <soapenv:Body>
            <v2:uploadObjectInSession>
                <v2:reportObjectAbsolutePathURL>""" + Target + """</v2:reportObjectAbsolutePathURL>
                <v2:objectType>xdoz</v2:objectType>
                <v2:objectZippedData>""" + string_encoded + """</v2:objectZippedData>
                <v2:bipSessionToken>""" + target_sessionid + """</v2:bipSessionToken>
            </v2:uploadObjectInSession>
        </soapenv:Body>
        </soapenv:Envelope> """

Final = getSoapResponse(Envelope=new_Envelope, url, action='uploadObjectInSession')
    if Final=="Error":
       print("FAILURE")
       return "Error"
    else:
       print(Final)
       return "Success"

Once the above function is called, and if I pass the string in objectZippedData, it fails to succeed whereas if I pass byte data in objectZippedData, I get the below error

new_Envelope = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://xmlns.oracle.com/oxp/service/v2">
TypeError: can only concatenate str (not "bytes") to str

1 Answer 1

0

Use .encode() to convert a string to bytes

>>> mystr="test"
>>> type(mystr)
<class 'str'>
>>> type(mystr.encode())
<class 'bytes'>

Your error suggests that when creating your newEnvelope by concatenating (using +) to accumulate your inputs together, one of them is actually of type bytes, instead of a string.

Find which one and use .decode() to turn it into a string.

Sign up to request clarification or add additional context in comments.

8 Comments

I am able to convert from string to bytes but I need help passing that bytes data into the payload for the objectZippedData field
Are you getting an error when putting it in place of string_encoded?
"string_encoded" is the string version of the result and "byte_encoded" is the byte version of the result. I get an unsuccessful response when I pass string_encoded as it only accepts bytes input.
So you're saying getSoapResponse() is expecting bytes for the content of new_envelope?
Right! For the objectZippedData field.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.