Скрипт WORKetc API на Python

#python #xml #json #api

#python #xml #json #API

Вопрос:

Я пытаюсь создать универсальный скрипт на Python, который может использоваться кем угодно для импорта / экспорта всевозможной информации с / на рабочую платформу Etc CRM. Здесь есть вся документация: http://admin.worketc.com/xml .

Однако сейчас я немного застрял. Аутентификация работает, я могу вызывать разные методы API, но только те, у которых нет параметров. Я новичок в Python, и именно поэтому я не могу понять, как передать параметры этому конкретному методу в API. В частности, мне нужно экспортировать все табели учета рабочего времени. Я пытаюсь конкретно вызвать этот метод: http://admin.worketc.com/xml?op=GetDraftTimesheets . По понятным причинам я не могу раскрыть информацию для входа, поэтому вам может быть немного сложно протестировать.

Сам код:

 import xml.etree.ElementTree as ET
import urllib2
import sys

email = 'email@domain.co.uk'
password = 'pass'
#service = 'GetEmployee?EntityID=1658'
#service = 'GetEntryID?EntryID=23354'
#service = ['GetAllCurrenciesWebSafe']
#service = ['GetEntryID', 'EntryID=23354']
service = ['GetDraftTimesheets','2005-08-15T15:52:01 00:00','2014-08-15T15:52:01 00:00' ]

class workEtcUniversal():
    sessionkey = None

    def __init__(self,url):
        if not "http://" in url and not "https://" in url:
            url = "http://%s" % url
            self.base_url = url

        else:
            self.base_url = url

    def authenticate(self, user, password):
        try:
            loginurl = self.base_url   email   'amp;pass='   password
            req = urllib2.Request(loginurl)
            response = urllib2.urlopen(req)

            the_page = response.read()
            root = ET.fromstring(the_page)
            sessionkey = root[1].text
            print 'Authentication successful!'

            try:
                f = self.service(sessionkey, service)
            except RuntimeError:
                print 'Did not perform function!'

        except RuntimeError:
            print 'Error logging in or calling the service method!'

    def service(self, sessionkey, service):

            try:
                if len(service)<2:         
                    retrieveurl = 'https://domain.worketc.com/xml/'   service[0]   '?VeetroSession='   sessionkey
                else: 
                    retrieveurl = 'https://domain.worketc.com/xml/'   service[0,1,2]   '?VeetroSession='   sessionkey
            except TypeError as err:
                print 'Type Error, which means arguments are wrong (or wrong implementation)'
                print 'Quitting..'
                sys.exit()

            try:
                responsefile = urllib2.urlopen(retrieveurl)
            except urllib2.HTTPError as err:
                if err.code == 500:
                    print 'Internal Server Error: Permission Denied or Object (Service) Does Not Exist'
                    print 'Quitting..'
                    sys.exit()
                elif err.code == 404:
                    print 'Wrong URL!'
                    print 'Quitting..'
                    sys.exit()
                else:
                    raise

            try:
                f = open("ExportFolder/worketcdata.xml",'wb')
                for line in responsefile:
                    f.write(line)
                f.close()
                print 'File has been saved into: ExportFolder'
            except (RuntimeError,UnboundLocalError):
                print 'Could not write into the file'


client = workEtcUniversal('https://domain.worketc.com/xml/AuthenticateWebSafe?email=')
client.authenticate(email, password)
 

Ответ №1:

Написание API, использующего код, требует решения нескольких вопросов:

  • какие методы в API доступны (получите их список с именами)
  • как выглядит запрос к такому методу (узнайте URL, используемый метод HTTP, требования к телу, если оно используется, какие заголовки ожидаются)
  • как собрать все части для выполнения запроса

Какие методы доступны

http://admin.worketc.com/xml перечисляет многие из них

Как выглядит запрос

GetDraftTimesheet описывается здесь http://admin.worketc.com/xml?op=GetDraftTimesheets

и он ожидает, что вы создадите следующий HTTP-запрос:

 POST /xml HTTP/1.1
Host: admin.worketc.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://schema.veetro.com/GetDraftTimesheets"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetDraftTimesheets xmlns="http://schema.veetro.com">
      <arg>
        <FromUtc>dateTime</FromUtc>
        <ToUtc>dateTime</ToUtc>
      </arg>
    </GetDraftTimesheets>
  </soap:Body>
</soap:Envelope>
 

Создание запроса

Самая большая задача — создать XML-документ правильной формы, как показано выше, содержащий элементы FromUtc и ToUtc заполненный правильными значениями. Я предполагаю, что значения должны быть в формате ISO datetime, это вы найдете сами.

Вы сможете создать такой XML с помощью какой-нибудь библиотеки Python, которую я бы использовал lxml .

Обратите внимание, что XML-документ использует пространства имен, вы должны правильно их обрабатывать.

Создание POST-запроса со всеми заголовками должно быть простым. Библиотека, которую вы используете для выполнения HTTP-запросов, должна правильно заполнять Content-Length значение, но в основном это делается автоматически.

Veerto предоставляет множество альтернативных методов

Например, для «http://admin.worketc.com/xml?op=FindArticlesWebSafe » существует множество различных методов для одной и той же услуги:

  • SOAP 1.1
  • SOAP 1.2
  • HTTP GET
  • HTTP СООБЩЕНИЕ

В зависимости от ваших предпочтений выберите тот, который соответствует вашим потребностям.

Самый простой — это, в основном, HTTP GET .

Для HTTP-запросов я бы рекомендовал использовать requests , которые действительно просты в использовании, если вы пройдете учебник, вы поймете, что я имею в виду.

Комментарии:

1. Спасибо за быстрый ответ! Мне просто интересно. Разве я не могу просто создать XML-файл, который выглядит точно так же в текстовом редакторе, а затем использовать его?

2. @serg553 Да, вы можете использовать XML, созданный в редакторе. Но если вы хотите передать некоторые параметры, вам нужно изменить xml для каждого запроса. Обратите внимание, что приведенный выше XML-файл должен содержать обновленные значения для «DateTime» до чего-то похожего на «2014-06-24T12: 01:22» (проверьте документацию API, но, вероятно, он допускает тип XSD xsd:dateTime .