Select to view content in your preferred language

Survey123 Status from Open to Closed using Python

926
7
Jump to solution
10-31-2024 07:10 AM
PeterKonrad
Emerging Contributor

I need a method to programmatically update an AGOL Survey123 survey's status from open to closed.  I have explored the arcgis.apps.survey123.SurveyManager but it doesn't seem to have a method to change the status.  I have a way to share/unshare but I want the survey to display the closed message when a user visits the survey.  Is there any way to achieve this with Python?

0 Kudos
1 Solution

Accepted Solutions
PeterKnoop
MVP Regular Contributor

Unfortunately there isn't a direct method for this yet in the ArcGIS Python API. Would be a good enhancement idea to submit though (via ArcGIS API for Python Ideas or github.)

The workaround we use is to directly edit the JSON in the form package, manually changing the status from open to closed, or closed to open. Below is simplified code that makes that simple change. (If your survey status is set to scheduled, then the code won't work as-is, however you could add code to handle scheduling as well.)

Make sure to put the item ID for your survey in the code below.

from arcgis import GIS
from zipfile import ZipFile
import os

# Connect to GIS
gis = GIS("home")

# Get Survey123 Form as item.
item = gis.content.get('provide_item_ID_of_survey_form_here')

# Download the data package for the form (its a zip file in this case.)
item.download(
    save_path=".",
    file_name="survey_data.zip"
)

# Extract all the files in the form package
with ZipFile("survey_data.zip") as zObject:
    zObject.extractall('survey_data')
    
###
# Choose one of the following to uncomment and run: open to closed, or closed to open
###

# Set an Open survey to Closed.
with open(r'survey_data/esriinfo/form.json', 'r') as f:
    x = f.read()
    if( '"status":"open"' in x ):
        print("Changing status from open to closed")
        x = x.replace('"status":"open"', '"status":"closed"')
with open(r'survey_data/esriinfo/form.json', 'w') as f:
    f.write(x)  
with open(r'survey_data/esriinfo/form.info', 'r') as f:
    x = f.read()
    if( '"status":"open"' in x ):
        print("Changing status from open to closed")
        x = x.replace('"status":"open"', '"status":"closed"')
with open(r'survey_data/esriinfo/form.info', 'w') as f:
    f.write(x)
    
# # Set a Closed survey to Open.
# with open(r'survey_data/esriinfo/form.json', 'r') as f:
#     x = f.read()
#     if( '"status":"closed"' in x ):
#         print("Changing status from closed to open")
#         x = x.replace('"status":"closed"', '"status":"open"')
# with open(r'survey_data/esriinfo/form.json', 'w') as f:
#     f.write(x) 
# with open(r'survey_data/esriinfo/form.info', 'r') as f:
#     x = f.read()
#     if( '"status":"closed"' in x ):
#         print("Changing status from closed to open")
#         x = x.replace('"status":"closed"', '"status":"open"')
# with open(r'survey_data/esriinfo/form.info', 'w') as f:
#     f.write(x)

# Compress all of the files in the form package directory to a zip file.
with ZipFile('new_survey_data.zip','w') as zip_ref:
    for root, dirs, files in os.walk('survey_data'):
        for file in files:
            zip_ref.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), 'survey_data'))
            
# Upload updated form package back to item on ArcGIS Online.
item.update(
    item_properties=None,
    data = r'new_survey_data.zip'
)

 

 

View solution in original post

7 Replies
abureaux
MVP Frequent Contributor

Are you limited to python? This can be achieved quite easily with Power Automate (and I'd assume also Make and FME).

I'm not familiar with doing this via Python. This may help though: Updating features in a feature layer

0 Kudos
PeterKonrad
Emerging Contributor

I am not limited to Python, how would it be achieved with Power Automate?

0 Kudos
abureaux
MVP Frequent Contributor

Power Automate is what I normally use.

The trigger for this operation is up to you (e.g., it can run once a week).

But for the actual operation, you will want to make use of Esri's Actions. Just type in "arcgis" and select either "ArcGIS" if you use AGO, or "ArcGIS Enterprise" if you use Enterprise. (NOTE: I highly recommend you follow these steps. Simply typing "Update a record in a feature layer" in the search field may not show you what you are looking for)

abureaux_0-1730399092705.png

From there, use the action that best suits your task. That is likely going to be this one:

abureaux_1-1730399124874.png

 

0 Kudos
PeterKonrad
Emerging Contributor

I'm not trying to update a value stored in a feature layer.  I am trying to change a setting in a Survey123 Form from open: accepting responses to closed and vise versa.

0 Kudos
abureaux
MVP Frequent Contributor

Sorry, my bad! I didn't see the attachment.

As far as I am aware, there isn't a built-in way to modify that parameter via automations or HTTP calls.

You can of course set a schedule, but that wont help if you dont know the run dates.

0 Kudos
PeterKnoop
MVP Regular Contributor

Unfortunately there isn't a direct method for this yet in the ArcGIS Python API. Would be a good enhancement idea to submit though (via ArcGIS API for Python Ideas or github.)

The workaround we use is to directly edit the JSON in the form package, manually changing the status from open to closed, or closed to open. Below is simplified code that makes that simple change. (If your survey status is set to scheduled, then the code won't work as-is, however you could add code to handle scheduling as well.)

Make sure to put the item ID for your survey in the code below.

from arcgis import GIS
from zipfile import ZipFile
import os

# Connect to GIS
gis = GIS("home")

# Get Survey123 Form as item.
item = gis.content.get('provide_item_ID_of_survey_form_here')

# Download the data package for the form (its a zip file in this case.)
item.download(
    save_path=".",
    file_name="survey_data.zip"
)

# Extract all the files in the form package
with ZipFile("survey_data.zip") as zObject:
    zObject.extractall('survey_data')
    
###
# Choose one of the following to uncomment and run: open to closed, or closed to open
###

# Set an Open survey to Closed.
with open(r'survey_data/esriinfo/form.json', 'r') as f:
    x = f.read()
    if( '"status":"open"' in x ):
        print("Changing status from open to closed")
        x = x.replace('"status":"open"', '"status":"closed"')
with open(r'survey_data/esriinfo/form.json', 'w') as f:
    f.write(x)  
with open(r'survey_data/esriinfo/form.info', 'r') as f:
    x = f.read()
    if( '"status":"open"' in x ):
        print("Changing status from open to closed")
        x = x.replace('"status":"open"', '"status":"closed"')
with open(r'survey_data/esriinfo/form.info', 'w') as f:
    f.write(x)
    
# # Set a Closed survey to Open.
# with open(r'survey_data/esriinfo/form.json', 'r') as f:
#     x = f.read()
#     if( '"status":"closed"' in x ):
#         print("Changing status from closed to open")
#         x = x.replace('"status":"closed"', '"status":"open"')
# with open(r'survey_data/esriinfo/form.json', 'w') as f:
#     f.write(x) 
# with open(r'survey_data/esriinfo/form.info', 'r') as f:
#     x = f.read()
#     if( '"status":"closed"' in x ):
#         print("Changing status from closed to open")
#         x = x.replace('"status":"closed"', '"status":"open"')
# with open(r'survey_data/esriinfo/form.info', 'w') as f:
#     f.write(x)

# Compress all of the files in the form package directory to a zip file.
with ZipFile('new_survey_data.zip','w') as zip_ref:
    for root, dirs, files in os.walk('survey_data'):
        for file in files:
            zip_ref.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), 'survey_data'))
            
# Upload updated form package back to item on ArcGIS Online.
item.update(
    item_properties=None,
    data = r'new_survey_data.zip'
)

 

 

PeterKonrad
Emerging Contributor

Thank you so much for this comprehensive answer.  I went ahead and submitted the idea as well.

0 Kudos