_runner
In-engine runner for agent-submitted source.
The agent host writes an entry script that calls :func:run with the
AgentScriptContext it built. The runner executes the agent source in a
fresh namespace, captures everything printed, serializes result to JSON,
and reports all of it back through the context.
Invariant
This module must stay parseable by IronPython 2.7, IronPython 3.4 and CPython 3, because the host picks the engine per request.
Invariant
pyrevitlib is loaded live while the host is a compiled DLL that only
changes after a rebuild and a Revit restart, so this module can meet an
older AgentScriptContext. Read any context member added after the
first release with getattr and a default that keeps the old behavior.
Attributes
SOURCE_NAME = '<agent-script>'
module-attribute
Classes
RunTimedOut
Bases: BaseException
Raised inside the agent script once its time limit has passed.
Derives from BaseException so a script's except Exception can't
swallow it. Python drops a trace function after its first raise on every
engine, so a handler that caught it would end the deadline checks. The
runner therefore narrows every bare except and except
BaseException in the script to except Exception before compiling,
and also records that the deadline passed so :func:run fails the run
even if the script then ends normally.
Functions:
run(context)
Execute context.Source and report the outcome on context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
AgentScriptContext
|
run request and outcome sink from the host. |
required |
Note
Never raises. Script errors, including a failure to serialize
result, are reported through context.SetError so the host can
roll the run back.
Note
context.TimeoutSeconds is enforced with sys.settrace, so it
stops Python code, including loops, but not a single blocking call
such as a long Revit API call or time.sleep; the run fails with
timeout once that call returns.
Warning
Raising from the trace function ends tracing, so the script's own
handlers must not catch RunTimedOut. The source is compiled with
every bare except and except BaseException narrowed to
except Exception; a script can no longer catch KeyboardInterrupt
or SystemExit that way. Suppression through an alias or
contextlib.suppress(BaseException) still bypasses this, and on
CPython the watchdog thread is the backstop.
Source code in pyrevitlib/pyrevit/agent/_runner.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | |