AGOL Notebook Arcpy - How to create mmpk?

1145
2
Jump to solution
07-21-2021 06:30 AM
lightpro
New Contributor III

So I want to automate creation of a MMPK from a webmap. I  know that I could create a standalone python script on my local machine that runs the arcpy.managment .CreateMobileMapPackage and references a map in a .aprx project however I'd like to try do this via an AGOL Notebook that I can schedule. 

I'm not able to get it to work however and maybe it's simply not possible?

As far as I understand it, AGOL advanced notebooks support arcpy, and the

arcpy.management.CreateMobileMapPackage(in_map, output_file)

 tool appears to be supported however I basically don't know how to reference the map I want in AGOL or what to specify as in_map and output file. I keep getting the following error

ExecuteError: ERROR 000110: s does not exist
Failed to execute (CreateMobileMapPackage).

 Does anyone know how to do this?

0 Kudos
1 Solution

Accepted Solutions
lightpro
New Contributor III

You put me on the right track @HamishMorton !

Instead of using a aprx template I took the webmap and converted it to a arcgis project using arcpy.mp.ConvertWebMapToArcGISProject which seems to have worked!

 

 

 

import arcpy
import json
import os
from arcgis.gis import GIS
from requests.models import PreparedRequest
req = PreparedRequest()
gis = GIS("home")

# Sign into portal and get token
token = arcpy.SignInToPortal('portalurl', 'username', 'password')

# Get webmap as json. ID hardcoded but could also do a search H
webmap = gis.content.get("mapid")
webmap_json = webmap.get_data(try_json=True)

# Append mapOptions (required for arcpy.mp.ConvertWebMapToArcGISProject) and exportOptions (probably only needed for printing)
# Set the desired extent and spatial reference
webmap_json.update(json.loads('''{"mapOptions" : { "extent" : {  "xmin":-20026376.39 ,  "ymin":-20048966.10,  "xmax":20026376.39,  "ymax":20048966.10,  "spatialReference" : {"wkid" : 3857} }}}'''))
webmap_json.update(json.loads('''{"exportOptions": { "dpi" : 300, "outputSize" :  [1000,1000]}}'''))

# Add token to feature layer urls in json
for lyr in webmap_json['operationalLayers']:
    #print('\n',lyr['url'])
    url = lyr['url']
    req.prepare_url(url, token)
    lyr.update({'url': req.url})

# Convert json in dict format to json in string format. Arcpyy.mp.convertWebMaptoArcgisProject will fail otherwise
webmap_json_as_string = json.dumps(webmap_json)

# Convert webmap to Arcgis Project
result = arcpy.mp.ConvertWebMapToArcGISProject(webmap_json_as_string)
aprx = result.ArcGISProject
m = aprx.listMaps()[0]

# Define filename and path to save mmpk in workspace
mmpk_filename = 'MyFile.mmpk'
mmpk_path = '/arcgis/home/' + mmpk_filename
mmpk_agol_item_title = os.path.splitext(mmpk_filename)[0]

# Check if mmpk already exists and delete if required
if os.path.exists(mmpk_path):
  os.remove(mmpk_path)
  print("Exists. Removed")
else:
  print("The file does not exist")

# Create MMPK
mmpk = arcpy.management.CreateMobileMapPackage(m, mmpk_path)

# Publish MMPK to AGOl. Note: Only requird once, can just update after

mmpk_properties={'title': mmpk_agol_item_title ,
                'description':'Auto-updated MMPK for quickcapture project',
                'tags':'arcgis, python, quickcapture, mmpk, soil sampling'}

mmpk_agol_item = gis.content.add(item_properties=mmpk_properties, data=mmpk_path)

# Update already published MMPK
# Find MMPK
gis_items = gis.content.search(query= "title:"+ mmpk_agol_item_title , item_type="Mobile Map Package", sort_field='title', sort_order='desc') 

# GIS Search could return multiple files so need to check to make sure we select the correct one
for item in gis_items:
    print(item.title)
    if item.title == mmpk_agol_item_title:
        mmpk_item = item
        mmpk_update = mmpk_item.update(data=mmpk_path)
        
# Check update success      
if mmpk_update is True:
    print("MMPK successfully updated")      
else:
    print("MMPK Update Failure!")
    

 

 

 

View solution in original post

2 Replies
HamishMorton
Esri Contributor

Hi @lightpro ,

If you had a template APRX, you could potentially make a copy of it each time you run the script. You could then add the relevant layers from your ArcGIS Online map to ArcGIS Pro, set extents, etc... then run the CreateMobileMapPackage tool. Something like below where you use the Python API and ArcPy:

from arcgis.mapping import WebMap
from arcgis.gis import GIS
import arcpy

# connect to your GIS and get the web map item
gis = GIS('home')
wm_item = gis.content.get('<item id>')

# create a WebMap object from the existing web map item
wm = WebMap(wm_item)

# Map document (possibly copy of a template)
aprx = arcpy.mp.ArcGISProject('<path to template>')
map = aprx.listMaps()[0]

# Add basemap
map.addBasemap(wm.basemap.title)

# Add all layers
for layer in wm.layers:
    map.addDataFromPath(layer.url)

# Create mmpk
arcpy.management.CreateMobileMapPackage(map, '<output path>')




Hamish
0 Kudos
lightpro
New Contributor III

You put me on the right track @HamishMorton !

Instead of using a aprx template I took the webmap and converted it to a arcgis project using arcpy.mp.ConvertWebMapToArcGISProject which seems to have worked!

 

 

 

import arcpy
import json
import os
from arcgis.gis import GIS
from requests.models import PreparedRequest
req = PreparedRequest()
gis = GIS("home")

# Sign into portal and get token
token = arcpy.SignInToPortal('portalurl', 'username', 'password')

# Get webmap as json. ID hardcoded but could also do a search H
webmap = gis.content.get("mapid")
webmap_json = webmap.get_data(try_json=True)

# Append mapOptions (required for arcpy.mp.ConvertWebMapToArcGISProject) and exportOptions (probably only needed for printing)
# Set the desired extent and spatial reference
webmap_json.update(json.loads('''{"mapOptions" : { "extent" : {  "xmin":-20026376.39 ,  "ymin":-20048966.10,  "xmax":20026376.39,  "ymax":20048966.10,  "spatialReference" : {"wkid" : 3857} }}}'''))
webmap_json.update(json.loads('''{"exportOptions": { "dpi" : 300, "outputSize" :  [1000,1000]}}'''))

# Add token to feature layer urls in json
for lyr in webmap_json['operationalLayers']:
    #print('\n',lyr['url'])
    url = lyr['url']
    req.prepare_url(url, token)
    lyr.update({'url': req.url})

# Convert json in dict format to json in string format. Arcpyy.mp.convertWebMaptoArcgisProject will fail otherwise
webmap_json_as_string = json.dumps(webmap_json)

# Convert webmap to Arcgis Project
result = arcpy.mp.ConvertWebMapToArcGISProject(webmap_json_as_string)
aprx = result.ArcGISProject
m = aprx.listMaps()[0]

# Define filename and path to save mmpk in workspace
mmpk_filename = 'MyFile.mmpk'
mmpk_path = '/arcgis/home/' + mmpk_filename
mmpk_agol_item_title = os.path.splitext(mmpk_filename)[0]

# Check if mmpk already exists and delete if required
if os.path.exists(mmpk_path):
  os.remove(mmpk_path)
  print("Exists. Removed")
else:
  print("The file does not exist")

# Create MMPK
mmpk = arcpy.management.CreateMobileMapPackage(m, mmpk_path)

# Publish MMPK to AGOl. Note: Only requird once, can just update after

mmpk_properties={'title': mmpk_agol_item_title ,
                'description':'Auto-updated MMPK for quickcapture project',
                'tags':'arcgis, python, quickcapture, mmpk, soil sampling'}

mmpk_agol_item = gis.content.add(item_properties=mmpk_properties, data=mmpk_path)

# Update already published MMPK
# Find MMPK
gis_items = gis.content.search(query= "title:"+ mmpk_agol_item_title , item_type="Mobile Map Package", sort_field='title', sort_order='desc') 

# GIS Search could return multiple files so need to check to make sure we select the correct one
for item in gis_items:
    print(item.title)
    if item.title == mmpk_agol_item_title:
        mmpk_item = item
        mmpk_update = mmpk_item.update(data=mmpk_path)
        
# Check update success      
if mmpk_update is True:
    print("MMPK successfully updated")      
else:
    print("MMPK Update Failure!")