Environment: Running ArcGIS API for Python version 2.0.1 from Pro 3.0.2.
I am trying to use the ArcGIS API for Python to create a view of an AGOL hosted feature layer and set a definition query. This guide seems to be the most definitive documentation of the process, but it's not working for me. Here is the code I have that follows this process:
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
source_item_id = '<your item id>'
view_def = {
'viewDefinitionQuery': "State_FIPS IN ('09','23','25','33','44','50')"
}
view_name = 'TEST_create_view_python_01'
gis = GIS(profile='AGOL')
source_item = gis.content.get(source_item_id)
source_flc = FeatureLayerCollection.fromitem(source_item)
new_view = source_flc.manager.create_view(name=view_name)
view_search = gis.content.search(view_name)[0]
view_flc = FeatureLayerCollection.fromitem(view_search)
service_layer = view_flc.layers[0]
service_layer.manager.update_definition(view_def)
I copied the definition query from a view I manually created in a browser, so I'm pretty sure that's correct. It runs without errors or warnings. The new view shows up as an AGOL item, but when I add the view to a webmap, I see this error:
And adding it to a map in Pro gives me this:
Next, I tried one little tweak. After defining the source_flc variable, I create a list of layers and pass that to the create_view function's view_layers parameter. Otherwise, the code is the same:
view_layers = [source_flc.layers[0]]
new_view = source_flc.manager.create_view(name=view_name, view_layers=view_layers)
I can add it to Pro and it renders fine, but the popups are just a regular attribute field display, not my custom popup.I went to edit the popups in my layer and found that the Visualization tab (where you set the popup) is missing!
When I click "Open in Map Viewer", nothing loads.
If I use the "Add" button, the view shows up. If I click the "+Add" button, it changes to an "X Remove" button, but nothing shows up in the layer list or renders on the map.
I can manually create a working view in a web browser. I am getting errors when I try this with other source layers. So this doesn't seem like a data issue. What am I doing wrong?
Hi @davedoesgis
This is my template for creating a view. Very similar to your workflow. You don't need to search for the view item.
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
## access AGOL
agol = GIS("home")
## feature service to make a view for
item = agol.content.get("FS_ITEM_ID")
## create a FLC object
flc = FeatureLayerCollection.fromitem(item)
## create the view
view = flc.manager.create_view(name="NAME_OF_VIEW")
## define the definition query
defquery_dict = {
"viewDefinitionQuery" : "SQL_EXPRESSION"
}
## get the layer to apply the def query to
## if there is more than one layer use the correct index
lyr = view.layers[0]
## update the definition
print(lyr.manager.update_definition(defquery_dict))
Make sure that your definition is correct, if the attributes are text use ' ' around the values in your expression, if there are numerical the omit the ' '.
Another thing to try is top open it up in the classic map viewer. The new viewer still has some bugs to work out and you can report as one if so.
Thanks. I've tried everything I can think of and couldn't get it to work. I included the search for the new view because that was in the sample, but working directly with the resulting Item or gis.content.get had the same result. The view is not creating correctly, so the issue isn't in updating the def.
I have hit max frustration with this issue. If I don't include the view_layers argument, I get errors trying to work with it in a webmap. If I include it, I get a view that doesn't show up in the layer list, so effectively just as broken.
I should also point out that you don't need to search for the new view you created. I just did it that way because that's the way the sample had it. You get the view's Item object returned to you from create_view(). Or if you want to retrieve a fresh copy of it for some reason, the create_view() response has an ID that you can use with gis.content.get(). Regardless, this isn't the issue.
I tried creating a template view and using gis.content.clone_items() going from and to the same AGOL connection. It ran, but nothing was created. I tried both Item.copy() and Item.copy_item(). These worked, but instead of creating a new view, the output was a new feature layer.
I'm giving up.This has absurdly passed the amount of time it would take to do it manually several times, which defeats the whole point of automation. I need 10 views with subsets of a hosted feature layer. My new strategy is to create 10 basic views. The code I put in the original post will update the definition query just fine assuming I'm starting with a working view.
Hello @davedoesgis I'd be frustrated as well incurring these issues. I'm not able to reproduce the scenario you describe when testing with the API at 2.0.1 or the most recent release of 2.2. Using code similar to yours I was able to create views, update them with a definition query, then render them in both the Map Viewer and ArcGIS Pro with custom popups preserved. There appears nothing incorrect about the code to create the view.
Are you able to create an environment with more recent releases of the api either 2.1 or 2.2 and test to see if you incur the same situation?
Do you see this same behavior when creating a view based on any other Feature Layer item?
If you want to investigate more in-depth as to what might be causing what you're observing, you could log an incident with Support who can look into the issue in detail.
I have the exact same problem, no visualization tab when a view layer is created through the python API. However, a manually created view layer has the visualization tab and the layer definitions are exactly the same except for the name and item id. If there is any solution you found I would love to hear it.
I ran into a similar issue with the visualization tab and data not appearing when using the ArcGIS Python API to generate a view.
In my case the issue appears to come from a possible bug in the API when a sublayer ID in a Hosted Feature Service does not start with 0, in mine they started counting at 12. When I looked at the API published View Layer's configuration JSON in ArcGIS Assistant, I noticed that the "Data" tab was completely empty, none of the parent service's layer JSON settings carried over as expected:
If I go to the source Hosted Feature Layer and copy and paste its JSON then the layers start to function as expected:
Here is a modified script that adds an extra step of updating the the View's configuration JSON to match the Hosted Feature layer:
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
## access AGOL
agol = GIS("home")
## feature service to make a view for
item = agol.content.get("FS_ITEM_ID")
## Get the Feature service "Data" json settings
source_json_data = item.get_data()
## create a FLC object
flc = FeatureLayerCollection.fromitem(item)
## create the view
view = flc.manager.create_view(name="NAME_OF_VIEW")
## define the definition query
defquery_dict = {
"viewDefinitionQuery" : "SQL_EXPRESSION"
}
## Update the newly published View's "Data" json settings, it appears that "text" is the key to use here
view.update(item_properties={"text":source_json_data})
## get the layer to apply the def query to
## if there is more than one layer use the correct index
lyr = view.layers[0]
## update the definition
print(lyr.manager.update_definition(defquery_dict))
Note that this assumes that you are created View Layers on all the original sublayers, this script may have issues if you are only creating a View using a subset of layers.
I was having this issue. My Feature Layer has a single item but for whatever reason the layer ID was set to 1 instead of the default 0. I can create a view manually on AGOL just fine, but when I tried to create a view of this item using arcgis python api using the typical create_view code, the script did not work:
# fails to create a viable view when layer id is 1 instead of 0
new_view = flc.manager.create_view(name=new_name)
The code above creates a view on AGOL that couldn't load into Map Viewer or ArcGIS Pro but could load into our Hub Site. After investigating I found the view layer ID was set to 0, which doesn't seem to jive with the original layer ID 1.
Here is the code that resulted in the view preserving my layer id:
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
## access AGOL
agol = GIS("PRO")
## feature service to make a view for
item = agol.content.get("FS_ITEM_ID")
## create a FLC object
flc = FeatureLayerCollection(item.url, agol)
## create the view
view = flc.manager.create_view(name="NAME_OF_VIEW",
view_layers=[flc.layers[0]],
preserve_layer_ids=True)
While the documentation states that preserve layer ids should default to True, I found it only did this if I listed out the view layers (line 15). Not sure if line 16 is necessary but I'm not taking any chances.
I am having this same issue, I've tried multiple iterations always come to the same conclusion: a layer view is created but does not function..... I am not python literate by any means, AI is my crutch here.
Empty Data:
What's odd is that the Thumbnail is actually generating the correct image of what would be the filtered data:
If you try and manually update this feature view's definition, you get an error as well.
from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
# Connect to AGOL
gis = GIS("HOME")
# Specify the URL of the source feature layer
source_layer_item = gis.content.get("Master_Tracker")
# Check if the item was retrieved successfully
if source_layer_item is None:
raise ValueError(f"Item with ID not found.")
source_layer = FeatureLayerCollection.fromitem(source_layer_item)
# Define the filter (SQL query) for the view layer
filter_query = "PROJECT = 'SaltLake_UT'"
# Create the view layer
view_layer_title = "Salt Lake UT"
view_layer_description = "This is a filtered view layer showing specific data based on the query."
view_layer = source_layer.manager.create_view(
name=view_layer_title,
description=view_layer_description,
preserve_layer_ids=True
)
# Apply the filter to the view layer
view_layer_manager = view_layer.layers[0].manager # Access the manager of the first layer
view_layer_manager.update_definition({
"viewDefinitionQuery": filter_query
})
print(f"Filtered view layer created: {view_layer.url}")
I have some filtered views I've created manually from the same source layer, and i look at their feature server data:
Working View:
Bad View:
Bad JSON:
Any assistance would be appreciated
I found that I've needed to specify the list of layers I want in the view to get create_view to work.
Yours:
view_layer = source_layer.manager.create_view(
name=view_layer_title,
description=view_layer_description,
preserve_layer_ids=True
)
What I've found works:
view_layer = source_layer.manager.create_view(
name=view_layer_title,
description=view_layer_description,
view_layers=source_layer.layers,
preserve_layer_ids=True
)
including the list of view_layers is important, for some reason.