Skip To Content

Scripting languages and the ArcGIS REST API

The ArcGIS REST API works with any scripting language that can make RESTful web service calls through HTTP and parse the responses. This includes Python, Java, JavaScript, PowerShell, C#, Ruby, Scala, Perl, and others.

The REST API examples in the ArcGIS Server Help use Python. However, the examples below show how you could write an equivalent script using a variety of languages. Each script starts the geometry service that is installed with ArcGIS Server.

Python

This script starts the geometry service using Python.

Starting a service requires administrative privileges, so a user name and password with administrator privileges must be supplied when running this script.

# Demonstrates how to start a service by starting the geometry service
# This service is included with every ArcGIS Server and is stopped by default

# For Http calls
import httplib, urllib, json

# For system tools
import sys

# For reading passwords without echoing
import getpass


# Defines the entry point into the script
def main(argv=None):
    # Print some info
    print
    print "This tool is a sample script that starts the Geometry service on a Server."
    print
    
    # Ask for admin/publisher user name and password
    username = raw_input("Enter user name: ")
    password = getpass.getpass("Enter password: ")

    # Ask for server name
    serverName = raw_input("Enter server name: ")
    serverPort = 6080
    
    # Get a token
    token = getToken(username, password, serverName, serverPort)
    if token == "":
        print "Could not generate a token with the username and password provided."
        return
    
    # Construct URL to start a service - as an example the Geometry service
    serviceStartURL = "/arcgis/admin/services/utilities/Geometry.GeometryServer/start"
    
    # This request only needs the token and the response formatting parameter 
    params = urllib.urlencode({'token': token, 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters    
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", serviceStartURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while attempting to start the service."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print "Error returned by operation. " + data
        else:
            print "Operation completed successfully!"
        
        return


# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):
    # Token URL is typically http://server[:port]/arcgis/admin/generateToken
    tokenURL = "/arcgis/admin/generateToken"
    
    # URL-encode the token parameters
    params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", tokenURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while fetching tokens from admin URL. Please check the URL and try again."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):            
            return
        
        # Extract the token from it
        token = json.loads(data)        
        return token["token"]            
        

# A function that checks that the input JSON object 
#  is not an error object.  
def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print "Error: JSON object returns an error. " + str(obj)
        return False
    else:
        return True
    
        
# Script start
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

Windows PowerShell

This script starts the geometry service using Windows PowerShell. It is intended as an example of how you could write other PowerShell scripts with the ArcGIS REST API.

# Demonstrates how to start a service by starting the geometry service.# This service is included with every ArcGIS Server 

and is stopped by default.

# To run this script, you must set the the appropriate security settings.
#  For more information about Powershell security, visit the following URL: 
#  http://www.windowsecurity.com/articles/PowerShell-Security.html


# provides serialization and deserialization functionality for JSON object
Add-Type -AssemblyName System.Web.Extensions


# Defines the entry point into the script
function main(){
  # Print some info
  echo "This is a sample script that starts the ArcGIS Server geometry service."
  
  # Ask for admin/publisher user name
  $username = read-host "Enter user name"
  $securePassword = read-host -AsSecureString "Enter password"
  
  # Ask for Admin/publisher password
  # Use Marshal Class to decode the secure string. Reference:
  #  http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx
  $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($securePassword)
  $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
  [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
  
  # Ask for servername
  $serverName = read-host "Enter server name"
  $serverPort = 6080
  
  # Get a token
  $token = token $username $password $serverName $serverPort
  if(!$token){
    write-warning "Could not generate a token with the username and password provided"
    
    return
  }
  
  # construct URL to start a service - as an example the Geometry service
  $url = "http://${serverName}:${serverPort}/arcgis/admin/services/Utilities/Geometry.GeometryServer/start"
  $parameters = "token=${token}&f=json"
  
  # Construct a HTTP request
  $http_request = New-Object -ComObject Msxml2.XMLHTTP
  $http_request.open('POST', $url, $false)
  $http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  
  # Connect to URL and post parameters
  try{
    $http_request.send($parameters)
  }
  catch{
    write-warning 'There were exceptions when sending the request'
    
    return
  }
  
  # Read response
  if($http_request.status -eq 200){
    # Check that data returned is not an error object
    if(assertJsonSuccess $http_request.responseText){
      echo "Operation completed successfully!"
    }
    else{
      write-warning "Error returned by operation."
      write-warning $http_request
    }
  }
  else{
    write-warning "Error while attempting to start the service."
  }
}


# A function to generate a token given username, password and the adminURL.
function token([string]$username, [string]$password, [string]$serverName, [int]$serverPort){
  # Token URL is typically http://server[:port]/arcgis/admin/generateToken
  $url = "http://${serverName}:${serverPort}/arcgis/admin/generateToken"
  $parameters = "username=${username}&password=${password}&client=requestip&f=json"
  
  # Construct a HTTP request
  $http_request = New-Object -ComObject Msxml2.XMLHTTP
  $http_request.open('POST', $url, $false)
  $http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  
  # Connect to URL and post parameters
  $token = ''
  try{
    $http_request.send($parameters)
  }
  catch{
    write-warning 'There were exceptions when sending the request'
    
    return $token
  }
  
  # Read response
  if($http_request.status -eq 200){
    # Check that data returned is not an error object
    if(assertJsonSuccess $http_request.responseText){
      # Extract the token from it
      $jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
      $jsonObj = $jsonSerializer.DeserializeObject($http_request.responseText)
      
      $token = $jsonObj['token']
    }
  }
  else{
    write-warning "Error encountered when retrieving an administrative token. Please check your credentials and try again."
  }
  
  $token
}


# A function that checks that the input JSON object 
#  is not an error object.  
function assertJsonSuccess([string]$data){
  $jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
  $jsonObj = $jsonSerializer.DeserializeObject($data)
  
  if($jsonObj['status'] -eq 'error'){
    write-warning "JSON object returns an error. Data => ${data}"
    $FALSE
  }
  else{
    $TRUE
  }
}


# Script start
main

Perl

This example script starts the geometry service using Perl. The script always attempts to securely log in (encrypting the user name and password). If HTTPS is not configured for ArcGIS Server then the secure login attempt fails and by default the script tries an insecure login. If you never want to attempt an insecure login then use the -e option to require secure logins.

This script uses the LWP and HTTP libraries which are usually included with all Perl distributions. This script doesn't require any Esri software to be installed on the system running it.

If altering this script for your own use, be aware that the geometry service resides in the Utilities folder and the URL used in the script will need to be modified to accommodate other folder names.

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common qw(GET POST);

my $ua = LWP::UserAgent->new;
$ua->timeout(300); 	#services start within 5 minutes or timeout

my ($user, $password, $serverName, $port, $requireEncryption) = getUserInput();
my $baseUrl ="http://$serverName:$port/arcgis";

my $token = getToken($baseUrl, $user, $password, $requireEncryption);
startService($baseUrl, $token, "Geometry", "GeometryServer");


sub getToken {
	# Attempt to login securely.  
	# If it fails and encryption required, tell user.
	# If it fails and encryption not required, try insecure login.
	
	my ($baseUrl, $user, $password, $requireEncryption) = @_;
	my $secureUrl = $baseUrl;
	$secureUrl =~ s/http/https/;
	$secureUrl =~ s/:6080/:6443/;

	my $token = makeTokenRequest($secureUrl, $user, $password);
	return $token if (defined $token);

	if ($requireEncryption) {
		print "Unable to login. Either the server doesn't support https, or the server name,\nusername, or password might be incorrect.\n\n";
		exit(1);
	}

	$token = makeTokenRequest($baseUrl, $user, $password);
	return $token if (defined $token);
	
	print "Unable to get token.  The server name, username, or password might be incorrect.\n";
	exit(1);
}


sub makeTokenRequest {
	my ($url, $user, $password) = @_;
	my $response = makeHttpPost("$url/admin/generateToken", {username=>$user, password=>$password, client=>"requestip", expiration=>30, f=>'json'});
	if ($response =~/\{\"token\"\:\"(.*)\",/) {
		return $1;
	} else {
		return undef;
	}
}

sub startService {
	my($baseUrl, $token, $serviceName, $serviceType) = @_;

	my $response = makeHttpPost("$baseUrl/admin/services/Utilities/$serviceName.$serviceType/start", {f=>'json', token=>$token});
	if ($response eq "") {
		print "ERROR: Unable to start the service.  Unable to make http connection to server.\n";
	} elsif ($response =~/success/) {
		print "Service $serviceName.$serviceType successfully started.\n";
	} elsif ($response =~ /"code":404/) {
		print "Service $serviceName.$serviceType was not found. Please check for typos.\n";
	}
}




sub makeHttpPost {

        my $url         = $_[0];
        my %parameter   = %{$_[1]};

        my $req = HTTP::Request->new(POST => $url);
        $req->content_type('application/x-www-form-urlencoded');
        my $requestParameters = "";
        foreach my $key ( keys %parameter) {
                $requestParameters .= "$key=$parameter{$key}&"
        }

        $req->content($requestParameters);
        my $res = $ua->request($req);
        if ($res->is_success) {
                return $res->content;
        } else {
	        return "";
	}
}

sub getUserInput {

	my ($user, $password, $serverName, $port, $requireEncryption);
	$serverName = "localhost";
	$port = "6080";
	$requireEncryption = 0;

	if ($#ARGV < 0) {
		print "This tool is a sample script that starts the Geometry service on a Server.\n\n";
		print "\t-u\tArcGIS Server publisher or admin user. Required\n";
		print "\t-p\tPassword for the user. Required.\n";
		print "\t-s\tServer machine. Optional, default is localhost.\n";
		print "\t-t\tPort.  Optional, default is 6080.\n";
		print "\t-e\tRequire secure login.\n";
		print "\n\n\tExample: startGeometryService -u admin -p password.\n";
		print "\tExample: startGeometryService -u admin -p password -s gis1.\n";
		print "\tExample: startGeometryService -u admin -p password -e.\n";
		print "\tExample: startGeometryService -u admin -p password -s gis1 -t 80.\n\n";
		print "Warning: This script always tries to login securely through https (encrypted).\n";
		print "If that fails, it tries an insecure login since ArcGIS Server may not be\n";
		print "configured for https.  Use the -e option to avoid ever using an insecure login.\n\n\n";
		exit();
	} else {
		for my $i (0 .. $#ARGV) {
			$user = $ARGV[$i+1] if ($ARGV[$i] eq "-u");
			$password = $ARGV[$i+1] if ($ARGV[$i] eq "-p");
			$serverName = $ARGV[$i+1] if ($ARGV[$i] eq "-s");
			$port = $ARGV[$i+1] if ($ARGV[$i] eq "-t");
			$requireEncryption = 1 if ($ARGV[$i] eq "-e");
		}
	}

	if (! defined $user || ! defined $password) {
		print "A user was not provided using the correct syntax.\n" if (! defined $user);
		print "A password was not provided using the correct syntax.\n" if (! defined $password);
		exit(1);
	}

	return ($user, $password, $serverName, $port, $requireEncryption);
}

Scala

The following example is written in Scala. It allows you to stop or start the geometry service.

// Sample usage of the ArcGIS Server Administrator API
// - Dispatch (http://dispatch.databinder.net)
// - LiftJSON
// ...demonstrates how to START or STOP the Geometry Service in an ArcGIS Server site

import dispatch._
import dispatch.liftjson._
import Http._
import dispatch.liftjson.Js._
import net.liftweb.json.JsonAST._

object StartStopGeometryService {

	def main(args: Array[String]){

                
		try{
		    print("Enter Command (START or STOP): ")       
            val command = Console.readLine()
            print("Enter host name: ") 
            val host = Console.readLine() 
            print("Enter port:") 
		    val port = Console.readLine()
		    print("Enter username: ") 
		    val username = Console.readLine()
		    print("Enter password (WARNING! Password will show up as clear text): ") 
		    val password = Console.readLine()
		    
		   // if (!command.equalsIgnoreCase("start") || !command.equalsIgnoreCase("stop")){
		   //   println("Usage: StartGeometryService <START | STOP> <hostname> <port> <username> <password>")
		   //   sys.exit()
		   // }
		      

		    // Http Request
            val http = new Http

		
		    // Request a TOKEN...
		    val u = url("http://" + host + ":" + port + "/arcgis/admin/generateToken") << Map("f" -> "pjson","username" -> username.toString, "password" -> password.toString,"client" -> "requestip" , "expiration" -> "1000")
		    val token = http(u ># {json => (json \\ "token").values})


		    // Use the token to make a call to the Geometry Service to START or STOP (STOP, in this case)
		    val geomStartURL = url("http://" + host + ":" + port + 			"/arcgis/admin/services/Utilities/Geometry.GeometryServer/" + command) << Map("f" -> "pjson", "token" -> token.toString)
		    val response = http(geomStartURL ># {json => json})
	
		    println(response)

		}catch{
             case e: Exception => println(e.getMessage)
        }
		
	}

}