eugenden.github.io

Начало работы с API ARCGIS Server

Для работы понабодобиться инструмент, позволяющий отправлять POST-запросы. Для примера возьмем библиотеку Python urrlib2.

Зафиксируем версию python

import sys
print sys.version
'2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)]'

Сформируем credential для ArcGIS Server

server_cred = {
    "protocol": "https",
    "hostname": "GIS_SERVER",
    "root": "arcgis",
    "port": "6443",
    "federated": "False",
    "token_url": "/admin/generatetoken",
    "user": "siteadmin",
    "password": "qwerty123"
}

Кроме библиотеки urllib2 понадобиться библиотека json, т.к. работа с API базируется на обмене текстовыми файлами в формате JSON. Для игнорирования проверки ssl потребуется соответствующая встроенная бибилотека. Помимо этого ддя кодировки параметров пригодиться библиотека urllib.

import urllib
import urllib2
import json
import ssl

Введем функцию для обработки POST-запросов. Укажем headers, закодируем входные параметры и настроим игнорирование сертификата ssl.

def urllib2_call(url_, params_):
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    params = urllib.urlencode(params_)
    sc = urllib2.Request(url_, params, headers)
    sc_response = urllib2.urlopen(sc, context=ctx)
    return sc_response

Теперь можно описать функцию получения токена к ArcGIS Server. Необходимо учесть, что сервер может быть интегрирован с порталом и тогда понадобиться портальный токен. В данном примере используется получение токена для IP если сервер неинтегрированный и токен на “web url”, если сервер интегированный.

def get_token(user_, pw_, token_url_, url=""):
    if bool(url):
        token_parameters = {'username': user_, 'password': pw_, 'client': 'referer',
                            'referer': '{0}/admin'.format(url_), 'f': 'pjson'}
    else:
        token_parameters = {'username': user_, 'password': pw_, 'client': 'requestip', 'f': 'json'}
    response = urllib2_call(token_url_, token_parameters)
    data = response.read()
    if response.code != 200:
        print 'Error while fetching tokens from URL', str(data)
        return ""
    else:
        token = json.loads(data)
        return token['token']

К серверу все запросы можно выполнять с помощью одной функции, меняя url и параметры.

def post_url(url, params, token_url, user, pw, federated="False"):
    if bool(token_url) and bool(user) and bool(pw) and federated == "False":
        tk_str = get_token(user, pw, token_url)
        params['token'] = tk_str if isinstance(params, dict) else {'token': tk_str}
    if bool(token_url) and bool(user) and bool(pw) and federated == "True":
        tk_str = get_token(user, pw, token_url, url)
        params['token'] = tk_str if isinstance(params, dict) else {'token': tk_str}
    params['f'] = 'json'
    response = urllib2_call(url, params)
    data = response.read()
    if response.code != 200:
        print 'Error calling URL={0}, params={1}, descriptions: '.format(url, params), str(data)
        return ""
    else:
        return response, data

Попробуем какой-нибудь практический случай, например добавление роли на портале:

def add_role(x, y):
    print "start function: add_role"
    print "y", y
    url = "{0}://{1}:{2}/{3}".format(x["protocol"], x["hostname"], x["port"], x["root"])
    mid_url = "/admin/security/roles/add"
    compleate_token_url = "{0}/{1}".format(url, x["token_url"])
    url_line = url + mid_url
    roles = y
    for role in roles:
        item = {"rolename": "{}".format(role), "description": ""}
        post_url(url_line, item, compleate_token_url, x["user"], x["password"], x["federated"])
        print "@add role " + role

add_role(server_cred, ["role1", "role2"])