Select to view content in your preferred language

Notebook - Custom Web Tools logging

138
4
yesterday
MobiusSnake
MVP Regular Contributor

Hi all,

I'm working on a custom web tool published from a notebook.  I'd like to log some geoprocessing messages (Info, Warning, Error) as you would using from a local toolbox using something like arcpy.AddError().  These will be displayed to users in an Experience Builder Analysis widget.

The notebook I'm publishing only uses a Standard runtime and I'd like to keep it that way to minimize credit consumption, so arcpy functions aren't available.  Is it possible to write geoprocessing messages from a Notebook/Web Tool without arcpy access?

Thanks!

0 Kudos
4 Replies
TonyAlmeida
MVP Regular Contributor

Have you tired a custom geoprocessing-style message logger for notebook web tools, something like,

messages = []

def log_info(msg):
    messages.append(f"[INFO] {msg}")

def log_warning(msg):
    messages.append(f"[WARNING] {msg}")

def log_error(msg):
    messages.append(f"[ERROR] {msg}")

# ... your processing logic ...

log_info("Processing started")
log_warning("Input layer has null geometries — skipping 5 records")
log_error("Output feature class could not be written")

# Output parameter — must match what's defined in the web tool config
output_messages = "\n".join(messages)
0 Kudos
MobiusSnake
MVP Regular Contributor

The Analysis widget in Experience Builder has a setting that allows you to change the log level between the predefined GP message levels, I'd like to be able to leverage that.  I'm assuming that would require the messages to be returned the way they are from a GP service on Server (the "messages" section of the GP Job response), rather than as a string output parameter.

HaydenWelch
MVP Regular Contributor

Have you tried ducking the Messages object? Just write a Message class that has the same attributes and methods that return the same info and see if you can sneak it into the pipeline.

I'm also pretty sure that most server responses use json for messages though, so you could also mock the message schema as seen from the server.

0 Kudos
MobiusSnake
MVP Regular Contributor

I think I've figured out how to sneak it in there, but it's ugly:

  • When a notebook's run as a web tool, there's an environment variable ENB_JOBID that points to a subdirectory of the /tmp folder (this isn't visible when run as a notebook)
  • This directory contains a logs.txt, which contains a list of dictionaries like this:
{
  "timestamp": "2026-05-26 22:55:01.432",
  "level": "INFO",
  "message": "Start processing time: 2026-05-26 22:55:01.432811"
}

It looks like the contents of that file is what's coming out of my EXB Analysis widget's messages.

On a scale of 0 (nice API call) to 10 (greasy hack) I'd say this falls somewhere around an 7.

Fingers crossed there's a better way.

Edit - I might be overcomplicating this... an unhandled exception will cause an error to be logged, and using warnings.warn() will log an warning.  Both include some extra details in the message I don't have control over, but it's pretty close to what I'd like.

0 Kudos