docs: def exportTiles(self,
                      levels,
                      exportBy="LevelID",
                      tilePackage=False,
                      exportExtent="DEFAULT",
                      optimizeTilesForSize=True,
                      compressionQuality=0,
                      areaOfInterest=None,
                      async=False
                      ):
          """
          The exportTiles operation is performed as an asynchronous task and
          allows client applications to download map tiles from a server for
          offline use. This operation is performed on a Map Service that
          allows clients to export cache tiles. The result of this operation
          is Map Service Job. This job response contains a reference to the
          Map Service Result resource, which returns a URL to the resulting
          tile package (.tpk) or a cache raster dataset.
          exportTiles can be enabled in a service by using ArcGIS for Desktop
          or the ArcGIS Server Administrator Directory. In ArcGIS for Desktop
          make an admin or publisher connection to the server, go to service
          properties, and enable Allow Clients to Export Cache Tiles in the
          advanced caching page of the Service Editor. You can also specify
          the maximum tiles clients will be allowed to download. The default
          maximum allowed tile count is 100,000. To enable this capability
          using the Administrator Directory, edit the service, and set the
          properties exportTilesAllowed=true and maxExportTilesCount=100000.
  
          At 10.2.2 and later versions, exportTiles is supported as an
          operation of the Map Server. The use of the
          http://Map Service/exportTiles/submitJob operation is deprecated.
          You can provide arguments to the exportTiles operation as defined
          in the following parameters table:
  
          Inputs:
           exportBy - The criteria that will be used to select the tile
             service levels to export. The values can be Level IDs, cache
             scales. or the resolution (in the case of image services).
  	   Values: LevelID | Resolution | Scale
          levels - Specifies the tiled service levels to export. The values
            should correspond to Level IDs, cache scales. or the resolution
            as specified in exportBy parameter. The values can be comma
            separated values or a range. Make sure tiles are present at the
            levels where you attempt to export tiles.
  	   Example 1: 1,2,3,4,5,6,7,8,9
  	   Example 2: 1-4,7-9
          tilePackage - Allows exporting either a tile package or a cache
            raster data set. If the value is true, output will be in tile
            package format, and if the value is false, a cache raster data
            set is returned. The default value is false
  	   Values: true | false
          exportExtent - The extent (bounding box) of the tile package or the
            cache dataset to be exported. If extent does not include a
            spatial reference, the extent values are assumed to be in the
            spatial reference of the map. The default value is full extent of
            the tiled map service.
                         Syntax: <xmin>, <ymin>, <xmax>, <ymax>
                         Example 1: -104,35.6,-94.32,41
                         Example 2: {"xmin" : -109.55, "ymin" : 25.76,
                          "xmax" : -86.39, "ymax" : 49.94,
                          "spatialReference" : {"wkid" : 4326}}
          optimizeTilesForSize - (Optional) Use this parameter to enable
            compression of JPEG tiles and reduce the size of the downloaded
            tile package or the cache raster data set. Compressing tiles
            slightly compromises the quality of tiles but helps reduce the
            size of the download. Try sample compressions to determine the
            optimal compression before using this feature.
  	   Values: true | false
          compressionQuality - (Optional) When optimizeTilesForSize=true, you
           can specify a compression factor. The value must be between 0 and
           100. The value cannot be greater than the default compression
           already set on the original tile. For example, if the default
           value is 75, the value of compressionQuality must be between 0 and
           75. A value greater than 75 in this example will attempt to up
           sample an already compressed tile and will further degrade the
           quality of tiles.
          areaOfInterest - (Optional) The areaOfInterest polygon allows
           exporting tiles within the specified polygon areas. This parameter
           supersedes the exportExtent parameter. Must be geometry.Polygon
           object.
          Example: { "features": [{"geometry":{"rings":[[[-100,35],
           [-100,45],[-90,45],[-90,35],[-100,35]]],
           "spatialReference":{"wkid":4326}}}]}
          async - default True, this value ensures the returns are returned
           to the user instead of the user having the check the job status
           manually.
          """
          params = {
              "f" : "json",
              "tilePackage" : tilePackage,
              "exportExtent" : exportExtent,
              "optimizeTilesForSize" : optimizeTilesForSize,
              "compressionQuality" : compressionQuality,
              "exportBy" : exportBy,
              "levels" : levels
          }
          url = self._url + "/exportTiles"
          if isinstance(areaOfInterest, Polygon):
              geom = areaOfInterest.asDictionary()
              template = { "features": [geom]}
              params["areaOfInterest"] = template
          if async == True:
              return self._get(url=url, param_dict=params,
                              proxy_url=self._proxy_url,
                              proxy_port=self._proxy_port)
          else:
              exportJob = self._get(url=url, param_dict=params,
                                       securityHandler=self._securityHandler,
                                       proxy_url=self._proxy_url,
                                       proxy_port=self._proxy_port)
              jobUrl = "%s/jobs/%s" % (url, exportJob['jobId'])
              gpJob = GPJob(url=jobUrl,
                            securityHandler=self._securityHandler,
                            proxy_port=self._proxy_port,
                            proxy_url=self._proxy_url)
              status = gpJob.jobStatus
              while status != "esriJobSucceeded":
                  if status in ['esriJobFailed',
                                         'esriJobCancelling',
                                         'esriJobCancelled']:
                      return None
                  else:
                      time.sleep(5)
                      status = gpJob.jobStatus
              allResults = gpJob.results
              for k,v in allResults.items():
                  if k == "out_service_url":
                      value = v['value']
                      params = {
                          "f" : "json"
                      }
                      gpRes = self._get(url=v['value'],
                                           param_dict=params,
                                           securityHandler=self._securityHandler,
                                           proxy_url=self._proxy_url,
                                           proxy_port=self._proxy_port)
                      if tilePackage == True:
                          files = []
                          for f in gpRes['files']:
                              name = f['name']
                              dlURL = f['url']
                              files.append(
                                  self._get(url=dlURL,
                                            out_folder=tempfile.gettempdir(),
                                            file_name=name,
                                            param_dict=params,
                                            securityHandler=self._securityHandler,
                                            proxy_url=self._proxy_url,
                                            proxy_port=self._proxy_port))
                          return files
                      else:
                          return gpRes['folders']
                  else:
                      return None