Does anyone know how to search services, such as a Feature Layer, on a standalone ArcGIS server through ArcGIS API for Python? For example, I am trying to access and list services published at https://geoappext.nrcan.gc.ca/arcgis/rest/services/ by using gis.content.search but with no luck.
I have been using this code:
gis = GIS()
items = gis.content.search(query="NRCAN",item_type="Feature Layer", max_items=10000)
I do get some of the services back as items but 'search' casts a too wide net, grabbing services that are not on that server as well, which then due to the max_items cap of 10,000 results in many of the services on the stated server not caught and returned as items. I would like to have only the feature layer services on the stated server returned as items, no other services.
Any help would be much appreciated, thank you.
Solved! Go to Solution.
What you want is the ServicesDirectory class. With it, you can iterate over the server's folders and return the services.
There is a "find" method, but repeated tests don't return reliable results. There's also a "report" method that returns the services in a folder as a Pandas DataFrame, which sounds ideal, but I haven't gotten that to return anything useful, either.
In any case, you can simply iterate over the entire server and populate a list of services, then search that.
from arcgis.gis.server.catalog import ServicesDirectory
s = ServicesDirectory('https://geoappext.nrcan.gc.ca/arcgis/rest/services/')
full_list = []
for f in s.folders:
for svc in s.list(folder=f):
full_list.append(svc)
full_list
Returns
[<MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT_TXT_3857/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT_TXT_3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBME_CBCE_HS_RO_3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT_CBCT_GEOM_3857/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT_CBCT_GEOM_3978/MapServer">,
...
You can then search through that list for specific items.
Bonus points: use list comprehension to compile the list in one line:
[svc for sublist in [s.list(f) for f in s.folders] for svc in sublist]
Perfect! Thank you very much, Josh, this is exactly what I was looking for. I spent so much time this morning to find a solution so this is greatly appreciated! I did play with the ServiceDirectory class but I obviously wasn't using the right syntax.
Thanks again!
Tomislav
What you want is the ServicesDirectory class. With it, you can iterate over the server's folders and return the services.
There is a "find" method, but repeated tests don't return reliable results. There's also a "report" method that returns the services in a folder as a Pandas DataFrame, which sounds ideal, but I haven't gotten that to return anything useful, either.
In any case, you can simply iterate over the entire server and populate a list of services, then search that.
from arcgis.gis.server.catalog import ServicesDirectory
s = ServicesDirectory('https://geoappext.nrcan.gc.ca/arcgis/rest/services/')
full_list = []
for f in s.folders:
for svc in s.list(folder=f):
full_list.append(svc)
full_list
Returns
[<MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT_TXT_3857/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBCT_TXT_3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBME_CBCE_HS_RO_3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT3978/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT_CBCT_GEOM_3857/MapServer">, <MapImageLayer url:"https://geoappext.nrcan.gc.ca/arcgis/rest/services//BaseMaps/CBMT_CBCT_GEOM_3978/MapServer">,
...
You can then search through that list for specific items.
Bonus points: use list comprehension to compile the list in one line:
[svc for sublist in [s.list(f) for f in s.folders] for svc in sublist]
Perfect! Thank you very much, Josh, this is exactly what I was looking for. I spent so much time this morning to find a solution so this is greatly appreciated! I did play with the ServiceDirectory class but I obviously wasn't using the right syntax.
Thanks again!
Tomislav