ArcGIS API for Python - How to get() anything using a submodule

1561
1
Jump to solution
03-05-2021 10:44 AM
JoanneMcGraw
Occasional Contributor III

Hello,

As I explore the ArcGIS API for Python functionality, there is something about working with the submodules that I can't seem to figure out and I'm hoping someone can provide info.

I am working with a stand-alone site of two 10.8.1 ArcGIS Servers; i.e., no Portal. The documentation at https://developers.arcgis.com/python/api-reference/arcgis.gis.server.html details a submodule at
https://developers.arcgis.com/python/api-reference/arcgis.gis.server.html#server which indicates the arcgis.gis.server.Server class "can be directly instantied when working with stand-alone (unfederated) ArcGIS Server sites". Seems like a good area for what I am trying to do, which is administering the ArcGIS Server site, not "using" it.

I have been able to instantiate and work with that class to accomplish much of what I want to do, but the manner in which I need to do this seems excessive. Generally, I appear to have to utilize the lists that class provides access to and loop through them all constantly to find, say, the service (or the datastore or whatever) that I want to work with at any given time.

However, other submodule documentation on that page seems to suggest more direct methods to get a service (or a datastore, etc.) are available. For example, the arcgis.gis.server.catalog.ServicesDirectory has a get(name, folder=None) method that "returns a single service in a folder". I have been unable to get that to work. Similarly, the arcgis.gis.server.DataStoreManager has a get(path) that "Retrieves the data item object at the given path... None if not found." Can't get that to work either.

These are only two examples. I've tried other methods in other submodules with varying success and have come to the conclusion that there is just something I am fundamentally not understanding about how to work with those submodules. I should note, that I am not trying to utilize any that are specifially identified as ones that "should not be created by a user".

So, I'm providing some example code and results (below) illustrating my two examples above, trying to use the ServicesDirectory and DataStoreManager, specifically, their get() methods. I've included prints() detailing some fairly specific items that are throwing me off too but, generally, it seems as though I am getting access to some of the modules' functionality but not all...? I don't know.

If anyone can identify what it is that I am doing wrong here, I would greatly appreciate it. It's been a frustrating couple of days.

Cheers,
jtm

Source code (results are below this block)

1. The DataStoreManager's list() returns the same as the Server.datastores.list(), suggesting it's created properly, but the DataStoreManager's get() doesn't work (using two different interpretations of what is supposed to be passed for its path parameter.

2. The ServicesDirectory.list() doesn't even work the same as the Server.services.list(), suggesting I haven't even created it properly; and, of course, its get() doesn't return anything either. I highlight what appears to be a documentation conflict for instantiating the ServicesDirectory which may be the cause of my trouble but, as noted, when I used url_admin (rather than url, as shown in my code) I couldn't get access to anything through that object and just got error messages.

import arcgis.gis.server
my_cfg = {
    "domain": "my_site.com",
    "username": "admin_username",
    "password": "admin_password",
    "ds_folderShares_name": "datastore_name",
    "folder_name": "folder_name",
    "service_name": "service_name"
}

url = "https://" + my_cfg["domain"] + "/arcgis"
url_admin = url + "/admin"
url_token = url + "/tokens/generateToken"

my_server = arcgis.gis.server.Server(
    url=url_admin,
    token_url=url_token,
    username=my_cfg["username"],
    password=my_cfg["password"],
    all_ssl=True
)

my_ds_manager = arcgis.gis.server.DataStoreManager(
    url=my_server.url + "/data",
    gis=my_server
)

print("\nServer.datastores.list()................................................")

datastores = my_server.datastores.list()
for datastore in datastores:
    if datastore.properties["path"] == "/fileShares/" + my_cfg["ds_folderShares_name"]:
        print("Found datastore")
        break

print("\nDataStoreManager.list()...............................................")

datastores = my_ds_manager.list()
for datastore in datastores:
    if datastore.properties["path"] == "/fileShares/" + my_cfg["ds_folderShares_name"]:
        print("Found datastore")
        break

print("\nDataStoreManager.get()................................................")
print("- Passing 'path': DataStoreManager.get('/fileShares/datastore_name')")
print("  The fact that the datastore I just made can't be found using this method is one thing;")
print("  but the documentation suggests this should return 'None if not found.'")

my_ds = my_ds_manager.get("/fileShares/" +  my_cfg["ds_folderShares_name"])
print(my_ds)

print("- Passing the name of the datastore: DataStoreManager.get('datastore_name')")
print("  Again, the fact that the datastore can't be found using this method is one thing;")
print("  but this one at least responds with a 'None' when it can't find it.")

my_ds = my_ds_manager.get( my_cfg["ds_folderShares_name"])
print(my_ds)

print("\nInstantiating ServicesDirectory.......................................")
print("The documentation appears conflicting for this instantiation. It says the 'url' is ")
print("'The web address to the ArcGIS Server administration end point.' but the example shown is")
print("'https://mysite.com/arcgis'. The admin end point doesn't work, so I'm guessing this is")
print("just a documentation issue.")

my_services = arcgis.gis.server.catalog.ServicesDirectory(
    url=url,
    token_url=url_token,
    username=my_cfg["username"],
    password=my_cfg["password"],
    all_ssl=True
)

service_path = my_cfg["folder_name"] + "/" + my_cfg["service_name"]

print("\nServer.services.list()................................................")
services = my_server.services.list(my_cfg["folder_name"] )
for service in services:
    if service.properties["serviceName"] == my_cfg["service_name"]:
        print("Found service")
        break

print("\nServicesDirectory.list()..............................................")
services = my_services.list(my_cfg["folder_name"])
found = False
for service in services:
    print("Found a service in", my_cfg["folder_name"])
    found = True
    break

if not found:
    print(services)

print("\nServicesDirectory.get('service_name', 'folder_name')..................")
service = my_services.get(my_cfg["service_name"], my_cfg["folder_name"] )
print(service)

Results:

Server.datastores.list()................................................
Found datastore

DataStoreManager.list()...............................................
Found datastore

DataStoreManager.get()................................................
- Passing 'path': DataStoreManager.get('/fileShares/datastore_name')
  The fact that the datastore I just made can't be found using this method is one thing;
  but the documentation suggests this should return 'None if not found.'
  
status='error'
messages=['Item not found.']
code=500
   
- Passing the name of the datastore: DataStoreManager.get('datastore_name')
  Again, the fact that the datastore can't be found using this method is one thing;
  but this one at least responds with a 'None' when it can't find it.
  
None

Instantiating ServicesDirectory.......................................
The documentation appears conflicting for this instantiation. It says the 'url' is 
'The web address to the ArcGIS Server administration end point.' but the example shown is
'https://mysite.com/arcgis'. The admin end point doesn't work, so I'm guessing this is
a documentation issue.

Server.services.list()................................................
Found service

ServicesDirectory.list()..............................................
[]

ServicesDirectory.get('service_name', 'folder_name')..................
None

 

1 Solution

Accepted Solutions
JoanneMcGraw
Occasional Contributor III

Since I didn't get any information through this venue, I contacted ESRI Support.

Essentially, the get() functionality in the submodules is geared towards working with Enterprise and AGOL. It does not not accommodate stand-alone ArcGIS Servers.

In the end, the only way to "get" a service or a datastore is to use the arcgis.gis.server.Server submodule's list() functionality for the property in question and loop through the response to find the item of interest yourself (as shown in my example).

Just providing closure in case anyone else who might be wasting time trying to do the same thing.

Cheers,

jtm

View solution in original post

1 Reply
JoanneMcGraw
Occasional Contributor III

Since I didn't get any information through this venue, I contacted ESRI Support.

Essentially, the get() functionality in the submodules is geared towards working with Enterprise and AGOL. It does not not accommodate stand-alone ArcGIS Servers.

In the end, the only way to "get" a service or a datastore is to use the arcgis.gis.server.Server submodule's list() functionality for the property in question and loop through the response to find the item of interest yourself (as shown in my example).

Just providing closure in case anyone else who might be wasting time trying to do the same thing.

Cheers,

jtm