Esri / arcgis-python-api

Documentation and samples for ArcGIS API for Python
https://developers.arcgis.com/python/
Apache License 2.0
1.88k stars 1.1k forks source link

In clone_items, a valid name is not always created if the name of the original item is missing (None) #1810

Open sverkerEsriSE opened 5 months ago

sverkerEsriSE commented 5 months ago

Describe the bug When using the clone_items method on items that don't have the name property set, the method clone() in arcgis_impl\common_clone.py will try to create a name from the item url. In some cases this can contain Swedish characters (å, ä, ö).

The regex used only replace non word characters, but these swedish characters are word characters, but still invalid in the name of ArcGIS items.

# Code excerpt from line 2929
if name is None:
  name = os.path.basename(os.path.dirname(original_item["url"]))
  # replace non-alphanumeric characters with underscore
  name = re.sub("\W+", "_", name)  # <---- This is the problematic regex
  name = self._get_unique_name(self.target, name)
  service_definition["name"] = name

To Reproduce Steps to reproduce the behavior:

from arcgis.gis import GIS
source_gis = GIS(profile="admin@source_gis")
target_gis = GIS(profile="admin@target_gis")

# get an item that doesn't have the .name property set, but has Swedish characters in url
item_without_name = source_gis.content.get("xxxxxxx")
new_itm = target_gis.content.clone_items([item_without_name])

error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   3024                 try:
-> 3025                     new_item = self.target.content.create_service(
   3026                         name,

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\gis\__init__.py in create_service(self, name, service_description, has_static_data, max_record_count, supported_query_formats, capabilities, description, copyright_text, wkid, create_params, service_type, owner, folder, item_properties, is_view, tags, snippet, item_id)
   7183         if len(re.findall(regex, name)) == 0:
-> 7184             raise ValueError(
   7185                 "The service `name` cannot contain any spaces or special characters except underscores."

ValueError: The service `name` cannot contain any spaces or special characters except underscores.

During handling of the above exception, another exception occurred:

_ItemCreateException                      Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_26300\2307847236.py in <cell line: 1>()
----> 1 target_gis.content.clone_items([itm_bad_name])

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\gis\__init__.py in clone_items(self, items, folder, item_extent, use_org_basemap, copy_data, copy_global_ids, search_existing_items, item_mapping, group_mapping, owner, preserve_item_id, **kwargs)
   8560             wab_code_attach=kwargs.pop("copy_code_attachment", True),
   8561         )
-> 8562         return deep_cloner.clone()
   8563 
   8564     def bulk_update(

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   1320         else:
   1321             with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
-> 1322                 results = executor.submit(self._clone, executor).result()
   1323                 return results
   1324 

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\concurrent\futures\_base.py in result(self, timeout)
    444                     raise CancelledError()
    445                 elif self._state == FINISHED:
--> 446                     return self.__get_result()
    447                 else:
    448                     raise TimeoutError()

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\concurrent\futures\_base.py in __get_result(self)
    389         if self._exception:
    390             try:
--> 391                 raise self._exception
    392             finally:
    393                 # Break a reference cycle with the exception in self._exception

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\concurrent\futures\thread.py in run(self)
     56 
     57         try:
---> 58             result = self.fn(*self.args, **self.kwargs)
     59         except BaseException as exc:
     60             self.future.set_exception(exc)

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\_impl\common\_clone.py in _clone(self, excecutor)
   1294                         if item:
   1295                             item.delete()
-> 1296                     raise ex
   1297 
   1298             level += 1

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\concurrent\futures\thread.py in run(self)
     56 
     57         try:
---> 58             result = self.fn(*self.args, **self.kwargs)
     59         except BaseException as exc:
     60             self.future.set_exception(exc)

~\AppData\Local\ESRI\conda\envs\arcgispro-py3-dev\lib\site-packages\arcgis\_impl\common\_clone.py in clone(self)
   3994             return new_item
   3995         except Exception as ex:
-> 3996             raise _ItemCreateException(
   3997                 "Failed to create {0} {1}: {2}".format(
   3998                     original_item["type"], original_item["title"], str(ex)

_ItemCreateException: ('Failed to create Feature Service Borlänge befolkning 15_80 500x500 2022 x: The service `name` cannot contain any spaces or special characters except underscores.', None)

Expected behavior That the cloning works

Platform (please complete the following information):

nparavicini7 commented 4 months ago

@sverkerEsriSE how are you creating these items with no name property set? Or is there an example of a publicly available service with swedish characters in the name that I can test?