<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Attachment download fails [FileNotFoundError] when name is local path in ArcGIS API for Python Questions</title>
    <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1339011#M9169</link>
    <description>&lt;P&gt;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/86309"&gt;@EarlMedina&lt;/a&gt;Thank you very much for this workaround. I tried it and it worked great.&lt;BR /&gt;&lt;BR /&gt;I also looked a bit further down the path you started and believe I found a more generic workaround, that doesn't include hardcoding a path in the source files.&lt;BR /&gt;&lt;BR /&gt;I modified the &lt;STRONG&gt;AttachmentManager.download&lt;/STRONG&gt; function in the &lt;STRONG&gt;managers.py&lt;/STRONG&gt; file &lt;EM&gt;(C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\arcgis\features\managers.py) &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I added &lt;EM&gt;att_name = os.path.basename(att_name) &lt;/EM&gt;to the code. Line 14 in example below, line 595 in the managers.py file. This makes sure that if a filepath name is added as a filename, it only uses the filename from the path. I tested it on a few different datasets, and works great.&lt;/P&gt;&lt;P&gt;It even works in relation to the clone_items() function and uses the new basename in the target as attachment filename.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;if not return_all:
    oid = oid[0]
    paths = []
    for att in attachment_id:
        att_path = "{}/{}/attachments/{}".format(self._layer.url, oid, att)
        att_list = self.get_list(int(oid))

        # get attachment file name
        desired_att = [att2 for att2 in att_list if att2["id"] == int(att)]
        if len(desired_att) == 0:  # bad attachment id
            raise RuntimeError
        else:
            att_name = desired_att[0]["name"]
            att_name = os.path.basename(att_name)

        if not save_path:
            save_path = tempfile.gettempdir()
        if not os.path.isdir(save_path):
            os.makedirs(save_path)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I will write an enhancement request to the technical support team this week.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks again for the help &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
    <pubDate>Wed, 18 Oct 2023 08:54:37 GMT</pubDate>
    <dc:creator>BijanTaheri</dc:creator>
    <dc:date>2023-10-18T08:54:37Z</dc:date>
    <item>
      <title>Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338162#M9149</link>
      <description>&lt;P&gt;I'm using the clone_items() function, which works fine for most operations.&lt;/P&gt;
&lt;P&gt;For items that have attachments the clone_items() function (I'm assuming) runs the download attachment function from the AttachmentManager as a part of the cloning process.&lt;/P&gt;
&lt;P&gt;The download attachment fails if the name of the attachment is a path referering to a local image, for the person that uploaded the image. For the most part the attachments are names "Fotos1.jpg", "Fotos2.jpg" and so on.&lt;/P&gt;
&lt;P&gt;If the photo name is called "C:\\Users\\xyz\\Desktop\\xyz\\xyz.JPG' i get the error:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;FileNotFoundError: [Errno 2] No such file or directory: "C:\\Users\\xyz\\Desktop\\xyz\\xyz.JPG'&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Attachment info:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;source_items.layers[0].attachments.get_list(oid=145)&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;[{'id': 61,&lt;BR /&gt;'globalId': 'eea8bc6b-5d97-4410-b10e-a8bc96c22788',&lt;BR /&gt;'parentGlobalId': '73e0b288-2a5d-4e75-bf75-1b672eff790a',&lt;BR /&gt;'name': "C:\\Users\\xyz\\Desktop\\xyz\\xyz.JPG',&lt;BR /&gt;'contentType': 'image/jpeg',&lt;BR /&gt;'size': 6387442,&lt;BR /&gt;'keywords': '',&lt;BR /&gt;'exifInfo': None}]&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;source_items.layers[0].attachments.download(oid=145, save_path=r"C:\LOCAL\PATH")&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;FileNotFoundError: [Errno 2] No such file or directory: "C:\\Users\\xyz\\Desktop\\xyz\\xyz.JPG'&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There is a lot of features with these types of filenames spread across a lot of (hosted) feature services, so i can't just change the names of the files.&lt;/P&gt;
&lt;P&gt;It is in ArcGIS Online.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Does anybody have an idea of why it happens, a workaround or anything else?&lt;/P&gt;</description>
      <pubDate>Fri, 28 Jun 2024 16:16:22 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338162#M9149</guid>
      <dc:creator>BijanTaheri</dc:creator>
      <dc:date>2024-06-28T16:16:22Z</dc:date>
    </item>
    <item>
      <title>Re: Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338226#M9151</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;I don't believe I've seen this problem before, but as you noted the fix that comes to mind is downloading all the attachments, re-uploading, reviewing to make sure filenames appear correctly, deleting the originals. Seems like the filepath is not being parsed correctly due to the filename appearing as a path.&lt;/P&gt;&lt;P&gt;This can be done programmatically to expedite the process. You would do something like this:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Use &lt;FONT face="courier new,courier"&gt;AttachmentManager.search&lt;/FONT&gt; with paging and an `&lt;SPAN&gt;attachment_where` clause to get all attachments&amp;nbsp;with bad filenames.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Download all attachments with bad filenames using &lt;FONT face="courier new,courier"&gt;AttachmentManager.download&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Rename as needed locally.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Upload each attachment to the correct feature using &lt;FONT face="courier new,courier"&gt;AttachmentManager.add&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Review and make sure the uploads were successful.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Delete the originals.&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;&lt;SPAN&gt;Re-attempt the clone.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Of course, even this approach is a bit laborious. I would probably only attempt it on the smallest of the Feature Layers to start.&lt;/P&gt;</description>
      <pubDate>Mon, 16 Oct 2023 16:46:47 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338226#M9151</guid>
      <dc:creator>EarlMedina</dc:creator>
      <dc:date>2023-10-16T16:46:47Z</dc:date>
    </item>
    <item>
      <title>Re: Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338523#M9153</link>
      <description>&lt;P&gt;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/86309"&gt;@EarlMedina&lt;/a&gt;Thank you for your reply.&lt;BR /&gt;&lt;BR /&gt;This was my thought process as well, but the problem is that the attachments can't be downloaded because the download functions looks for the attachment in the bad filename/local path instead of the actual locations.&lt;BR /&gt;&lt;BR /&gt;Using the UI i can see the attachment, and by replicating the feature service to a GDB using the REST api i can also see the attachments. It is only when i use the Python API that it fails.&lt;BR /&gt;&lt;BR /&gt;I also haven't seen this issue before, and it definitely isn't a regular issue. But i think the AttachmentManager download function is handling the filenames wrong.&lt;BR /&gt;&lt;BR /&gt;I attached the error log, if it is any help.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="BijanTaheri_0-1697533946593.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/83206i5F15DB6A737AB78E/image-size/medium?v=v2&amp;amp;px=400" role="button" title="BijanTaheri_0-1697533946593.png" alt="BijanTaheri_0-1697533946593.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 09:15:57 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338523#M9153</guid>
      <dc:creator>BijanTaheri</dc:creator>
      <dc:date>2023-10-17T09:15:57Z</dc:date>
    </item>
    <item>
      <title>Re: Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338594#M9155</link>
      <description>&lt;P&gt;Hey&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/517918"&gt;@BijanTaheri&lt;/a&gt;&amp;nbsp;, I was able to simulate your problem on my end with a bit of work. It's my opinion that you can't resolve the download issue in the API without modifying the source. Consequently, I would suggest that you open a case with Technical Support to log an enhancement to the API to add an additional check for invalid paths/illegal characters with respect to the download function (which relies on the &lt;FONT face="courier new,courier"&gt;stream_response_to_file&lt;/FONT&gt; function).&lt;/P&gt;&lt;P&gt;The change is simple, but I have to state that modifying the source voids any official support. I understand, however, that this is a recovery operation for you at this point. Therefore, if you want to try the download workaround I'd suggest creating a separate python environment to experiment in.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically, you want to add an additional step that cleans the filename. For cases where a file could have the same name, you'll get an error so you also have to introduce some uniqueness. Start by opening (as admin) the file&amp;nbsp;&lt;EM&gt;C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\requests_toolbelt\downloadutils\stream.py&lt;/EM&gt;.&lt;/P&gt;&lt;P&gt;Go to the&amp;nbsp;&lt;SPAN&gt;&lt;FONT face="courier new,courier"&gt;stream_response_to_file&lt;/FONT&gt;&amp;nbsp;&lt;/SPAN&gt;function. Look for the else statement and update to appear like so:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    else:
        filename = get_download_file_path(response, path)
        from datetime import datetime
        time = datetime.now().strftime("%H%M%S%f")
        parsed_filename_w_ext = filename.split("\\")[-1]
        name = parsed_filename_w_ext.split(".")[0]
        ext = parsed_filename_w_ext.split(".")[-1]
        new_name = f"{name}_{time}.{ext}"
        dir_path_to_download_to = r"C:\Users\yourUser\directory"
        filename = os.path.join(dir_path_to_download_to, new_name)
       
        if os.path.exists(filename):
            raise exc.StreamingError("File already exists: %s" % filename)
        fd = open(filename, 'wb')&lt;/LI-CODE&gt;&lt;P&gt;Be sure to set the value of "dir_path_to_download_to" to whatever the value of "save_path" would have been. Save as admin. Retry the download function. Change source back to original when done.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 13:56:59 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1338594#M9155</guid>
      <dc:creator>EarlMedina</dc:creator>
      <dc:date>2023-10-17T13:56:59Z</dc:date>
    </item>
    <item>
      <title>Re: Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1339011#M9169</link>
      <description>&lt;P&gt;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/86309"&gt;@EarlMedina&lt;/a&gt;Thank you very much for this workaround. I tried it and it worked great.&lt;BR /&gt;&lt;BR /&gt;I also looked a bit further down the path you started and believe I found a more generic workaround, that doesn't include hardcoding a path in the source files.&lt;BR /&gt;&lt;BR /&gt;I modified the &lt;STRONG&gt;AttachmentManager.download&lt;/STRONG&gt; function in the &lt;STRONG&gt;managers.py&lt;/STRONG&gt; file &lt;EM&gt;(C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\arcgis\features\managers.py) &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I added &lt;EM&gt;att_name = os.path.basename(att_name) &lt;/EM&gt;to the code. Line 14 in example below, line 595 in the managers.py file. This makes sure that if a filepath name is added as a filename, it only uses the filename from the path. I tested it on a few different datasets, and works great.&lt;/P&gt;&lt;P&gt;It even works in relation to the clone_items() function and uses the new basename in the target as attachment filename.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;if not return_all:
    oid = oid[0]
    paths = []
    for att in attachment_id:
        att_path = "{}/{}/attachments/{}".format(self._layer.url, oid, att)
        att_list = self.get_list(int(oid))

        # get attachment file name
        desired_att = [att2 for att2 in att_list if att2["id"] == int(att)]
        if len(desired_att) == 0:  # bad attachment id
            raise RuntimeError
        else:
            att_name = desired_att[0]["name"]
            att_name = os.path.basename(att_name)

        if not save_path:
            save_path = tempfile.gettempdir()
        if not os.path.isdir(save_path):
            os.makedirs(save_path)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I will write an enhancement request to the technical support team this week.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks again for the help &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Oct 2023 08:54:37 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1339011#M9169</guid>
      <dc:creator>BijanTaheri</dc:creator>
      <dc:date>2023-10-18T08:54:37Z</dc:date>
    </item>
    <item>
      <title>Re: Attachment download fails [FileNotFoundError] when name is local path</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1339085#M9170</link>
      <description>&lt;P&gt;Nice! Very glad to hear this worked out and good catch! I didn't do much digging around so having that info on where the best place to fix is will help a lot.&lt;/P&gt;</description>
      <pubDate>Wed, 18 Oct 2023 13:00:50 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/attachment-download-fails-filenotfounderror-when/m-p/1339085#M9170</guid>
      <dc:creator>EarlMedina</dc:creator>
      <dc:date>2023-10-18T13:00:50Z</dc:date>
    </item>
  </channel>
</rss>

