<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Python client for ArcGIS for Server in ArcAPI Questions</title>
    <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876603#M109</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Hi Larry,&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Thanks for the tip about urllib2. It is true that working with urllib2 is a bit awkward but exactly this awkwardness is removed if you use my arrest.py. More serious&amp;nbsp; issues I've had with urllib2 were related to requesting data from https with self signed certificate. I would prefer the requests package but I didn't want to add a dependency on an external package. Is requests part of core Python in 3.x?&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;I also looked at the script to collect stats of all services you referred to and translated it into a function below. I could not test it because I don't have admin credentials to any server I can reach at the moment. Can you check if it works?&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Filip.&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;"""Queries the logs and writes statistics on map service activity.
Modified version of script available on ArcGIS Help:
&lt;A class="jive-link-external-small" href="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/" rel="nofollow noopener noreferrer" target="_blank"&gt;http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/&lt;/A&gt;
To try this example, follow these steps:
1) Publish several map services (without defining tile caches for them).
2) Set the ArcGIS Server log level to FINE.
3) Make some draw requests of your services by adding them to ArcMap etc.
4) Run this script and examine the resulting text file.
"""

import httplib, urllib, json
import sys, time

def collect_services_statistics(server_name, output_file, username, password, hours=24, port=6080):
&amp;nbsp;&amp;nbsp;&amp;nbsp; """Query ArcGIS Server logs and write a summary of all map service draws.
&amp;nbsp;&amp;nbsp;&amp;nbsp; server_name -- e.g. 
&amp;nbsp;&amp;nbsp;&amp;nbsp; output_file -- path of the text file where the statistics should be written
&amp;nbsp;&amp;nbsp;&amp;nbsp; username, password -- credentials for the server admin rest interface
&amp;nbsp;&amp;nbsp;&amp;nbsp; hours=24 -- result will include summary for this number of the last hours
&amp;nbsp;&amp;nbsp;&amp;nbsp; port=6080 -- arcgis server port number
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; def assertJsonSuccess(data):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Check that the input JSON object is not an error object."""
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj = json.loads(data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if 'status' in obj and obj['status'] == "error":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "Error: JSON object returns an error. " + str(obj)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; def getToken(username, password, server_name, port):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Generate a token given username, password and the adminURL."""
&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Token URL is typically &lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://server[:port]/arcgis/admin/generateToken" rel="nofollow noopener noreferrer" target="_blank"&gt;http://server[:port]/arcgis/admin/generateToken&lt;/A&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tokenURL = "/arcgis/admin/generateToken"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # URL-encode the token parameters
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Connect to URL and post parameters
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn = httplib.HTTPConnection(server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.request("POST", tokenURL, params, headers)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read response
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response = httpConn.getresponse()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (response.status != 200):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Unable to fetch token, check the URL and try again.")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = response.read()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Check that data returned is not an error object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not assertJsonSuccess(data):&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Extract the toke from it
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; token = json.loads(data)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return token['token']
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; millisecondsToQuery = hours * 60 * 60 * 100 # 86400000 is 1 day
&amp;nbsp;&amp;nbsp;&amp;nbsp; hitDict = {}
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Get a token
&amp;nbsp;&amp;nbsp;&amp;nbsp; token = getToken(username, password, server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp; if token == "":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Could not generate a token using the credentials.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Construct URL to query the logs
&amp;nbsp;&amp;nbsp;&amp;nbsp; logQueryURL = "/arcgis/admin/logs/query" # is this going to work in future?
&amp;nbsp;&amp;nbsp;&amp;nbsp; startTime = int(round(time.time() * 1000))
&amp;nbsp;&amp;nbsp;&amp;nbsp; endTime = startTime - millisecondsToQuery
&amp;nbsp;&amp;nbsp;&amp;nbsp; logFilter = "{'services':'*','server':'*','machines':'*'}"
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; params = urllib.urlencode({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'level': 'FINE',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'startTime': startTime, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'endTime': endTime, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'filter':logFilter, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'token': token, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'f': 'json'
&amp;nbsp;&amp;nbsp;&amp;nbsp; })
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; headers = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Content-type": "application/x-www-form-urlencoded",
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Accept": "text/plain"
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Connect to URL and post parameters&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn = httplib.HTTPConnection(server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.request("POST", logQueryURL, params, headers)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read response
&amp;nbsp;&amp;nbsp;&amp;nbsp; response = httpConn.getresponse()
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (response.status != 200):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Error while querying logs.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = response.read()


&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Check that data returned is not an error object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not assertJsonSuccess(data):&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Error returned by operation. " + data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Deserialize response into Python object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataObj = json.loads(data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()


&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Need these to calculate average draw time for an ExportMapImage call
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mapDraws = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalDrawTime = 0 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Iterate over messages&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for item in dataObj["logMessages"]:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if item["message"] == "End ExportMapImage":

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elapsed = float(item["elapsed"])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keyCheck = item["source"]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if keyCheck in hitDict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats = hitDict[keyCheck]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats[0] += 1 # Add 1 to tally of hits
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats[1] += elapsed # Add elapsed time to total elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Add key with one hit and total elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hitDict[keyCheck] = [1, elapsed]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Open text file and write header line&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with open(output_file, "w") as summaryFile:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; header = "Service,Number of hits,Average seconds per draw\n"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; summaryFile.write(header)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read through dictionary and write totals into file 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for key in hitDict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Calculate average elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalDraws = hitDict[key][0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalElapsed = hitDict[key][1]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; avgElapsed = 0

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if totalDraws &amp;gt; 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Elapsed time divided by hits
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; avgElapsed = (1.0 * (totalElapsed / totalDraws))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Construct and write the comma-separated line&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; line = key + "," + str(totalDraws) + "," + str(avgElapsed) + "\n"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; summaryFile.write(line)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return summaryFile
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
if __name__ == "__main__":
&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server_name = '&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://sampleserver5.arcgisonline.com" rel="nofollow noopener noreferrer" target="_blank"&gt;http://sampleserver5.arcgisonline.com&lt;/A&gt;&lt;SPAN&gt;'&lt;/SPAN&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; output_file = 'c:/temp/summary.csv'
&amp;nbsp;&amp;nbsp;&amp;nbsp; username, password = "that_is_what", "i_do_not_know"
&amp;nbsp;&amp;nbsp;&amp;nbsp; collect_services_statistics(server_name, output_file, username, password, hours=24, port=6080)
&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Sun, 12 Dec 2021 10:59:49 GMT</pubDate>
    <dc:creator>FilipKrál</dc:creator>
    <dc:date>2021-12-12T10:59:49Z</dc:date>
    <item>
      <title>Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876594#M100</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi all,&lt;/P&gt;&lt;P&gt;What do you think about this new module in arcapi? I called it '&lt;STRONG&gt;arrest.py&lt;/STRONG&gt;', for '&lt;STRONG&gt;Ar&lt;/STRONG&gt;cGIS &lt;STRONG&gt;REST&lt;/STRONG&gt; Python client'. It is a set of classes that allow you to interact with ArcGIS for Server REST API (only reading though). Check out the examples near the bottom (line 966 and below). The module has no dependencies so you can play with just the single python script.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://github.com/NERC-CEH/arcapi/blob/feature-arrest/arrest.py" title="https://github.com/NERC-CEH/arcapi/blob/feature-arrest/arrest.py"&gt;https://github.com/NERC-CEH/arcapi/blob/feature-arrest/arrest.py&lt;/A&gt;‌&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The module is in a new branch so far and I would love to get some feedback from you. Is it a good idea? Do you miss anything? Can you add anything?&lt;/P&gt;&lt;P&gt;I hope we can polish it and check it into master arcapi in couple of weeks.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Cheers,&lt;/P&gt;&lt;P&gt;Filip.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 06 Aug 2014 18:29:35 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876594#M100</guid>
      <dc:creator>FilipKrál</dc:creator>
      <dc:date>2014-08-06T18:29:35Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876595#M101</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Filip,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanx for sharing. I will look into it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Kind regards, Xander&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 06 Aug 2014 21:39:08 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876595#M101</guid>
      <dc:creator>XanderBakker</dc:creator>
      <dc:date>2014-08-06T21:39:08Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876596#M102</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks, Filip,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;nice idea.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Do you think if it would be good to integrate / build a Python module, which also will go through all GIS services and collect &lt;SPAN style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;"&gt;service statistics from ArcGIS Server REST 'logs' and export into Excel or SCV file?&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt;&lt;SPAN style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;"&gt;Maybe, you have already this module. If so, please share...&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt;&lt;SPAN style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;"&gt;++++++++++++++&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;"&gt;The example is available at &lt;A href="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/" title="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/"&gt;ArcGIS Help (10.2, 10.2.1, and 10.2.2)&lt;/A&gt; &lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 15 Sep 2014 05:54:04 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876596#M102</guid>
      <dc:creator>larryzhang</dc:creator>
      <dc:date>2014-09-15T05:54:04Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876597#M103</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;it is an example with the chart in the report&lt;IMG alt="logs statistics.PNG" class="jive-image image-1" src="/legacyfs/online/12468_logs statistics.PNG" style="width: 620px; height: 337px;" /&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 15 Sep 2014 07:40:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876597#M103</guid>
      <dc:creator>larryzhang</dc:creator>
      <dc:date>2014-09-15T07:40:25Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876598#M104</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Oh, thanks for the tip, Larry. The element of authentication makes it slightly more complex but I'll consider it if I can make a nice simple function out of it.&lt;/P&gt;&lt;P&gt;F.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 20 Sep 2014 21:20:48 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876598#M104</guid>
      <dc:creator>FilipKrál</dc:creator>
      <dc:date>2014-09-20T21:20:48Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876599#M105</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi &lt;A href="https://community.esri.com/migrated-users/20184"&gt;larry zhang&lt;/A&gt;‌, you seem to be able to use the code you referred to but I couldn't make it work.&lt;/P&gt;&lt;P&gt;What version of ArcGIS Server did you use? I thought the /arcgis/admin end point has been changed. Anyhow, I suppose general users don't have credentials for it anyway.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I tried to experiment with the following 10.2.x servers.&lt;/P&gt;&lt;P&gt;&lt;A href="http://sampleserver5.arcgisonline.com/arcgis/rest/" title="http://sampleserver5.arcgisonline.com/arcgis/rest/"&gt;http://sampleserver5.arcgisonline.com/arcgis/rest/&lt;/A&gt; (I have no credentials to this one but I couldn't even find the end points)&lt;/P&gt;&lt;P&gt;&lt;A href="https://datahub.esriuk.com/arcgis/rest/" title="https://datahub.esriuk.com/arcgis/rest/"&gt;https://datahub.esriuk.com/arcgis/rest/&lt;/A&gt; (I managed to generate token from &lt;A href="https://datahub.esriuk.com/arcgis/tokens/generateToken" title="https://datahub.esriuk.com/arcgis/tokens/generateToken"&gt;https://datahub.esriuk.com/arcgis/tokens/generateToken&lt;/A&gt;‌ but I cannot see any admin interface.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here is the function I tried to get token with. Hopefully I'll figure out some way of using it to access secured services with arcapi/arrest.py.&lt;/P&gt;&lt;PRE __default_attr="python" __jive_macro_name="code" class="jive_macro_code jive_text_macro _jivemacro_uid_14115897628831653" jivemacro_uid="_14115897628831653"&gt;
&lt;P&gt;import urllib2&lt;/P&gt;
&lt;P&gt;import urllib&lt;/P&gt;
&lt;P&gt;import json&lt;/P&gt;
&lt;P&gt;from contextlib import closing&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;def generateToken(url, username, password):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; req = urllib2.Request(url, params, headers)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; with closing(urllib2.urlopen(req)) as res:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dta = res.read()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; jsn = json.loads(dta)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return jsn.get('token')&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;username,password = '***', '***'&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;url = "&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="https://datahub.esriuk.com/arcgis/tokens/generateToken" rel="nofollow" target="_blank"&gt;https://datahub.esriuk.com/arcgis/tokens/generateToken&lt;/A&gt;&lt;SPAN&gt;"&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;token = generateToken(url, username, password)&lt;/P&gt;
&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Filip.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 24 Sep 2014 20:22:52 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876599#M105</guid>
      <dc:creator>FilipKrál</dc:creator>
      <dc:date>2014-09-24T20:22:52Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876600#M106</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Filip,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;ESRI in addition also produces their own Python API for accessing REST Services from ArcGIS Server and ArcGIS Online.&amp;nbsp; The API for ArcGIS Server can be found here:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://github.com/esri/arcrest" title="https://github.com/esri/arcrest"&gt;Esri/ArcREST · GitHub&lt;/A&gt; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The API for ArcGIS Portal (ArcGIS Online) can be found here:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://github.com/esri/portalpy" title="https://github.com/esri/portalpy"&gt;Esri/portalpy · GitHub&lt;/A&gt; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If you find something that ArcREST cannot do that arrest.py does, it may be beneficial to submit it to the ESRI repository.&amp;nbsp; In addition, you may also want to consider a multitude of possible APIs to access REST services as I have found that one will support things that the others will not.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I hope this helps!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Sep 2014 00:05:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876600#M106</guid>
      <dc:creator>AlexanderNohe1</dc:creator>
      <dc:date>2014-09-25T00:05:44Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876601#M107</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&lt;SPAN&gt;Thanks a lot, dear all, Greeting, Filip, pls refer to the blog at &lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://isbullsh.it/2012/06/Rest-api-in-python/" rel="nofollow" target="_blank"&gt;http://isbullsh.it/2012/06/Rest-api-in-python/&lt;/A&gt;&lt;SPAN&gt; , which indicates that urllib2 is not right way to go... Hi, Alex, It looks that the links like &lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="https://github.com/esri/arcrest" rel="nofollow" target="_blank"&gt;https://github.com/esri/arcrest&lt;/A&gt;&lt;SPAN&gt; not working to me. Not sure why?&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 28 Sep 2014 05:17:58 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876601#M107</guid>
      <dc:creator>larryzhang</dc:creator>
      <dc:date>2014-09-28T05:17:58Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876602#M108</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&lt;BR /&gt;Filip,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Can you check the example codes to collect statistics of all services, which is available at &lt;A href="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/" title="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/"&gt;ArcGIS Help (10.2, 10.2.1, and 10.2.2)&lt;/A&gt;&amp;nbsp; ?&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 28 Oct 2014 07:11:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876602#M108</guid>
      <dc:creator>larryzhang</dc:creator>
      <dc:date>2014-10-28T07:11:13Z</dc:date>
    </item>
    <item>
      <title>Re: Python client for ArcGIS for Server</title>
      <link>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876603#M109</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Hi Larry,&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Thanks for the tip about urllib2. It is true that working with urllib2 is a bit awkward but exactly this awkwardness is removed if you use my arrest.py. More serious&amp;nbsp; issues I've had with urllib2 were related to requesting data from https with self signed certificate. I would prefer the requests package but I didn't want to add a dependency on an external package. Is requests part of core Python in 3.x?&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;I also looked at the script to collect stats of all services you referred to and translated it into a function below. I could not test it because I don't have admin credentials to any server I can reach at the moment. Can you check if it works?&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;Filip.&lt;/P&gt;&lt;P style="font-size: 14.3999996185303px;"&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;"""Queries the logs and writes statistics on map service activity.
Modified version of script available on ArcGIS Help:
&lt;A class="jive-link-external-small" href="http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/" rel="nofollow noopener noreferrer" target="_blank"&gt;http://resources.arcgis.com/en/help/main/10.2/index.html#/Example_Derive_map_service_statistics_from_the_ArcGIS_Server_logs/0154000005vw000000/&lt;/A&gt;
To try this example, follow these steps:
1) Publish several map services (without defining tile caches for them).
2) Set the ArcGIS Server log level to FINE.
3) Make some draw requests of your services by adding them to ArcMap etc.
4) Run this script and examine the resulting text file.
"""

import httplib, urllib, json
import sys, time

def collect_services_statistics(server_name, output_file, username, password, hours=24, port=6080):
&amp;nbsp;&amp;nbsp;&amp;nbsp; """Query ArcGIS Server logs and write a summary of all map service draws.
&amp;nbsp;&amp;nbsp;&amp;nbsp; server_name -- e.g. 
&amp;nbsp;&amp;nbsp;&amp;nbsp; output_file -- path of the text file where the statistics should be written
&amp;nbsp;&amp;nbsp;&amp;nbsp; username, password -- credentials for the server admin rest interface
&amp;nbsp;&amp;nbsp;&amp;nbsp; hours=24 -- result will include summary for this number of the last hours
&amp;nbsp;&amp;nbsp;&amp;nbsp; port=6080 -- arcgis server port number
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; def assertJsonSuccess(data):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Check that the input JSON object is not an error object."""
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj = json.loads(data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if 'status' in obj and obj['status'] == "error":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "Error: JSON object returns an error. " + str(obj)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; def getToken(username, password, server_name, port):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Generate a token given username, password and the adminURL."""
&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Token URL is typically &lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://server[:port]/arcgis/admin/generateToken" rel="nofollow noopener noreferrer" target="_blank"&gt;http://server[:port]/arcgis/admin/generateToken&lt;/A&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tokenURL = "/arcgis/admin/generateToken"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # URL-encode the token parameters
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Connect to URL and post parameters
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn = httplib.HTTPConnection(server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.request("POST", tokenURL, params, headers)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read response
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response = httpConn.getresponse()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (response.status != 200):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Unable to fetch token, check the URL and try again.")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = response.read()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Check that data returned is not an error object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not assertJsonSuccess(data):&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Extract the toke from it
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; token = json.loads(data)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return token['token']
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; millisecondsToQuery = hours * 60 * 60 * 100 # 86400000 is 1 day
&amp;nbsp;&amp;nbsp;&amp;nbsp; hitDict = {}
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Get a token
&amp;nbsp;&amp;nbsp;&amp;nbsp; token = getToken(username, password, server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp; if token == "":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Could not generate a token using the credentials.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Construct URL to query the logs
&amp;nbsp;&amp;nbsp;&amp;nbsp; logQueryURL = "/arcgis/admin/logs/query" # is this going to work in future?
&amp;nbsp;&amp;nbsp;&amp;nbsp; startTime = int(round(time.time() * 1000))
&amp;nbsp;&amp;nbsp;&amp;nbsp; endTime = startTime - millisecondsToQuery
&amp;nbsp;&amp;nbsp;&amp;nbsp; logFilter = "{'services':'*','server':'*','machines':'*'}"
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; params = urllib.urlencode({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'level': 'FINE',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'startTime': startTime, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'endTime': endTime, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'filter':logFilter, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'token': token, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'f': 'json'
&amp;nbsp;&amp;nbsp;&amp;nbsp; })
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; headers = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Content-type": "application/x-www-form-urlencoded",
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Accept": "text/plain"
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Connect to URL and post parameters&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn = httplib.HTTPConnection(server_name, port)
&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.request("POST", logQueryURL, params, headers)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read response
&amp;nbsp;&amp;nbsp;&amp;nbsp; response = httpConn.getresponse()
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (response.status != 200):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Error while querying logs.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = response.read()


&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Check that data returned is not an error object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not assertJsonSuccess(data):&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception("Error returned by operation. " + data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Deserialize response into Python object
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataObj = json.loads(data)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; httpConn.close()


&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Need these to calculate average draw time for an ExportMapImage call
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mapDraws = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalDrawTime = 0 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Iterate over messages&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for item in dataObj["logMessages"]:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if item["message"] == "End ExportMapImage":

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elapsed = float(item["elapsed"])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keyCheck = item["source"]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if keyCheck in hitDict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats = hitDict[keyCheck]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats[0] += 1 # Add 1 to tally of hits
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stats[1] += elapsed # Add elapsed time to total elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Add key with one hit and total elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hitDict[keyCheck] = [1, elapsed]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Open text file and write header line&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with open(output_file, "w") as summaryFile:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; header = "Service,Number of hits,Average seconds per draw\n"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; summaryFile.write(header)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Read through dictionary and write totals into file 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for key in hitDict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Calculate average elapsed time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalDraws = hitDict[key][0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalElapsed = hitDict[key][1]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; avgElapsed = 0

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if totalDraws &amp;gt; 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #Elapsed time divided by hits
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; avgElapsed = (1.0 * (totalElapsed / totalDraws))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Construct and write the comma-separated line&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; line = key + "," + str(totalDraws) + "," + str(avgElapsed) + "\n"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; summaryFile.write(line)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return summaryFile
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
if __name__ == "__main__":
&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server_name = '&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://sampleserver5.arcgisonline.com" rel="nofollow noopener noreferrer" target="_blank"&gt;http://sampleserver5.arcgisonline.com&lt;/A&gt;&lt;SPAN&gt;'&lt;/SPAN&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; output_file = 'c:/temp/summary.csv'
&amp;nbsp;&amp;nbsp;&amp;nbsp; username, password = "that_is_what", "i_do_not_know"
&amp;nbsp;&amp;nbsp;&amp;nbsp; collect_services_statistics(server_name, output_file, username, password, hours=24, port=6080)
&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 12 Dec 2021 10:59:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcapi-questions/python-client-for-arcgis-for-server/m-p/876603#M109</guid>
      <dc:creator>FilipKrál</dc:creator>
      <dc:date>2021-12-12T10:59:49Z</dc:date>
    </item>
  </channel>
</rss>

