Get a list of every Layer, in every Service, in every Folder in an ArcGIS REST endpoint - python-3.x

I have two ArcGIS REST endpoints for which I am trying to get a list of every layer:
https://rdgdwe.sc.egov.usda.gov/arcgis/rest/services
https://services1.arcgis.com/RLQu0rK7h4kbsBq5/ArcGIS/rest/services
These are not my organization's endpoints so I don't have access to them internally. At each of these endpoints there can be folders, services, and layers, or just services and layers.
My goal is to get a list of all layers. So far I have tried:
endpoints=(["https://rdgdwe.sc.egov.usda.gov/arcgis/rest/services",
"https://services1.arcgis.com/RLQu0rK7h4kbsBq5/ArcGIS/rest/services"])
for item in endpoints:
reqs = requests.get(item, verify=False)
# used this verify because otherwise I get an SSL error for endpoints[0]
soup =BeautifulSoup(reqs.text, 'html.parser')
layers = []
for link in soup.find_all('a'):
print(link.get('href'))
layers.append(link)
However this doesn't account for the variable nested folders/services/layers or services/layer schemas, and it doesn't seem to be fully appending to my layers list.
I'm thinking I could also go the JSON route and append ?f=psjon . So for example:
https://rdgdwe.sc.egov.usda.gov/arcgis/rest/services/?f=pjson would get me the folders
https://rdgdwe.sc.egov.usda.gov/arcgis/rest/services/broadband/?f=pjson would get me all the services in the broadband folder
and
https://rdgdwe.sc.egov.usda.gov/arcgis/rest/services/broadband/CDC_5yr_OpioidOverDoseDeaths_2016/MapServer?f=pjson would get me the CDC_OverDoseDeathsbyCounty2016_5yr layer in the first service (CDC_5yr_OpioidOverDoseDeaths_2016) in the broadband folder.
Any help is appreciated. I put this here vs in the GIS stack exchange as it seems a more python question than geospatial.

I don't really agree this is a Python question because there doesn't seem to be any issue with how to use the various Python libraries. The main issue appears to be how do you work with Esri's REST API. Seeing that Esri is very much a GIS company and their REST API is very much a GIS API, I think GIS StackExchange would have been a better forum for the question.
But, since we are here now....
If you are going to continue working with Esri's REST API with Python, I strongly encourage you to read up on Esri's ArcGIS API for Python. At its core, the ArcGIS API for Python is a Python wrapper for working with Esri's REST API. Unless someone has very basic needs, rolling one's own Python code for Esri's REST API isn't time well spent.
If you are set on rolling your own, I strongly encourage you to read Get started -- ArcGIS REST APIs | ArcGIS Developers. The documentation describes the structure of the REST API, syntax, and it includes some examples.
The following isn't pretty, it is meant more to help you connect the dots when reading Esri's documentation. That said, it will give you a list of Map Services on an ArcGIS Server site and the layers for those services.
import json
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
services = {}
services_endpoint = "https://fqdn/arcgis/rest/services"
req = requests.get(f"{services_endpoint}?f=json", verify=False)
svcs_root = json.loads(req.text)
for fld in svcs_root['folders']:
req = requests.get(f"{services_endpoint}/{fld}?f=json", verify=False)
svcs_fld = json.loads(req.text)
for svc in svcs_fld['services']:
if svc['type'] not in ('MapServer'): continue
req = requests.get(f"{services_endpoint}/{svc['name']}/{svc['type']}?f=json", verify=False)
svc_def = json.loads(req.text)
services.update({svc['name']:{'type':svc['type'], 'layers':svc_def['layers']}})
for svc in svcs_root['services']:
if svc['type'] not in ('MapServer'): continue
req = requests.get(f"{services_endpoint}/{svc['name']}/{svc['type']}?f=json", verify=False)
svc_def = svc = json.loads(req.text)
services.update({svc['name']:{'type':svc['type'], 'layers':svc_def['layers']}})

As part of developing GISsurfer (https://gissurfer.com) I was faced with that exact problem but for any ArcGIS server that did not require login creds. My solution was to write PHP code to 'walk the tree' to find all services.

Related

Unable to fetch the jira cloud assets through atlassian-python-api

I am working on a Atlassian Jira cloud product. I have a requirement to get the details of Jira cloud assets and update a field with some specific key-value pair. To achieve same, I have chosen python api to interact with Atlassian jira cloud and do those changes.
But, I am unable to access jira cloud assets using the atlassian-python-api which I have got from the https://pypi.org/project/atlassian-python-api/. Even I tried with different versions of it to achieve same.
Here is my sample code.
from atlassian import Jira
# Enter your Jira Cloud site URL and API token
JIRA_URL = "https://<your-domain>.atlassian.net"
JIRA_API_TOKEN = "<your-api-token>"
# Initialize the Jira API client
jira = Jira(
url=JIRA_URL,
username="",
password="",
cloud=True,
api_token=JIRA_API_TOKEN,
)
# Fetch a list of all assets
assets = jira.assets().search("")
# Print the asset details in a tabular format
print("Asset ID\tAsset Type\tName\tDescription")
for asset in assets:
print(f"{asset['id']}\t{asset['type']}\t{asset['name']}\t{asset['description']}")
But, getting below error.
assets = jira.assets().search("")
AttributeError: 'Jira' object has no attribute 'assets'
After that, I tried to fetch with different components like - jira.jira_service_desk().get_all_assets() , jira.get_all_assets() and jira.cloud.asset_management.get_all_assets() . But, everytime I am facing respective issue like 'Jira' object has no attribute <>`.
Could you please suggest a way make the bulk operations on jira-cloud-assets.
FYI, Even I went with the atlassian provided api - https://developer.atlassian.com/cloud/assetsapi/rest/api-group-assets/#api-asset-get - It also doesn't help to get them.
Expecting a solution to make write operations on Jira-Cloud assets.

How to filter Google Cloud Instances using google-compute-engine python client?

I am using
Package Version
------------------------ ---------
google-api-core 2.0.1
google-auth 2.0.2
google-cloud-compute 0.5.0
google-compute-engine 2.8.13
to retrieve google cloud instances data. I was referring to the docs to get aggregated list of instances. I wasnt able to filter instances based on tags of the compute VM instances. Is there a particular way to do it using python as there is no particular mention about it in the documentation. ?
Please include your code.
You should be able to apply a Filter to AggregatedListInstancesRequest and you should be able to specify labels, see Filtering searches using labels. I'm confident (!?) the API is consistent.
The documentation refers to the filter query parameter. I didn't manage to get it to work with tags. But you can still list all the instances and filter it directly.
In the example below I'm looking for the gke-nginx-1-cluster-846d7440-node tag.
from googleapiclient import discovery
from google.oauth2 import service_account
scopes = ['https://www.googleapis.com/auth/compute']
sa_file = 'alon-lavian-0474ca3b9309.json'
credentials = service_account.Credentials.from_service_account_file(sa_file, scopes=scopes)
service = discovery.build('compute', 'v1', credentials=credentials)
project = 'alon-lavian'
zone = 'us-central1-a'
request = service.instances().list(project=project, zone=zone)
while request is not None:
response = request.execute()
for instance in response['items']:
if 'gke-nginx-1-cluster-846d7440-node' in instance['tags']['items']:
print(instance)
request = service.instances().list_next(previous_request=request, previous_response=response)

What is suggested method to get service versions

What is the best way to get list of service versions in google app engine in flex env? (from service instance in Python 3). I want to authenticate using service account json keys file. I need to find currently default version (with most of traffic).
Is there any lib I can use like googleapiclient.discovery, or google.appengine.api.modules? Or I should build it from scratches and request REST api on apps.services.versions.list using oauth? I couldn't not find any information in google docs..
https://cloud.google.com/appengine/docs/standard/python3/python-differences#cloud_client_libraries
Finally I was able to solve it. Simple things on GAE became big problems..
SOLUTION:
I have path to service_account.json set in GOOGLE_APPLICATION_CREDENTIALS env variable. Then you can use google.auth.default
from googleapiclient.discovery import build
import google.auth
creds, project = google.auth.default(scopes=['https://www.googleapis.com/auth/cloud-platform.read-only'])
service = build('appengine', 'v1', credentials=creds, cache_discovery=False)
data = service.apps().services().get(appsId=APPLICATION_ID, servicesId=SERVICE_ID).execute()
print data['split']['allocations']
Return value is allocations dictionary with versions as keys and traffic percents in values.
All the best!
You can use Google's Python Client Library to interact with the Google App Engine Admin API, in order to get the list of a GAE service versions.
Once you have google-api-python-client installed, you might want to use the list method to list all services in your application:
list(appsId, pageSize=None, pageToken=None, x__xgafv=None)
The arguments of the method should include the following:
appsId: string, Part of `name`. Name of the resource requested. Example: apps/myapp. (required)
pageSize: integer, Maximum results to return per page.
pageToken: string, Continuation token for fetching the next page of results.
x__xgafv: string, V1 error format. Allowed values: v1 error format, v2 error format
You can find more information on this method in the link mentioned above.

Using Python with pygerrit2 Library to make API call to Gerrit From Power BI Desktop

I've recently started using power BI. I am trying to get data from Gerrit Rest Api Using Python. The following code works fine when I run it locally on my machine.
from requests.auth import HTTPDigestAuth
from pygerrit2.rest import GerritRestAPI
auth = HTTPDigestAuth('####', '##############')
rest = GerritRestAPI(url='https://gerrit.****.com', auth=auth)
changes = rest.get("/projects/?d")
In Power BI it doesn't cause any errors, but there are no results in the resulting Navigator Pane.
This seems to be the same problem outlined in this forum https://community.powerbi.com/t5/Desktop/Load-JSON-as-source-via-Python/td-p/485375
But I don't see any real resolution.
Is there any other way I can accomplish this?
I think you must change from:
rest = GerritRestAPI(url='https://gerrit.****.com', auth=auth)
To:
rest = GerritRestAPI(url='https://gerrit.****.com/a', auth=auth)
Without the "/a" the authentication doesn't work and you're getting an empty project list.
See more details about the authentication in the Gerrit documentation here.

GET / POST using Clarion

I have Clarion 9 app that I want to be able to communicate with HTTP servers. I come from PHP background. I have 0 idea on what to do.
What I wish to be able to do:
Parse JSON data and convert QUEUE data to JSON [Done]
Have a global variable like 'baseURL' that points to e.g. http://localhost.com [Done]
Call functions such apiConnection.get('/users') would return me the contents of the page. [I'm stuck here]
apiConnection.post('/users', myQueueData) would POST myQueueData contents.
I tried using winhttp.dll by reading it from LibMaker but it didn't read it. Instead, I'm now using wininet.dll which LibMaker successfully created a .lib file for it.
I'm currently using the PROTOTYPE procedures from this code on GitHub https://gist.github.com/ddur/34033ed1392cdce1253c
What I did was include them like:
SimpleApi.clw
PROGRAM
INCLUDE('winInet.equ')
ApiLog QUEUE, PRE(log)
LogTitle STRING(10)
LogMessage STRING(50)
END
MAP
INCLUDE('winInetMap.clw')
END
INCLUDE('equates.clw'),ONCE
INCLUDE('DreamyConnection.inc'),ONCE
ApiConnection DreamyConnection
CODE
IF DreamyConnection.initiateConnection('http://localhost')
ELSE
log:LogTitle = 'Info'
log:LogMessage = 'Failed'
ADD(apiLog)
END
But the buffer that winInet's that uses always returns 0.
I have created a GitHub repository https://github.com/spacemudd/clarion-api with all the code to look at.
I'm really lost in this because I can't find proper documentation of Clarion.
I do not want a paid solution.
It kind of depends which version of Clarion you have.
Starting around v9 they added ClaRunExt which provides this kind of functionality via .NET Interop.
From the help:
Use HTTP or HTTPS to download web pages, or any other type of file. You can also post form data to web servers. Very easy way to send HTTP web requests (and receive responses) to Web Servers, REST Web Services, or standard Web Services, with the most commonly used HTTP verbs; POST, GET, PUT, and DELETE.
Otherwise, search the LibSrc\ directory for "http" and you will get an idea of what is already there. abapi.inc for example, appears to provide a wrapper around wininet.lib.

Resources