Select to view content in your preferred language

Licence error when using arcpy.un in a geoprocessing service

346
8
Jump to solution
a month ago
PierreloupDucroix
Occasional Contributor III

Hello,

I try to run a geoprocessing service that uses arcpy.un (to run a trace), but I get an error :

003049: The account logged into portal is not licensed with the Utility Network user type extension...

I am in enterprise 11.3.

To reproduce, I made a simple script that uses arcpy.un :

import os.path

from arcpy import un
arcpy.SignInToPortal("https://portalUrl/arcgis", 'adminAccount', 'pwd')
arcpy.AddMessage("connection successful")
arcpy.AddMessage(arcpy.GetPortalDescription(arcpy.GetActivePortalURL())["user"]["username"])

UN = r"https://portalUrl/ags/rest/services/Utility_Network/FeatureServer/0"
arcpy.un.VerifyNetworkTopology(
    in_utility_network=UN,
    out_log_file=r"in_memory\test"
)

 

the error https://pro.arcgis.com/en/pro-app/latest/tool-reference/tool-errors-and-warnings/001001-010000/tool-...

indicates that the user should have an Advanced Editing license, anyway I tried with an administrator account (with an ArcGIS Pro Standard license that include Adv Editing) or with a Creator + Advanced Editing...

Any idea ?

0 Kudos
1 Solution

Accepted Solutions
RobertKrisher
Esri Regular Contributor

@PierreloupDucroix correct, a geoprocessing service runs within the context of the server and feature service. Does the account you're using to run the geoprocessing services have the correct user type extension? Is the script any better behaved if you use the ArcGIS API for Python instead of ArcPy?

ArcPy was originally developed for desktop analysis, so I have noticed that when you need to be precise with service login information in a non-ArcGIS Pro context that the ArcGIS API for Python (which was developed to target AGOL/ArcGIS Enterprise) is more reliable.

View solution in original post

0 Kudos
8 Replies
MikeMillerGIS
Esri Frequent Contributor

Verify might be a bad tool to build a simple repo, it seems to have some user name requirements:

  • The network topology must be enabled.

  • When working with an enterprise geodatabase, the database connection must be from a branch versioned workspace.

  • When working with an enterprise geodatabase, the Input Utility Network parameter value must be from a database connection established as the database utility network owner.

  • When working with an enterprise geodatabase, the connected ArcGIS Enterprise portal account must be the portal utility network owner.

 

If you review the server logs, does it provide more info, such as what user is being sent?  Since it is a GP service, I wonder if it is using the ArcGIS user account

0 Kudos
RobertKrisher
Esri Regular Contributor

@PierreloupDucroix  Does this script work when you run it in a CONDA prompt and fail when you run it in a GP service? I just tested this locally with ArcGIS Pro 3.3 and ArcGIS Enterprise 11.3, and when the logged in user didn't have the ArcGIS Advanced Editing user type extension assigned, I would get this error, but as soon as I assigned it to the user the tool would succeed. I'll wait for confirmation from you before I dig into testing this with a GP service.

RobertKrisher_0-1720794394502.png

 

 

I agree that the error message can be misleading because it sounds like you're missing the utility network user type extension, when instead the service is saying you're missing the user type extension required for the utility network (which was previously a un user type and is now the advanced user type).

0 Kudos
PierreloupDucroix
Occasional Contributor III

Hello @MikeMillerGIS and @RobertKrisher ,

thanks for your halp.

You're right, verifyNetworkTopology was not the right tool to test. I modified my script to run an arcpy.un.trace, which is what I want to do at the end.

import os
import arcpy

arcpy.SignInToPortal("https://portalUrl/arcgis", 'adminAccount', 'psw')
arcpy.AddMessage("connection successful")
print("start")
arcpy.AddMessage(arcpy.GetPortalDescription(arcpy.GetActivePortalURL())["user"]["username"])

UN = r"https://portalUrl/ags/rest/services/Utility_Network/FeatureServer/0"
arcpy.un.Trace(
    in_utility_network=UN,
    trace_type="SUBNETWORK",
    starting_points=None,
    barriers=None,
    domain_network="Electric",
    tier="Réseau HTA",
    target_tier="",
    subnetwork_name="NOUMEA_500_PSDONIAMBO_28",
    shortest_path_network_attribute_name="",
    include_containers="INCLUDE_CONTAINERS",
    include_content="INCLUDE_CONTENT",
    include_structures="INCLUDE_STRUCTURES",
    include_barriers="INCLUDE_BARRIERS",
    validate_consistency="VALIDATE_CONSISTENCY",
    condition_barriers="'E:Cycle de vie' IS_GREATER_THAN SPECIFIC_VALUE 3 OR;'E:Etat coupure' IS_EQUAL_TO SPECIFIC_VALUE 1 OR;Category IS_EQUAL_TO SPECIFIC_VALUE E:Terre OR;'Is subnetwork controller' IS_EQUAL_TO SPECIFIC_VALUE 1 #",
    function_barriers=None,
    traversability_scope="BOTH_JUNCTIONS_AND_EDGES",
    filter_barriers=None,
    filter_function_barriers=None,
    filter_scope="BOTH_JUNCTIONS_AND_EDGES",
    filter_bitset_network_attribute_name="",
    filter_nearest="DO_NOT_FILTER",
    nearest_count=None,
    nearest_cost_network_attribute="",
    nearest_categories=None,
    nearest_assets=None,
    functions=None,
    propagators="'E:Phase a propager' # PROPAGATED_BITWISE_AND INCLUDES_ANY 7",
    output_assettypes=None,
    output_conditions=None,
    include_isolated_features="EXCLUDE_ISOLATED_FEATURES",
    ignore_barriers_at_starting_points="DO_NOT_IGNORE_BARRIERS_AT_STARTING_POINTS",
    include_up_to_first_spatial_container="DO_NOT_INCLUDE_UP_TO_FIRST_SPATIAL_CONTAINER",
    result_types="ELEMENTS",
    selection_type="NEW_SELECTION",
    clear_all_previous_trace_results="CLEAR_ALL_PREVIOUS_TRACE_RESULTS",
    trace_name="",
    aggregated_points="Trace_Results_Aggregated_Points",
    aggregated_lines="Trace_Results_Aggregated_Lines",
    aggregated_polygons="Trace_Results_Aggregated_Polygons",
    allow_indeterminate_flow="TRACE_INDETERMINATE_FLOW",
    validate_locatability="DO_NOT_VALIDATE_LOCATABILITY",
    use_trace_config="DO_NOT_USE_TRACE_CONFIGURATION",
    trace_config_name="",
    out_json_file=os.path.join(os.path.dirname(__file__), "toto.json"),
    run_async="RUN_SYNCHRONOUSLY",
    include_geometry="EXCLUDE_GEOMETRY",
    include_domain_descriptions="EXCLUDE_DOMAIN_DESCRIPTIONS",
    result_network_attributes=None,
    result_fields=None,
    use_digitized_direction="IGNORE_DIGITIZED_DIRECTION",
    synthesize_geometries="DO_NOT_SYNTHESIZE_GEOMETRIES"
)
arcpy.AddMessage("end")

Here is what I tried :

- run the script in pycharm with ArcGIS Pro conda environment (from C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3)

--> the script runs successfully, and the JSON is written with my trace elements

- run the script in pycharm with ArcGIS Server conda environment (from D:\arcgis_enterprise\framework\runtime\ArcGIS\bin\Python\envs\arcgispro-py3)

--> the script fails with error :

Traceback (most recent call last):
  File "D:\arcgis_enterprise\arcgisserver\directories\arcgissystem\arcgisinput\testUNLicense.GPServer\extracted\cd\phase2_datamigration\testUNLicense.py", line 19, in <module>
    arcpy.un.Trace(
  File "D:\arcgis_enterprise\server\framework\runtime\ArcGIS\Resources\ArcPy\arcpy\un.py", line 3181, in Trace
    raise e
  File "D:\arcgis_enterprise\server\framework\runtime\ArcGIS\Resources\ArcPy\arcpy\un.py", line 3178, in Trace
    retval = convertArcObjectToPythonObject(gp.Trace_un(*gp_fixargs((in_utility_network, trace_type, starting_points, barriers, domain_network, tier, target_tier, subnetwork_name, shortest_path_network_attribute_name, include_containers, include_content, include_structures, include_barriers, validate_consistency, condition_barriers, function.....
  File "D:\arcgis_enterprise\server\framework\runtime\ArcGIS\Resources\ArcPy\arcpy\geoprocessing\_base.py", line 512, in <lambda>
    return lambda *args: val(*gp_fixargs(args, True))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
arcgisscripting.ExecuteError: ERROR 160902: Unable to resume a service session.
Failed to execute (Trace).

 

- run the gpserver while connected with an admin account with GIS Professional Standard user type or with an account with a Creator user type + Advanced Editing license

--> the gpserver fails with the same error

- share the gpserver publicly and run in a private browser

--> the gpserver fails with erreor :

    esriJobMessageTypeInformative: Submitted.
    esriJobMessageTypeInformative: Executing...
    esriJobMessageTypeInformative: Heure de début : samedi 13 juillet 2024 16:08:52
    esriJobMessageTypeInformative: connection successful
    esriJobMessageTypeInformative: start
    esriJobMessageTypeError: Traceback (most recent call last):  File "D:\arcgis_enterprise\arcgisserver\directories\arcgissystem\arcgisinput\testUNLicense.GPServer\extracted\cd\phase2_datamigration\testUNLicense.py", line 7, in <module>  arcpy.AddMessage("start")  ^^^^^^^^^ KeyError: 'user'
    esriJobMessageTypeInformative: Échec du script testUNLicense...
    esriJobMessageTypeError: Échec de l’exécution de (testUNLicense).
    esriJobMessageTypeInformative: Échec à samedi 13 juillet 2024 16:08:53 (temps écoulé : 0,24 secondes)
    esriJobMessageTypeError: Failed.

I guess that the GPServer is not using the arcpy.signinToPortal account, and is using instead "some connection" from ArcGIS Server which does not have the same license as a normal User Type...

What do you think ?

 

0 Kudos
RobertKrisher
Esri Regular Contributor

@PierreloupDucroix correct, a geoprocessing service runs within the context of the server and feature service. Does the account you're using to run the geoprocessing services have the correct user type extension? Is the script any better behaved if you use the ArcGIS API for Python instead of ArcPy?

ArcPy was originally developed for desktop analysis, so I have noticed that when you need to be precise with service login information in a non-ArcGIS Pro context that the ArcGIS API for Python (which was developed to target AGOL/ArcGIS Enterprise) is more reliable.

0 Kudos
PierreloupDucroix
Occasional Contributor III

Thanks, Robert,

I tried to use the ArcGIS API for Python and succeeded in having a trace result as JSON \o/

It needed some modifications since the arcpy trace parameters and GIS trace params are quite different.

It now works in PyCharm, but also in my GPserver, connected with an admin account or a creator with Advanced Editing license.

I am still struggling with some errors when performing complex traces (on interconnected subnetworks).

I think the trace is not honoring my condition barriers.

Previously it was condition_barriers="'E:Etat coupure' IS_EQUAL_TO SPECIFIC_VALUE 1 OR",

and now I translated into

    "condition_barriers": [
        {
            "name": "E:Etat coupure",
            "operator": "equal",
            "value": "1",
            "combineUsingOr": True,
            "isSpecificValue": True
        }
    ],

But no matter how I format the condition_barriers, I get an error that "more than one subnet controller are discovered", whick I can reproduce in ArcPro by deleting the condition barrier.

Do you know if there is a parameter that could bypass my condition barrier ?

My global config looks like this

locations = []
trace_type = "subnetwork"
result_types = [
    {
        "type": "elements",
        "includeGeometry": True,
        "includePropagatedValues": False,
        "networkAttributeNames": None,
        "diagramTemplateName": None,
        "resultTypeFields": None
    },
    {
        "type": "connectivity",
        "includeGeometry": True,
        "includePropagatedValues": False,
        "networkAttributeNames": None,
        "diagramTemplateName": None,
        "resultTypeFields": None
    },
    {
        "type": "aggregatedGeometry",
        "includeGeometry": True,
        "includePropagatedValues": False,
        "networkAttributeNames": None,
        "diagramTemplateName": None,
        "resultTypeFields": None
    }
]
traceConfiguration = {
    "include_containers": True,
    "include_content": True,
    "include_structures": True,
    "include_barriers": True,
    "validate_consistency": False,
    "validate_locatability": False,
    "synthesizeGeometries": False,
    "includeIsolated": False,
    "ignoreBarriersAtStartingPoints": False,
    "includeUpToFirstSpatialContainer": False,
    "allowIndeterminateFlow": False,
    "useDigitizedDirection": False,
    "domainNetworkName": "Electric",
    "tierName": "Réseau HTA",
    "targetTierName": None,
    "subnetworkName": "NOUMEA_500_PSDONIAMBO_28",
    "shortestPathNetworkAttributeName": None,
    "filterBitsetNetworkAttributeName": None,
    "traversabilityScope": "junctionsAndEdges",
    "filterScope": "junctionsAndEdges",
    "condition_barriers": [
        {
            "name": "E:Etat coupure",
            "operator": "equal",
            "value": "1",
            "combineUsingOr": True,
            "isSpecificValue": True
        }
    ],
    "filterBarriers": None,
    "filterFunctionBarriers": None,
    "functions": None,
    "outputFilters": None,
    "outputConditions": None,
    "propagators": None
}

unTrace = GisUN.trace(
    locations=locations, 
    trace_type="SUBNETWORK", 
    configuration=traceConfiguration, 
    result_types=result_types
)

 

0 Kudos
RobertKrisher
Esri Regular Contributor

@PierreloupDucroix You will need to include your condition barriers as part of your trace configuration object and because the trace configuration object in ArcGIS API for Python is a 1:1 match for the rest spec object you need to make sure your key names match the rest spec: conditionBarriers, incluseContainers, etc

0 Kudos
PierreloupDucroix
Occasional Contributor III

Thank you so much, Robert,

I mixed naming from arcpy and Rest.

--> AND there is an omission in the documentation :

in the REST trace doc (https://developers.arcgis.com/rest/services-reference/enterprise/trace-utility-network-server/#trace...) the conditionBarriers is described like this without the "type" field resulting in an error "missing required field in JSON" :

PierreloupDucroix_0-1721082222744.png

but fortunately, in the example this mandatory field is present

PierreloupDucroix_2-1721082314810.png

 

Two more things :

I noticed that, in the ArcGIS API reference, the UtilityNetworkManager class is called with

 

 class arcgis.features._utility.UtilityNetworkManager(url, version=None, gis=None)

 

is there any difference with using

 

 class arcgis.features.UtilityNetworkManager(url, version=None, gis=None)

 

 

Also when using the Trace method, you should pass the /UtilityNetworkServer URL, but if you pass the /FeatureServer URL, the arcgis.features.UtilityNetworkManager(URL) object is still a "Utility Network Server" object (print shows < Utility Network Server @ https://portalUrl/ags/rest/services/Utility_Network/FeatureServer >)

and the Trace method (presumably others too)  will run and return the description of the FeatureServer object without any error, which is a bit confusing.

0 Kudos
RobertKrisher
Esri Regular Contributor

@PierreloupDucroix the two classes are the same instance of the same class. The underscore indicates that it is an internal variable that you shouldn't be using. The API does have a certain amount of flexibility with handling different URLs.

I have made note of the issue with the documentation and forwarded it to the team responsible for maintaining the online help.

0 Kudos