Last active
December 2, 2025 01:00
-
-
Save knu2xs/eec04f383cb72e4b1b65242b79bc858f to your computer and use it in GitHub Desktop.
Publish a feature layer and ensure the layer index is zero.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from pathlib import Path | |
| import shutil | |
| import tempfile | |
| from typing import Optional | |
| import arcgis.env | |
| from arcgis.features import GIS, Item | |
| import arcpy | |
| def publish_feature_layer( | |
| layer: arcpy._mp.Layer, | |
| gis: Optional[GIS] = None, | |
| feature_layer_name: Optional[str] = None | |
| ) -> Item: | |
| """ | |
| Publish a feature layer to ArcGIS Online ensuring the layer ID is 0. | |
| Args: | |
| layer: The ArcPy Layer object to publish. | |
| gis: GIS object with permissions to publish the layer. | |
| feature_layer_name: Optional name for the published feature layer. If not provided, uses the layer name. | |
| Returns: | |
| The published Item object. | |
| """ | |
| # ensure working with a layer object | |
| if not isinstance(layer, arcpy._mp.Layer): | |
| raise TypeError("The provided layer is not an ArcPy Layer object.") | |
| # ensure there is a gis to work with | |
| if gis is None and arcgis.env.active_gis is not None: | |
| gis = arcgis.env.active_gis | |
| else: | |
| raise EnvironmentError( | |
| "Cannot access an active GIS in the environment. Please populate the gis parameter with an " | |
| "instantiated GIS object with permissions to publish." | |
| ) | |
| # ensure the logged in user has publishing permissions | |
| if not gis.users.me.is_publisher and not gis.users.me.is_admin: | |
| raise PermissionError( | |
| f"The logged in user, {gis.users.me.username}, does not have permissions to publish content. " | |
| "Please use a user with Publisher or Admin privileges." | |
| ) | |
| # determine the feature layer name | |
| if feature_layer_name is None: | |
| feature_layer_name = layer.name | |
| # slugify the name | |
| feature_layer_name = re.sub(r"\s+", "_", feature_layer_name.strip()) | |
| # if the name starts with a number, prepend with letter 'f_' | |
| if re.match(r"^\d", feature_layer_name): | |
| feature_layer_name = f"f_{feature_layer_name}" | |
| # use tempfile to get a temporary directory | |
| tmp_dir = Path(tempfile.gettempdir()) | |
| # create a new aprx project in the temporary directory | |
| new_aprx_path = tmp_dir / "temp_project.aprx" | |
| # create a new ArcGIS Pro project | |
| arcpy.mp.CreateProject("NEW", new_aprx_path) | |
| new_aprx = arcpy.mp.ArcGISProject(new_aprx_path) | |
| new_map = new_aprx.listMaps()[0] | |
| # add the layer to the new project | |
| new_map.addLayer(layer) | |
| # ensure layer is at the top (index 0) --- | |
| new_map.moveLayer(None, layer, "TOP") | |
| new_aprx.save() | |
| # Create sharing draft and stage service | |
| sharing_draft = new_map.getWebLayerSharingDraft( | |
| server_type="HOSTING_SERVER", | |
| service_type="FEATURE", | |
| service_name=feature_layer_name | |
| ) | |
| sddraft_path = tmp_dir / f"{feature_layer_name}.sddraft" | |
| sharing_draft.exportToSDDraft(out_sddraft=sddraft_path) | |
| sd_path = tmp_dir / f"{feature_layer_name}.sd" | |
| arcpy.server.StageService( | |
| in_service_definition_draft=sddraft_path, | |
| out_service_definition=sd_path | |
| ) | |
| # Upload service definition using GIS object | |
| published_item = gis.content.add({}, sd_path) | |
| published_item.publish() | |
| logger.debug(f"Published service: {published_item.title}") | |
| # Verify publication and layer id | |
| layers = published_item.layers | |
| # ensure there is only one layer | |
| if len(layers) != 1: | |
| logger.warning( | |
| f"Published item {published_item.title} has {len(layers)} layers. Expected exactly 1 layer." | |
| ) | |
| else: | |
| logger.debug( | |
| f"Published item {published_item.title} has 1 layer as expected." | |
| ) | |
| # ensure the layer id is 0 | |
| if layers[0].properties.id != 0: | |
| logger.warning( | |
| f"Published layer {layers[0].properties.name} has layer ID {layers[0].properties.id}. Expected layer ID 0." | |
| ) | |
| else: | |
| logger.debug( | |
| f"Published layer {layers[0].properties.name} has layer ID 0 as expected." | |
| ) | |
| # report item id in log | |
| logger.info( | |
| f"Published feature layer '{feature_layer_name}' to ArcGIS Online with item ID: {published_item.id} ({published_item.url})." | |
| ) | |
| # clean up temporary files | |
| shutil.rmtree(tmp_dir, ignore_errors=True) | |
| return published_item |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment