Filenames for items added via URL

1498
5
Jump to solution
07-23-2021 11:31 AM
lightpro
New Contributor III

I am having an issue where files uploaded to Arcgis online don't have a proper filename or extension. They are given a random filename such as "tmpeqklflj2" with no extension i.e. this is the file you get when downloading back from AGOL.

This only happens when I add content via a URL (as opposed to uploading from a local file)

I'm working with TPK's but as a quick example, say I add an image file from the below URL (an esri logo as an example). You can see that the filename assigned is not the same as the actual name of the file, but is given the filename "tmpj1xrvkhc" with no extension. 

Am I missing a parameter or is there a way to update the resource filename after? I can see that when adding or updating an Item Resource it's possible to assign a filename  a file to an Item as a Resource but only when adding or updating a new file from the local disk. Similarly the updateResource of the REST API seems like it could do it but I haven't been able to get that to work either.

 

 

gis = GIS("home")
properties={'title': 'MyLogo', 'tags':'logo'}
newitem = gis.content.add(item_properties=properties, data="https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg")

 

 

lightpro_0-1627064721281.png

 



 

 

 

0 Kudos
1 Solution

Accepted Solutions
lightpro
New Contributor III

So I couldn't resolve this error, but have a couple of workarounds. I also figured out how to define the filename when adding an item (see first example) 

Method 1: 

Catch the error and just programmatically check that the file has been added after. For anyone reading this thread, I also was able to define the filename for a file added via URL, so if the "exception" issue could be resolved then this method works fine.

 

 

from arcgis.gis import GIS
gis = GIS("home")

url = "https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg"

title = 'MyLogo'
item_type = 'Image'


properties={
    'title': title, 
    'tags':'logo', 
    'type': 'Image', 
    'dataUrl':url,
    'filename' : 'myfilename.jpeg'
}

try:
    newitem = gis.content.add(item_properties=properties, data=url)
except Exception as e:
    err_409 = 'Item already exists. Set the overwrite flag to true if you want to overwrite.' + "\n" + '(Error Code: 409)'
    err_400 = 'Item does not exist or is inaccessible.' + "\n" + '"(Error Code: 400)"'
    if str(e) == err_400 or str(e) == err_409:
        # Code to search AGOL for item
        items = gis.content.search(query= "title:"+ title , item_type=item_type)
        print(items)

 

 

 

 

 

Method 2:

Rather than bother with this I just decided to use the REST API directly. 

 

 

 

 

import requests
from arcgis.gis import GIS
gis = GIS("home")

folder_id = '' # ID of folder to upload file to
title = 'MyFile'
filename = 'MyFilename.jpeg'
item_type = 'Image'
dataURL = 'https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg'

# Need to request token from rest
token = 'insertyourtoken'

postdata = {
        'f':'json',
        'title':title,
        'type':item_type,
        'filename' : filename,
        'dataUrl': url,
        'token' : token
    }

post_url = 'https://[root]/content/users/[userName]/' + folderid + '/addItem'

response = requests.post(post_url, data=postdata)
response.json()

 

 

 

 

 

 

View solution in original post

0 Kudos
5 Replies
emedina
New Contributor III

Seems like the add method is imperfect, because this works as expected querying the REST API directly.

Anyhow, this fixes your example:

 

 

 

url = "https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg"
properties={
    "title": "MyLogo", 
    "tags":"logo", 
    "type": "Image", 
    "extension": "jpg", 
    "dataUrl":url
}
# Below triggers an exception, but actually works..
newitem = gis.content.add(item_properties=properties)

# Below triggers no exception, but is redundant. Still produces the intended result
newitem = gis.content.add(item_properties=properties, data=url)

 

 

 

 

So, what you're missing are the type and extension properties.

0 Kudos
lightpro
New Contributor III

Hi @emedina , interesting! This definitely gets the filename correct however both calls trigger exceptions for me...??

Exception: Item does not exist or is inaccessible.
(Error Code: 400)
0 Kudos
lightpro
New Contributor III

So I couldn't resolve this error, but have a couple of workarounds. I also figured out how to define the filename when adding an item (see first example) 

Method 1: 

Catch the error and just programmatically check that the file has been added after. For anyone reading this thread, I also was able to define the filename for a file added via URL, so if the "exception" issue could be resolved then this method works fine.

 

 

from arcgis.gis import GIS
gis = GIS("home")

url = "https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg"

title = 'MyLogo'
item_type = 'Image'


properties={
    'title': title, 
    'tags':'logo', 
    'type': 'Image', 
    'dataUrl':url,
    'filename' : 'myfilename.jpeg'
}

try:
    newitem = gis.content.add(item_properties=properties, data=url)
except Exception as e:
    err_409 = 'Item already exists. Set the overwrite flag to true if you want to overwrite.' + "\n" + '(Error Code: 409)'
    err_400 = 'Item does not exist or is inaccessible.' + "\n" + '"(Error Code: 400)"'
    if str(e) == err_400 or str(e) == err_409:
        # Code to search AGOL for item
        items = gis.content.search(query= "title:"+ title , item_type=item_type)
        print(items)

 

 

 

 

 

Method 2:

Rather than bother with this I just decided to use the REST API directly. 

 

 

 

 

import requests
from arcgis.gis import GIS
gis = GIS("home")

folder_id = '' # ID of folder to upload file to
title = 'MyFile'
filename = 'MyFilename.jpeg'
item_type = 'Image'
dataURL = 'https://www.esri.com/content/dam/esrisites/common/logos/esri-logo.jpg'

# Need to request token from rest
token = 'insertyourtoken'

postdata = {
        'f':'json',
        'title':title,
        'type':item_type,
        'filename' : filename,
        'dataUrl': url,
        'token' : token
    }

post_url = 'https://[root]/content/users/[userName]/' + folderid + '/addItem'

response = requests.post(post_url, data=postdata)
response.json()

 

 

 

 

 

 

0 Kudos
emedina
New Contributor III

Very strange you got exceptions for both of those examples. Maybe the version of your api? I am at the latest version. Anyhow yes, the REST API query was the most reliable method for me as well.

For those needing a token for the REST API workaround, you can make the process a  little bit more palatable by still incorporating the Python API to get the token like so:

gis = GIS("https://www.yourportalurl.com/whatever", "username", "password")
token = gis._con.token

 

If you have  a long-running script and are doing several adds, you can add some logic to get a new token which you can do using this method:

gis._con.relogin()

 

lightpro
New Contributor III

I was working in an AGOL workbook so I assume it was the latest version of the API. Anyway thanks for your help! 😀

0 Kudos