Для работы понабодобиться инструмент, позволяющий отправлять 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"])