ArcPy Get Coded Domain Values from Portal/AGOL

1004
2
12-06-2018 07:35 AM
JimHerberich
New Contributor II

I am retrieving data from Feature Service Feature Class and Feature Service Table sources hosted on Portal (10.6) via a Python toolbox tool in ArcGIS Pro (currently 2.2.1).  Some fields have coded domains, and naturally I want to return the domain values instead of the codes.  I thought I could use arcpy.da.ListDomains or arcpy.DomainToTable_management to enable the lookups, except I can't find what to use as the "in_workspace" parameter for these (the service URL does not work).  Currently fetching data with arcpy.da.TableToNumPyArray but could go to arcpy.da.SearchCursor although that returns codes, too.  Am I out-of-luck?

Tags (2)
2 Replies
RandyBurton
MVP Alum

You can use the REST API to read the feature layer's JSON.  You can find the domain information listed in the fields section.  For AGOL I have used this code (with modification, it may also work with Portal).  It returns a field's domain in an ordered dictionary.  From there, you can get the domain's name, type and the name/code pairing.  Hope this helps.

import urllib
import urllib2
import json
import collections

# Credentials and feature service information
username = <username>
password = <password>

services = [ "FeatureLayerName" ] # service you are interested in
URL = "https://services.arcgis.com/<abcxyz>/arcgis/rest/services/" # modify as needed


# obtain a token
referer = "http://www.arcgis.com/"
query_dict = { 'username': username, 'password': password, 'referer': referer }

query_string = urllib.urlencode(query_dict)
url = "https://www.arcgis.com/sharing/rest/generateToken"
token = json.loads(urllib.urlopen(url + "?f=json", query_string).read())

if "token" not in token:
    print(token['error'])
    sys.exit(1)

query_dict = { "f": "json", "token": token['token'] }

# display json data
for service in services:

    # print service + " - ",
    fsURL = URL + service + "/FeatureServer/0" # assumes first layer, may need to adjust

    jsonResponse = urllib.urlopen(fsURL, urllib.urlencode(query_dict))

    jsonOutput = json.loads(jsonResponse.read(),
                            object_pairs_hook=collections.OrderedDict)[u'fields']

    for field in jsonOutput:
        if field["domain"] is not None:
            print field["domain"]
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

EDIT -  Also, when you query a feature with the REST API, the returned JSON includes a fields section with a features (attributes) section.  You just need to process the fields section for domains and then process the features/attributes.

0 Kudos
JimHerberich
New Contributor II

Thanks Randy.  But completely separate access method and authentication method don't really help in the Desktop (arcpy) context... at least we now know where to get the info!

0 Kudos