Notifications API Reference
Docstrings for telling you when long-running work has finished. The narrative guides are Setup & Usage for configuring a channel, and Examples for what to send.
Three channels are available, and every function below can use any of them:
| channel | reaches you | needs |
|---|---|---|
| bell | the machine you are sitting at | nothing |
| anywhere | an address in the config | |
| Zulip | a team chat stream | a bot token in the config |
Configuration lives in ~/.mera.toml, found by mera_config_path, which checks $MERA_CONFIG, then ~/.mera.toml, then ~/.config/mera/config.toml. Environment variables take precedence over the file, which keeps secrets off disk. The older ~/email.txt, ~/zulip.txt and ~/bell.txt are still read when no TOML config exists.
Tested on macOS and Linux. Windows is not tested. The bell depends on the system sound command, so it is the one most likely to be silent elsewhere; email and Zulip are plain network calls and are not platform specific.
Sending a notification
Mera.notifyme — Function
Get an email and/or Zulip notification, e.g., when your calculations are finished.
Both channels are configured in ~/.mera.toml. Print a template with mera_config_example, fill in the parts you want, then chmod 600 ~/.mera.toml — it holds an API key. Configure either channel, or both; each is used only if present.
[email]
to = "you@example.com"
[zulip]
bot_email = "mybot@zulip.example.com"
api_key = "..." # or set MERA_ZULIP_API_KEY instead
server = "https://zulip.example.com"Email additionally needs the command-line mail client installed; Mera pipes the message to it. Nothing is sent if [email] to is unset.
Zulip needs all three keys. It is the richer channel: it carries image and file attachments, and posts to a channel/topic (zulip_channel=, zulip_topic=), which email does not.
Every value can also come from an environment variable — MERA_EMAIL_TO, MERA_ZULIP_BOT_EMAIL, MERA_ZULIP_API_KEY, MERA_ZULIP_SERVER, MERA_ZULIP_CHANNEL — which take precedence over the file and keep secrets off disk. The legacy email.txt, zulip.txt and bell.txt in $HOME still work; ~/.mera.toml wins where both exist. See mera_config.
Output Capture (optional):
- capture_output: Can be a Cmd, Function, or String to capture terminal/function output
- The captured output will be appended to your message
File Attachments (optional):
- image_path: Single image file to attach
- attachments: Vector of file paths to attach (multiple files)
- attachment_folder: Path to folder - all image files (.png, .jpg, .jpeg, .gif, .svg) will be attached
- maxattachments: Maximum number of files to attach when using attachmentfolder (default: 10)
- maxfilesize: Maximum file size in bytes for non-image attachments (default: 25000000 ≈ 25 MB). Files larger than this are skipped with an explanatory warning (Zulip itself may enforce stricter limits – typical defaults are 25–50 MB). For images a stricter 1 MB optimization target is applied automatically to keep uploads fast and reliable; large images are resized down to <=1024px on the longest side.
Time Tracking (optional):
- start_time: Start time for execution tracking (use time() or now())
- include_timing: Boolean to include automatic timing information (default: false)
- timing_details: Include detailed performance metrics (memory, allocations)
Exception Handling (optional):
- exception_context: Exception object to include stack trace and error details
- includestacktrace: Boolean to include full stack trace (default: true when exceptioncontext provided)
julia> notifyme()julia> notifyme("Calculation 1 finished!")julia> notifyme(msg="Calculation finished!", zulip_channel="alerts", zulip_topic="Run Status")julia> notifyme(msg="Plot ready!", zulip_channel="plots", zulip_topic="Results", image_path="result.png")julia> notifyme(msg="Multiple results!", attachments=["plot1.png", "plot2.png", "data.csv"])julia> notifyme(msg="All plots from analysis!", attachment_folder="./plots/")julia> notifyme(msg="Limited plots!", attachment_folder="./plots/", max_attachments=5)julia> notifyme(msg="Large dataset results!", attachments=["data.csv"], max_file_size=50_000_000) # 50MB limit# Example: enforce a tighter 5 MB limit to avoid heavy uploads when on slow networks
julia> notifyme(msg="Quick summary only", attachments=["summary.log"], max_file_size=5_000_000)# Time tracking examples
julia> start = time(); heavy_computation(); notifyme("Computation done!", start_time=start)julia> notifyme("Analysis finished!", include_timing=true, timing_details=true)# Exception handling examples
julia> try
risky_computation()
catch e
notifyme("Computation failed!", exception_context=e)
endjulia> notifyme(msg="Directory listing:", capture_output=`ls`)julia> notifyme(msg="Function output:", capture_output=() -> sum(rand(100)))Mera.bell — Function
bell(sound = nothing)Play a short notification sound — e.g. when a long calculation finishes.
Pick the sound in any of these ways (first match wins):
- by name —
bell(:chime)(aSymbolorString); - by number —
bell(2)(the position shown bybell(:list), also a numeric string likebell("2")); - a configured default —
[bell] sound = "gong"in~/.mera.toml, theMERA_BELL_SOUNDenvironment variable, or the legacy~/bell.txt(seemera_config); - the built-in fallback —
:strum(the original Mera sound).
19 sounds ship with Mera. List them with their numbers using bell(:list): arpeggio, bell, bird, bloop, bongo, chime, coin, coindrop, cosmic, ding, done, door, frog, gong, knock, oscillations, owl, strum, whistle.
You can also drop your own *.wav into the package's src/sounds/ folder and select it by its file name or number.
bell() # the configured default, else :strum
bell(:gong) # a deep blooming gong
bell("chime") # a glassy three-note chime
bell(4) # the 4th sound in bell(:list)
bell(:list) # print the numbered catalogue of available soundsMera.timed_notify — Function
Track execution time and send notification with timing information
Convenience function that automatically tracks execution time of a code block and sends a notification with timing details.
Parameters:
- task_name: Description of the task being timed
- code_block: Function or code to execute and time
- zulip_channel: Zulip channel for notification (default: "timing")
- zulip_topic: Zulip topic for notification (default: "Execution Times")
- include_details: Include detailed performance metrics (default: false)
Examples:
# Time a function execution
timed_notify("Data processing", () -> process_large_dataset())
# Time with detailed metrics
timed_notify("Complex analysis", () -> analyze_galaxy_formation(),
include_details=true, zulip_channel="research")
# Time with custom messaging
timed_notify("Simulation run #47", () -> run_simulation(params),
zulip_channel="simulations", zulip_topic="Run Times")Mera.send_results — Function
Send multiple plots or results with a single notification
Convenience function for common research workflows where you want to share multiple files (plots, data, results) at once.
Parameters:
- msg: Message to send
- folder: Path to folder containing files to attach
- file_pattern: Pattern to match files (default: images only)
- max_files: Maximum number of files to attach (default: 10)
- zulip_channel: Zulip channel/stream name (default: "results")
- zulip_topic: Zulip topic name (default: "Analysis Results")
Examples:
# Send all plots from analysis folder
send_results("Temperature analysis complete!", "./plots/")
# Send specific files
send_results("Key results ready!", ["figure1.png", "data.csv", "summary.txt"])
# Send with custom channel and topic
send_results("Paper plots ready!", "./figures/",
zulip_channel="publications", zulip_topic="Paper 1 - Figures")Progress tracking
A tracker reports long-running work as it goes, rather than only at the end. Create one, update it inside the loop, and complete it when the work is done.
Mera.create_progress_tracker — Function
Progress tracking with automatic time-based notifications
Creates a progress tracker that automatically sends notifications at specified time intervals or progress milestones.
Parameters:
- total_items: Total number of items to process
- time_interval: Send notification every N seconds (default: 300 = 5 minutes)
- progress_interval: Send notification every N% progress (default: 10%)
- task_name: Name of the task for notifications
- zulip_channel: Zulip channel (default: "progress")
- zulip_topic: Zulip topic (default: "Task Progress")
Returns: ProgressTracker object with update!() method
Examples:
# Create progress tracker for 1000 items, notify every 5 minutes or 10% progress
tracker = create_progress_tracker(1000, task_name="Galaxy analysis")
for i in 1:1000
# Do some work
process_galaxy(i)
# Update progress (automatically sends notifications at intervals)
update_progress!(tracker, i)
end
# Final completion notification
complete_progress!(tracker)Mera.update_progress! — Function
Update progress tracker and send notifications if thresholds are met
Parameters:
- tracker: Progress tracker created by createprogresstracker()
- current_item: Current item number being processed
- custom_message: Optional custom message for this update
Examples:
tracker = create_progress_tracker(1000, task_name="Data analysis")
for i in 1:1000
analyze_data_point(i)
update_progress!(tracker, i)
# Optional: Add custom message for specific milestones
if i == 500
update_progress!(tracker, i, "Reached halfway point - results looking good!")
end
endupdate_progress!(tsp::ThreadSafeProgress, filename::String)Thread-safe function to update progress bar with current file information. Uses locking to prevent race conditions when multiple threads update simultaneously.
Thread Safety
- Acquires exclusive lock before any modifications
- Updates both counter and description atomically
- Releases lock automatically when function exits
- Prevents progress bar corruption from concurrent updates
Display Format
- Shows [completed/total] ratio
- Displays currently processing filename
- Updates speed calculation automatically
Mera.complete_progress! — Function
Send final completion notification for progress tracker
Parameters:
- tracker: Progress tracker to complete
- final_message: Optional final message
- include_summary: Include full execution summary (default: true)
Examples:
tracker = create_progress_tracker(1000, task_name="Simulation")
# ... do work with update_progress! calls ...
complete_progress!(tracker, "All galaxies processed successfully!")Utilities
Mera.safe_execute — Function
Enhanced exception handler with automatic notification
Wraps risky code with automatic exception notification including full context.
Parameters:
- code_block: Function to execute with exception handling
- task_description: Description of what the code is doing
- zulip_channel: Channel for error notifications (default: "errors")
- zulip_topic: Topic for error notifications (default: "Exception Reports")
- include_context: Include system context in error report (default: true)
Examples:
# Basic exception handling with notification
result = safe_execute("Galaxy temperature calculation") do
calculate_galaxy_temperatures(data)
end
# Custom error channel and additional context
result = safe_execute("Critical simulation step",
zulip_channel="critical-errors",
include_context=true) do
run_critical_simulation_step()
endMera.optimize_image_for_zulip — Function
optimize_image_for_zulip(image_path; max_dimension=1024, max_file_size=1_000_000)Shrink an image so it uploads comfortably to Zulip, returning a path to use.
Downscales past max_dimension and re-encodes to approach max_file_size. Re-encoding can make an already-small PNG larger, so the result is whichever file is genuinely smaller — the original is returned unchanged when optimisation would not help.
Related
- Overview, what Mera can send and when it is worth it
- Setup & Usage, configuring bell, email and Zulip
- Examples, notifications around real analysis runs
- Complete API Reference