Start Stop Map Service arcpy

15819
24
Jump to solution
11-17-2016 10:56 AM
jaykapalczynski
Frequent Contributor

Is there a way to stop and start a map/feature service in ArcGIS Server via python?

1 Solution

Accepted Solutions
BlakeTerhune
MVP Regular Contributor

Lots of useful info has already been posted, it can just be a chore to sort through it to get exactly what you need. This is compounded by the fact that there are always many different ways to do the same thing and makes it extra confusing. Here is the Python code I use to start/stop a single service. It uses all built-in modules so there's no need to install anything extra.

"""Based on these 2014 resources by Kevin Hibma (Product Engineer at Esri):
ArcGIS Server Administration Toolkit - 10.1+
    http://www.arcgis.com/home/item.html?id=12dde73e0e784e47818162b4d41ee340
AdministeringArcGISServerwithPython_DS2014
    https://github.com/arcpy/AdministeringArcGISServerwithPython_DS2014

Other related information can be found in the ArcGIS Help Resources
  Scripting with the ArcGIS REST API
      http://resources.arcgis.com/en/help/main/10.2/0154/0154000005r1000000.htm
"""

# Required imports
import urllib
import urllib2
import json
import contextlib  ## context manager to clean up resources when exiting a 'with' block

def main():  ## Entry point into the script
    # Local variables
    ## Authentication
    adminUser = r"someuser"
    adminPass = r"passw0rd"
    ## ArcGIS Server Machine
    server = "SERVERNAME"
    port = "6080"
    ## Services ("FolderName/ServiceName.ServiceType")
    svc = "SampleWorldCities.MapServer"

    try:
        # Get ArcGIS Server token
        expiration = 60  ## Token timeout in minutes; default is 60 minutes.
        token = getToken(adminUser, adminPass, server, port, expiration)

        # Perform action on service
        action = "start"  ## "start" or "stop"
        jsonOuput = serviceStartStop(server, port, svc, action, token)
        ## Validate JSON object result
        if jsonOuput['status'] == "success":
            print "{} {} successful".format(action.title(), str(svc))
        else:
            print "Failed to {} {}".format(action, str(svc))
            raise Exception(jsonOuput)

    except Exception, err:
        print err


# Function to generate a token from ArcGIS Server; returns token.
## http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000000m5000000.htm
def getToken(adminUser, adminPass, server, port, expiration):
    # Build URL
    url = "http://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)

    # Encode the query string
    query_dict = {
        'username': adminUser,
        'password': adminPass,
        'expiration': str(expiration),  ## Token timeout in minutes; default is 60 minutes.
        'client': 'requestip'
    }
    query_string = urllib.urlencode(query_dict)

    try:
        # Request the token
        with contextlib.closing(urllib2.urlopen(url, query_string)) as jsonResponse:
            getTokenResult = json.loads(jsonResponse.read())
            ## Validate result
            if "token" not in getTokenResult or getTokenResult == None:
                raise Exception("Failed to get token: {}".format(getTokenResult['messages']))
            else:
                return getTokenResult['token']

    except urllib2.URLError, e:
        raise Exception("Could not connect to machine {} on port {}\n{}".format(server, port, e))


# Function to start or stop a service on ArcGIS Server; returns JSON response.
## http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000001s6000000.htm
def serviceStartStop(server, port, svc, action, token):
    # Build URL
    url = "http://{}:{}/arcgis/admin".format(server, port)
    requestURL = url + "/services/{}/{}".format(svc, action)

    # Encode the query string
    query_dict = {
        "token": token,
        "f": "json"
    }
    query_string = urllib.urlencode(query_dict)

    # Send the server request and return the JSON response
    with contextlib.closing(urllib.urlopen(requestURL, query_string)) as jsonResponse:
        return json.loads(jsonResponse.read())


if __name__ == '__main__':
    main()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

24 Replies
jaykapalczynski
Frequent Contributor

NOTE: I am trying to do this from a different server from where AGS is installed.  

I have to stop a service to run some code on the FC in SDe.  Then restart the Service.

Can I call a python script on another server?  

Can I do this via arcpy?

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

yes.

The "released" version of the toolbox is

Downloadable tools for ArcGIS Server administration | ArcGIS Blog 

direct link to download page... http://www.arcgis.com/home/item.html?id=12dde73e0e784e47818162b4d41ee340 

Might want to look at this thread too

AGS admin scripting help 

I have done some additional work on a copy locally that reads the credentials from a .ini file so it doesn't echo the admin credentials in the results tab.  Also, I know Kevin Hibma‌ is working on a new version, but haven't heard any release date (I think it's a, "as I have time" project)

edit:  btw, my modified toolset allows me to search the running services that are using a datasource so I shut down all those.  Then I totally replace the fgdb before starting those services back up.  I will eventually post it, but not ready yet.

jaykapalczynski
Frequent Contributor

Was looking into the AGS Admin link...saw the below.

Not sure where to download all the scripts and stuff from the Zip file too?

Can I specify a single Service?

Pretty confused right now.....

def stopStartServices(server, port, adminUser, adminPass, stopStart, serviceList, token=None): 
''' Function to stop, start or delete a service.
Requires Admin user/password, as well as server and port (necessary to construct token if one does not exist).
stopStart = Stop|Start|Delete
serviceList = List of services. A service must be in the <name>.<type> notation
If a token exists, you can pass one in for use. 
''' 

# Get and set the token
if token is None: 
token = gentoken(server, port, adminUser, adminPass)

# modify the services(s) 
for service in serviceList:
op_service_url = "http://{}:{}/arcgis/admin/services/{}/{}?token={}&f=json".format(server, port, service, stopStart, token)
status = urllib2.urlopen(op_service_url, ' ').read()

if 'success' in status:
print (str(service) + " === " + str(stopStart))
else: 
print status

return
0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

If you download that admin toolbox, use the tool.  One you put in your server name port (usually 6080) and admin credentials, it should list ALL the services, where running or not.  That is why I'm modifying it.  Cause otherwise when you rerun it to start the services back up, it will include anything your checked to "stop" whether or not is was running before.

That might not make sense, but just run it so you get the GUI, and it should make more sense.

0 Kudos
BlakeTerhune
MVP Regular Contributor

my modified toolset allows me to search the running services that are using a datasource so I shut down all those.  Then I totally replace the fgdb before starting those services back up.  I will eventually post it, but not ready yet.

Looking forward to that!

RebeccaStrauch__GISP
MVP Emeritus

Blake, if you get anxious and want to take a look at my scripts, DM me.  The issue is I'm writeing/testing for an internal addin  and I have too much hardcoded (i.e. my .fgdb for example) for use in this addin.  But the functionality is there and working.  For GP services it actually has to read from the manifest.json for the service on the c: drive to see if it is being used.  Some of these things I still need to pull out to be separate functions....but off that project for a couple weeks right now.

0 Kudos
CallumSmith2
Occasional Contributor

Yes you can using the REST api.

See ArcGIS REST API 

cheers

Callum

jaykapalczynski
Frequent Contributor

So I only need one line of code?  

http://server:port/arcgis/admin/services/Maps/SeattleMap.MapServer/start

What about credentials etc. and the 100 lines of code in the previous posts.

0 Kudos
CallumSmith2
Occasional Contributor

Hi Jay

Not quite that simple. You will have to generate a token and pass that as part of the request. Are you familiar with making http/https requests with python? Have a look at the request module. If I have time today I will put together an example script.

cheers

Callum