Within a Python Toolbox, using a parameter type DEFile and direction set to output, when you choose an existing file ArcGIS Pro automatically deletes the file before execution. I would like the option to append to an existing file. Using the environment manager to set overwriteOutput to False, causes an error. Suppressing this error does not work. Changing the direction to input does not work, because you need an existing file. I want option to create a new file or modify an existing one.
Thank you for sharing your idea! As I understand it, you wish to create a tool that allows the user to specify a file, and whether or not to append to the file or to overwrite its contents. If the specified file does not exist, you wish for the tool to create that file and write contents to it. What you are suggesting is already possible within the existing framework for the Python Toolbox. You will need to separate the input and output parameters and derive the output from the input. For input, DEFile may not be the best choice, as it does not allow you to select a file that does not yet exist. You can, however, specify the output to be of type DEFile. The below Python toolbox code showcases two approaches: Approach (A) allows overwriting or appending to the selected file, and approach (B) allows overwriting, appending to, or creating and writing to a new file if the specified file does not already exist:
# -*- coding: utf-8 -*-
import os
import arcpy
class Toolbox:
def __init__(self):
"""
This toolbox showcases how you can accomplish overwriting or appending content to a file.
"""
self.label = "Toolbox"
self.alias = "toolbox"
# List of tool classes associated with this toolbox
self.tools = [A_OverwriteOrApendFile, B_OverwriteApendOrCreateFile]
class A_OverwriteOrApendFile:
def __init__(self):
"""
This tool appends to or overwrites an existing file, but does not have the ability to creating a new file.
"""
self.label = "(A) Overwrite or Append file with contents"
self.description = "This tool appends to or overwrites an existing file, but does not allow creating a new file."
def getParameterInfo(self):
"""Define the tool parameters."""
params = [
arcpy.Parameter(
name="infile",
displayName="File",
datatype="DEFile",
direction="Input",
parameterType="Required",
),
arcpy.Parameter(
name="text",
displayName="Write Text",
datatype="GPString",
direction="Input",
parameterType="Required",
),
arcpy.Parameter(
name="append",
displayName="Append",
datatype="GPBoolean",
direction="Input",
parameterType="Optional",
),
arcpy.Parameter(
name="output",
displayName="Output File",
datatype="DEFILE",
direction="Output",
parameterType="Derived"
)
]
return params
def isLicensed(self):
"""Set whether the tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
infile = parameters[0].valueAsText
text = parameters[1].valueAsText
append = parameters[2].value
output = parameters[3]
# append or overwrite
if append:
with open(infile, "at") as f:
f.write(text)
else:
with open(infile, "wt") as f:
f.write(text)
output.value = infile
return
def postExecute(self, parameters):
"""This method takes place after outputs are processed and
added to the display."""
return
class B_OverwriteApendOrCreateFile:
def __init__(self):
"""
This tool appends to or overwrites an existing file, or creates and writes to a new file
if the specified file does not yet exist.
"""
self.label = "(B) Overwrite, Append, or Create file with contents"
self.description = "This tool appends to or overwrites an existing file, or creates and writes to a new file."
def getParameterInfo(self):
"""Define the tool parameters."""
params = [
arcpy.Parameter(
name="dir",
displayName="Directory",
datatype="DEFolder",
direction="Input",
parameterType="Required",
),
arcpy.Parameter(
name="file",
displayName="File",
datatype="GPString",
direction="Input",
parameterType="Required",
),
arcpy.Parameter(
name="text",
displayName="Write Text",
datatype="GPString",
direction="Input",
parameterType="Required",
),
arcpy.Parameter(
name="append",
displayName="Append",
datatype="GPBoolean",
direction="Input",
parameterType="Optional",
),
arcpy.Parameter(
name="output",
displayName="Output File",
datatype="DEFILE",
direction="Output",
parameterType="Derived"
)
]
return params
def isLicensed(self):
"""Set whether the tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
indir = parameters[0]
if indir.altered: # list existing files in selected directory
infile = parameters[1]
infile.filter.type = "ValueList"
infile.filter.list = [
file
for file
in os.listdir(indir.valueAsText)
if os.path.isfile(os.path.join(indir.valueAsText, file))
]
if infile.altered: # allow user to specify their own (new) file
infile.filter.list = list(set(infile.filter.list + [infile.valueAsText]))
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
indir = parameters[0].valueAsText
filename = parameters[1].valueAsText
filepath = os.path.join(indir, filename)
text = parameters[2].valueAsText
append = parameters[3].value
output = parameters[4]
# append or overwrite
# NOTE: Python's open func. will create new file if it does not exist
if append:
with open(filepath, "at") as f:
f.write(text)
else:
with open(filepath, "wt") as f:
f.write(text)
output.value = filepath
return
def postExecute(self, parameters):
"""This method takes place after outputs are processed and
added to the display."""
return
Since the proposed idea is already achievable with the existing tooling, we have closed this idea as "already offered". You may use the attached toolbox as a reference for implementing your own tools with these capabilities. Thank you again for sharing your idea, we appreciate your suggestion, and we are always looking for ways to improve our capabilities. If you have any further questions or concerns, please do not hesitate to contact us.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.