Search code examples
pythonvb.netpython-2.7wsdlsuds

How to use Types and Methods with SUDS


My code connects to a Autotask service through SUDS. I get a list of Methods, one of which I have to call. I'm new to this, so I'm not sure on how to correctly do this. This is my code, including help by Bodsda:

import os, sys
import xml.etree.ElementTree as ET
from suds.client import Client
from suds.sax.element import Element


class Init():
    def __init__(self):
        #Search the app.config file for all data to be used
        script_dir = os.path.dirname(__file__)
        file_path = "app.config"
        abs_file_path = os.path.join(script_dir, file_path) 

        tree = ET.parse(abs_file_path)
        root = tree.getroot()
        sites = root.iter('AutotaskUpdateTicketEstimatedHours.My.MySettings')
        self.data = {}
        for site in sites: 
            apps = site.findall('setting')
            for app in apps:
                self.data[app.get('name')] = app.find('value').text


class ConnectATWS():
    def __init__(self):
        #Connect to server with the credentials
        app_config = Init()
        self.username = app_config.data["Username"]
        self.password = app_config.data["Password"]
        self.login_id = app_config.data["LoginID"]
        strQuery = """
        <queryxml>
            <entity>Ticket</entity>
            <query>
                <condition>
                    <field>Id
                        <expression op="GreaterThan">0</expression>
                    </field>
                </condition>
                <condition>
                    <field>Status
                        <expression op="NotEqual">5</expression>
                    </field>
                </condition>
                <condition>
                    <field>EstimatedHours
                        <expression op="IsNull"></expression>
                    </field>
                </condition>
            </query>
        </queryxml>"""
        new_url = 'https://webservices5.autotask.net/atservices/1.5/atws.wsdl'
        client = Client(new_url, username=self.login_id, password=self.password)
        response = client.service.query(strQuery)

        if response.ReturnCode != 1:
            print "Error code: %s" % response.ReturnCode
            print "Error response: %s" % response.Errors
            sys.exit(1)
        else:
            print "Query successful..."
            print "============================="
            print response.EntityResults



if __name__ == '__main__':
    handler = ConnectATWS()

This is my response:

(ATWSResponse){
   ReturnCode = 1
   EntityResults = ""
   EntityResultType = "ticket"
   Errors = ""
   EntityReturnInfoResults = ""
 }

This is the list of Methods and Types I get through the client:

    Suds ( https://fedorahosted.org/suds/ )  version: 0.4 GA  build: R699-20100913

Service ( ATWS ) tns="http://autotask.net/ATWS/v1_5/"
   Prefixes (1)
      ns0 = "http://autotask.net/ATWS/v1_5/"
   Ports (1):
      (ATWSSoap)
         Methods (14):
            CreateAttachment(Attachment attachment, )
            DeleteAttachment(xs:long attachmentId, )
            GetAttachment(xs:long attachmentId, )
            GetFieldInfo(xs:string psObjectType, )
            GetInvoiceMarkup(xs:int InvoiceId, xs:string Format, )
            GetWsdlVersion()
            create(ArrayOfEntity Entities, )
            delete(ArrayOfEntity Entities, )
            getEntityInfo()
            getThresholdAndUsageInfo()
            getUDFInfo(xs:string psTable, )
            getZoneInfo(xs:string UserName, )
            query(xs:string sXML, )
            update(ArrayOfEntity Entities, )
         Types (108):
            ATWSError
            ATWSResponse
            ATWSZoneInfo
            Account
            AccountLocation
            AccountNote
            AccountTeam
            AccountToDo
            ActionType
            AdditionalInvoiceFieldValue
            AllocationCode
            Appointment
            ArrayOfATWSError
            ArrayOfEntity
            ArrayOfEntityInfo
            ArrayOfEntityReturnInfo
            ArrayOfField
            ArrayOfPickListValue
            ArrayOfUserDefinedField
            Attachment
            AttachmentInfo
            AutotaskIntegrations
            BillingItem
            BillingItemApprovalLevel
            ChangeRequestLink
            ClientPortalUser
            Contact
            Contract
            ContractBlock
            ContractCost
            ContractFactor
            ContractMilestone
            ContractNote
            ContractRate
            ContractRetainer
            ContractService
            ContractServiceAdjustment
            ContractServiceBundle
            ContractServiceBundleAdjustment
            ContractServiceBundleUnit
            ContractServiceUnit
            ContractTicketPurchase
            Country
            Department
            Entity
            EntityDuplicateStatus
            EntityInfo
            EntityReturnInfo
            EntityReturnInfoDatabaseAction
            ExpenseItem
            ExpenseReport
            Field
            InstalledProduct
            InstalledProductType
            InstalledProductTypeUdfAssociation
            InternalLocation
            InventoryItem
            InventoryItemSerialNumber
            InventoryLocation
            InventoryTransfer
            Invoice
            InvoiceTemplate
            Opportunity
            PaymentTerm
            Phase
            PickListValue
            Product
            ProductVendor
            Project
            ProjectCost
            ProjectNote
            PurchaseOrder
            PurchaseOrderItem
            PurchaseOrderReceive
            Quote
            QuoteItem
            QuoteLocation
            Resource
            ResourceRole
            ResourceSkill
            Role
            SalesOrder
            Service
            ServiceBundle
            ServiceBundleService
            ServiceCall
            ServiceCallTask
            ServiceCallTaskResource
            ServiceCallTicket
            ServiceCallTicketResource
            ShippingType
            Skill
            Task
            TaskNote
            TaskPredecessor
            TaskSecondaryResource
            Tax
            TaxCategory
            TaxRegion
            Ticket
            TicketChangeRequestApproval
            TicketCost
            TicketNote
            TicketSecondaryResource
            TimeEntry
            UserDefinedField
            UserDefinedFieldDefinition
            UserDefinedFieldListItem

I need to use the ATWSResponse type but I don't really understand how to do this. Furthermore, I'm attempting to simulate this vb.net code part which does what I'm trying to do in Python:

Sub ProcessTicket()
    Dim boolQueryFinished = False
    Dim strCurrentID As String = "0"
    Dim strQuery As String
    Dim strCriteria As String = ""
    Dim TicketArray(0) As Ticket

    While (Not (boolQueryFinished))
        If LCase(Trim(varIgnoreTicketStatus)) = "true" Then
            WriteToLog("Updating All Tickets Where EstimatedHours Is Null")
        Else
            WriteToLog("Updating Ticket Where Status <> Complete And EstimatedHours Is Null")
            ' 5 - Complete
            strCriteria = "<condition><field>Status<expression op=""NotEqual"">5</expression></field></condition>"
        End If

        strQuery = "<queryxml><entity>Ticket</entity><query>" & _
                    "<condition><field>id<expression op=""greaterthan"">" & strCurrentID & "</expression></field></condition>" & strCriteria & _
                    "<condition><field>EstimatedHours<expression op=""isnull""></expression></field></condition>" & _
                    "</query></queryxml>"

        Dim r As ATWSResponse
        Dim strLog As String

        r = ATWSService.query(strQuery)
        WriteToLog("Found " & r.EntityResults.Length & " Tickets begining at " & strCurrentID)

        If r.EntityResults.Length > 0 Then
            For Each ent As Entity In r.EntityResults
                CType(ent, Ticket).EstimatedHours = EstHoursDefault

                TicketArray(0) = CType(ent, Ticket)

                Dim sResponse As ATWSResponse
                Dim entityArray() As Entity = CType(TicketArray, Entity())
                sResponse = ATWSService.update(entityArray)

My question is how can I successfully query with the QueryXML with my Python code and return entities like in the vb.net code?


Solution

  • First of all, the url being used to connect to the api was not the correct one. I needed to use https://webservices5.autotask.net/atservices/1.5/atws.wsdl.

    Once the client received a response, I had to match the ReturnCode in order to run the code I wanted. The return code could not be 1 (which is an error in the query), therefore I used:

            if response.ReturnCode != 1:
                print "Error code: %s" % response.ReturnCode
                print "Error response: %s" % response.Errors
                sys.exit(1)
            else:
                print "Query successful..."
                print "============================="
                response = response.EntityResults[0]
    

    In order to store my returned data (entities), which were Tickets, I had to do the following loops:

                entities = []
                for entity in response:
                    entities.append(dict(entity))
    
                for entity in entities:
                    self.query_data.append(entity["Title"] + "  Estimated Hours " + str(entity["EstimatedHours"]))
    

    This way I could store the list of tuples in entities list in order to then access each entity themselves. With this done, all I had to do was append the results to a list self.query_data.

    Note: Credit to Bodsda for his help in figuring out how I was querying the wrong address with my XML, plus help with the loops.