Skip to main content

Utilities for building clean, maintainable ArcPy toolboxes

Project description

arcsmith

Utilities for building clean, maintainable ArcPy toolboxes.

arcsmith reduces the boilerplate common to ArcPy toolbox development — parameter validation, symbology application, and field management — so that toolbox code remains readable and consistent.

Python PyPI License: MIT


Installation

pip install arcsmith

Note: arcsmith depends on arcpy, which ships with ArcGIS Pro and is not available via pip. Ensure you are running in an environment where arcpy is accessible.


Usage

import arcsmith

# Layer symbology
arcsmith.layer.add_w_sym("path/to/fc", "path/to/sym.lyrx", target_map)

# Parameter management (Inside of toolbox's updateParameters)
if arcsmith.param.state(parameters[0]) == 'pending':
        parameters[1].value = None

Modules

  • arcsmith.param: Parameter state management, dropdowns, and checkbox-driven visibility
  • arcsmith.layer: Adding layers and applying symbology
  • arcsmith.fields: Field introspection, management, and mapping (coming soon)

arcsmith.param

Helpers for managing arcpy.Parameter state inside ToolValidator.

A key concept throughout this module is parameter state. Understanding whether a parameter has been changed by the user and whether it has passed through ArcPy's validation cycle is the foundation of updateParameters logic that ArcSmith simplifies.


state

Returns a string describing the combined altered / hasBeenValidated state of a parameter.

state(param: arcpy.Parameter) -> str

States

State .altered .hasBeenValidated Description
fresh False False Initial, untouched state
pending True False Changed, awaiting validation
settled False True Validated, not changed since
confirmed True True Changed and validated

The 'pending' state is the most important to detect. It marks the moment a value was just changed, and is the right time to cascade resets or re-populate dependent controls.

Example

state = state(parameters[0])

if state == 'pending':
    # parameter was just changed
    ...

cascade_clear

Resets downstream parameters to None when an upstream parameter is in a pending state.

cascade_clear(trigger_param, downstream_params)

Parameters

Parameter Type Default Description
trigger_param arcpy.Parameter required The parameter whose change triggers the cascade.
downstream_params list[arcpy.Parameter] required Parameters to clear when trigger_param is 'pending'.

Safe to call unconditionally on every updateParameters pass. If trigger_param is not 'pending' the call is a no-op.

Example

# Clear workspace and layer fields whenever the geodatabase selection changes
cascade_clear(params[0], [params[1], params[2]])

drop_populate

Sets or replaces a parameter's dropdown filter list.

drop_populate(param, values, overwrite_empty=False)

Parameters

Parameter Type Default Description
param arcpy.Parameter required The dropdown parameter to populate.
values list[str] required Options to display in the dropdown.
overwrite_empty bool False If True, updates the filter even when values is empty, clearing the list.

By default, an empty values list leaves the existing filter untouched. This prevents accidentally clearing a valid dropdown when an upstream dependency hasn't been set yet.

Example

# Populate field names derived from a selected feature class
fields = [f.name for f in arcpy.ListFields(params[0].value)]
drop_populate(params[1], fields)

# Explicitly clear a dropdown
drop_populate(params[1], [], overwrite_empty=True)

checkbox_dependence

Enables or disables dependent parameters based on a controlling checkbox, assigning placeholder values when hidden to keep required parameters satisfied.

checkbox_dependence(
    controlling_checkbox,
    dependents,
    placeholder=None,
    always_show_dependents=False
)

Behaviour

Checkbox state Effect
Unchecked Dependents disabled; placeholder value(s) assigned
Just checked Dependents enabled; values cleared to None
Otherwise No-op. Existing user input is preserved.

Raises: ValueError if placeholder is a list whose length differs from dependents.

Examples

# Broadcast a single placeholder to all dependents
checkbox_dependence(cb, [p1, p2, p3], placeholder="N/A")

# Single dependent - no list required
checkbox_dependence(cb, p1, placeholder=0)

# Mixed types, one placeholder per dependent
checkbox_dependence(cb, [p1, p2, p3], placeholder=["N/A", 0, None])

# Keep dependents visible but disabled when unchecked
checkbox_dependence(cb, [p1, p2], placeholder="N/A", always_show_dependents=True)

dynamic_dropdown

Enables the correct group of dependent parameters based on the selected dropdown option, disabling all others.

dynamic_dropdown(controlling_dropdown, option_map, placeholder_map=None)

Parameters

Parameter Type Default Description
controlling_dropdown arcpy.Parameter required Dropdown that controls which parameter group is active.
option_map dict[str, list[arcpy.Parameter]] required Maps each option label to the parameters that should be enabled when that option is selected.
placeholder_map dict[str, list] None Maps each option label to placeholder values assigned when the dropdown is pending. None entries skip assignment for that parameter.

Behaviour

Dropdown state Effect
Any state All managed parameters disabled first
Valid selection, not pending Active group re-enabled; existing values preserved
Valid selection, pending Active group cleared to placeholders (or None) and enabled

Raises: ValueError if any placeholder_map list length differs from its option_map counterpart.

Examples

# Show different parameters depending on the input type selected
dynamic_dropdown(
    params[0],
    option_map={
        "Shapefile":     [params[1]],
        "Feature Class": [params[2], params[3]],
    }
)

# With placeholder values applied on change
dynamic_dropdown(
    params[0],
    option_map={
        "Shapefile":     [params[1]],
        "Feature Class": [params[2], params[3]],
    },
    placeholder_map={
        "Shapefile":     [None],
        "Feature Class": ["N/A", 0],
    }
)

arcsmith.layer

Helpers for adding layers to a map and applying .lyrx symbology programmatically.


add_w_sym

Adds a data source to a map as a new layer and immediately applies symbology from a .lyrx file.

add_w_sym(lyr_src, lyrx_src, target_map, lyr_name=None)

Parameters

Parameter Type Default Description
lyr_src str or Path required Path to the data source (feature class, raster, etc.) to add.
lyrx_src str or Path required Path to the .lyrx file containing the symbology to apply.
target_map arcpy.mp.Map required Map object to add the layer to.
lyr_name str None Display name for the layer in the TOC. Defaults to the source name.

Returns: arcpy.mp.Layer. The newly added layer with symbology applied.

Example

# Add a feature class and apply symbology
lyr = add_w_sym("path/to/fc", "path/to/sym.lyrx", target_map)

# Add with a custom display name
lyr = add_w_sym("path/to/fc", "path/to/sym.lyrx", target_map, lyr_name="Study Area")

apply_lyrx

Applies symbology from a .lyrx file to one or more layers already present in the map TOC, matched by display name or data source path.

apply_lyrx(lyrx_src, target_map, lyr_name=None, lyr_source=None, geom_type=None)

Parameters

Parameter Type Default Description
lyrx_src str or Path required Path to the .lyrx file containing the symbology to apply.
target_map arcpy.mp.Map required Map object containing the layer(s) to update.
lyr_name str None Display name to match; all layers with this name are updated.
lyr_source str or Path None Data source path to match; only the first exact match is updated.
geom_type 'Point' | 'Polyline' | 'Polygon' | 'Multipoint' None Geometry type filter when matching by lyr_name. Case-insensitive. Ignored when matching by lyr_source.

Returns: list[arcpy.mp.Layer]. All layers that were updated.

Raises:

  • ValueError if neither or both of lyr_name and lyr_source are provided.
  • ValueError if no matching layers are found in the map.

Example

# Update all layers named "rivers"
lyrs = apply_lyrx("path/to/sym.lyrx", target_map, lyr_name="rivers")

# Update only polyline "rivers" layers
lyrs = apply_lyrx("path/to/sym.lyrx", target_map, lyr_name="rivers", geom_type="Polyline")

# Update a single layer by data source path
lyrs = apply_lyrx("path/to/sym.lyrx", target_map, lyr_source="path/to/fc")

arcsmith.fields

Coming soon. This module is planned for a future release.

Utilities for field introspection, management, and mapping. These functions return copies of the input rather than modifying it in place, and accept both layer objects and path strings.

Field introspection

  • list_fields: Return field names for a layer or table, with optional filters for field type and to exclude system fields like OID and Shape.
  • unique_values: Return sorted unique values for a given field.
  • field_exists: Check whether a named field exists, useful for defensive scripting before adds or deletes.

Field management

  • keep_fields: Return a copy with all fields removed except a specified list.
  • drop_fields: Return a copy with a specified list of fields removed. Skips missing names rather than erroring.
  • rename_field: Return a copy with a field renamed. Handled via add/calculate/delete internally since ArcPy has no native rename.

Field mapping

  • build_field_map: Construct a FieldMappings object from a layer, optionally filtered to a subset of fields, as a clean starting point for tools like Merge or Append.
  • field_map_rename: Apply a rename dictionary to a FieldMappings object, avoiding verbose FieldMap boilerplate.
  • align_fields: Given a source and target, build a field mapping that matches fields by name, useful for Append with schema mismatches.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

arcsmith-0.0.2.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arcsmith-0.0.2-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file arcsmith-0.0.2.tar.gz.

File metadata

  • Download URL: arcsmith-0.0.2.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.0 {"ci":null,"cpu":"AMD64","implementation":{"name":"CPython","version":"3.14.5"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.20 7 Apr 2026","python":"3.14.5","system":{"name":"Windows","release":"11"}} HTTPX2/2.4.0

File hashes

Hashes for arcsmith-0.0.2.tar.gz
Algorithm Hash digest
SHA256 0f3f3727f318c4209bfcea0e1db40d09d33a5ee85061120cd26fef83148c8988
MD5 0770913b3d1bf54dfbffb12a729d04fe
BLAKE2b-256 4e1ac09141d55d9c1cde892881b4d3a10e6725a3baa23582c0c4f7414ba55c73

See more details on using hashes here.

File details

Details for the file arcsmith-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: arcsmith-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.0 {"ci":null,"cpu":"AMD64","implementation":{"name":"CPython","version":"3.14.5"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.20 7 Apr 2026","python":"3.14.5","system":{"name":"Windows","release":"11"}} HTTPX2/2.4.0

File hashes

Hashes for arcsmith-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2496af5674f5b2f5afabd258c0a360f593907699852eb81a057fcf7f470b470c
MD5 b9111a3c330927c90f58573a2e74e778
BLAKE2b-256 7f0fd6185fa7b8a903eb909399cfe24399a0e857db0faee2ec0965a8ecf8ba1e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page