211c215c654c363993a9d480cbda679de0bbd7e9
hiram
  Fri May 1 13:59:15 2026 -0700
eliminating stderr information to avoid cron job noise refs #31811

diff --git src/hg/utils/otto/userRequests/ottoRequest.py src/hg/utils/otto/userRequests/ottoRequest.py
index ebfb5dc8b68..75141e61783 100755
--- src/hg/utils/otto/userRequests/ottoRequest.py
+++ src/hg/utils/otto/userRequests/ottoRequest.py
@@ -1,27 +1,31 @@
 #!/usr/bin/env python3
 """ottoRequest.py - check ottoRequest table for pending requests
 and send email notification for each one found.
 
 Intended to run from cron.  Reads the notification email address and
 table name from an hg.conf file.  Uses hgsql for database access.
 
 Usage:
     ottoRequest.py [-c /path/to/hg.conf]
 
 Options:
     -c, --conf    Path to hg.conf  [default: /usr/local/apache/cgi-bin/hg.conf]
+
+cron entry in the otto user:
+1,8,15,22,29,36,43,50,57 * * * * /hive/data/outside/otto/liftRequest/ottoRequest.py
+
 """
 
 import argparse
 import fcntl
 import os
 import re
 import subprocess
 import sys
 
 NOTIFY_FROM = 'genome-www@soe.ucsc.edu'
 BCC_BY_TYPE = {
     'liftOver': 'chain-file-request-group@ucsc.edu',
     'assembly': 'genark-request-group@ucsc.edu',
 }
 
@@ -101,54 +105,54 @@
                 out.append('\0')
             else:
                 out.append(s[i:i+2])
             i += 2
         else:
             out.append(s[i])
             i += 1
     return ''.join(out)
 
 
 def hgsqlQuery(db, sql):
     """Run a SQL query via hgsql and return rows as list of dicts.
     hgsql -B emits tabs/newlines/backslashes inside field values as
     literal \\t / \\n / \\\\ so each row stays on one line undo that
     on each field before returning."""
-    cmd = ['hgsql', db, '-N', '-B', '-e', sql]
+    cmd = ['/cluster/bin/x86_64/hgsql', db, '-N', '-B', '-e', sql]
     result = subprocess.run(cmd, capture_output=True, text=True)
     if result.returncode != 0:
         sys.exit(f"hgsql error: {result.stderr.strip()}")
     rows = []
     if not result.stdout.strip():
         return rows
     for line in result.stdout.strip().split('\n'):
         fields = [unescapeMysql(f) for f in line.split('\t')]
         rows.append({
             'id':          fields[0],
             'requestType': fields[1],
             'fromDb':      fields[2],
             'toDb':        fields[3],
             'email':       fields[4],
             'comment':     fields[5],
             'requestTime': fields[6],
         })
     return rows
 
 
 def hgsqlUpdate(db, sql):
     """Run a SQL update/insert statement via hgsql."""
-    cmd = ['hgsql', db, '-N', '-B', '-e', sql]
+    cmd = ['/cluster/bin/x86_64/hgsql', db, '-N', '-B', '-e', sql]
     result = subprocess.run(cmd, capture_output=True, text=True)
     if result.returncode != 0:
         print(f"hgsql update error: {result.stderr.strip()}", file=sys.stderr)
         return False
     return True
 
 
 def parseAssemblyComment(comment):
     """Assembly requests pack fields into the ottoRequest.comment column
     via hubApi/findGenome.c:apiAssemblyRequest:
         name: '<name>'[; betterName: '<bn>'][; comment: '<user comment>']
     The user comment may itself contain newlines and apostrophes, so the
     inner quote pair is matched greedily up to the trailing closing quote.
     re.DOTALL lets '.' span newlines.
     Return (name, betterName, userComment)."""