about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPjotr Prins2026-03-29 10:15:42 +0200
committerPjotr Prins2026-03-29 10:15:42 +0200
commitb3ef15eca284f98ff0e7d2259c5d79cac0724119 (patch)
tree9c90b9dd99e60de8d0a6f843aeac84839de0dd18
parentdb9974a1b64c643a760c67e30d3787d47cd28a34 (diff)
downloadgenecup-b3ef15eca284f98ff0e7d2259c5d79cac0724119.tar.gz
Move API key into credentials file [AI]
-rw-r--r--README.md22
-rw-r--r--guix.scm7
-rwxr-xr-xmore_functions.py1
-rwxr-xr-xserver.py29
4 files changed, 43 insertions, 16 deletions
diff --git a/README.md b/README.md
index 1897704..7c09004 100644
--- a/README.md
+++ b/README.md
@@ -30,11 +30,22 @@ Live searches are conducted through PubMed to get relevant PMIDs, which are then
 You can use the [guix.scm](./guix.scm) container to run genecup:
 
 ```sh
-env GEMINI_API_KEY="AIzaSy**" `guix build -L . genecup-gemini`/server.py --port 4201
+`guix build -L . genecup-gemini`/bin/genecup --port 4201
 ```
 
 Note that the build includes minipubmed and punkt for testing!
 
+## Gemini API credentials
+
+For stress classification via Gemini, create a credentials file:
+
+```sh
+mkdir -p ~/.config/gemini
+echo "YOUR_API_KEY_HERE" > ~/.config/gemini/credentials
+```
+
+The server reads the API key from `~/.config/gemini/credentials` on startup.
+
 # Run a production server
 
 ## Install local mirror of PubMed
@@ -44,22 +55,21 @@ Following the instruction provided by NCBI: https://www.nlm.nih.gov/dataguide/ed
 Point environment variables to this dir and run in the local source tree:
 
 ```
-env EDIRECT_PUBMED_MASTER=/export GEMINI_API_KEY="AIzaSy**" `guix build -L . genecup-gemini`/server.py --port 4201
+env EDIRECT_PUBMED_MASTER=/export/PubMed `guix build -L . genecup-gemini`/bin/genecup --port 4201
 ```
 
 You can run from a proper container:
 
 ```
-guix shell -L . -C -N -F genecup-gemini -- env GEMINI_API_KEY="AIzaSy**" genecup --port 4201
+guix shell -L . -C -N -F genecup-gemini -- genecup --port 4201
 ```
 
 Environment variables used:
 
 ```
-EDIRECT_PUBMED_MASTER: PubMed datadir (defaults to ./minipubmed)
-GEMINI_API_KEY: LLM access key
+EDIRECT_PUBMED_MASTER: PubMed datadir (defaults to built-in minipubmed)
 GENECUP_DATADIR: SQLITE DB directory (default .)
-NLTK_DATA: punkt directory (defaults to ./minipubmed/tokenizer)
+NLTK_DATA: punkt_tab directory (defaults to built-in nltk-punkt)
 TMPDIR (default /tmp)
 ```
 
diff --git a/guix.scm b/guix.scm
index 748a7f6..0dc9b76 100644
--- a/guix.scm
+++ b/guix.scm
@@ -7,7 +7,9 @@
 ;;
 ;; Development shell:
 ;;
-;;   guix shell -L . -C -N -F genecup-gemini coreutils -- env GEMINI_API_KEY="AIz**" genecup --port 4201
+;;   guix shell -L . -C -N -F genecup-gemini coreutils -- genecup --port 4201
+;;
+;; Note: API key is read from ~/.config/gemini/credentials
 ;;
 
 (define-module (guix)
@@ -183,7 +185,7 @@ access to Gemini models.")
             (lambda* (#:key inputs #:allow-other-keys)
               (delete-file "minipubmed.tgz")
               (let ((pubmed (string-append (assoc-ref inputs "minipubmed")
-                                           "/share/minipubmed")))
+                                           "/share/minipubmed/PubMed")))
                 ;; Patch default pubmed path to store location
                 (substitute* "more_functions.py"
                   (("\\./minipubmed") pubmed)))))
@@ -247,7 +249,6 @@ access to Gemini models.")
     (propagated-inputs
      (list
        python-bcrypt
-       python-dotenv
        python-flask
        python-flask-sqlalchemy
        python-google-genai
diff --git a/more_functions.py b/more_functions.py
index 2c1198b..5dc52d4 100755
--- a/more_functions.py
+++ b/more_functions.py
@@ -210,3 +210,4 @@ testdir = os.path.join(pubmed_path, "Archive", "01")
 if not os.path.isdir(testdir):
     print(f"ERROR: PubMed/Archive not found in {pubmed_path}")
     raise SystemExit(1)
+    raise SystemExit(1)
diff --git a/server.py b/server.py
index 46cd347..2a2b925 100755
--- a/server.py
+++ b/server.py
@@ -20,10 +20,26 @@ from flask import (Flask, Response, flash, jsonify, redirect, render_template,
                    request, session, url_for)
 from flask_sqlalchemy import SQLAlchemy
 
-from dotenv import load_dotenv
-load_dotenv()
 import os
-GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
+
+def _read_gemini_api_key():
+    """Read Gemini API key from ~/.config/gemini/credentials."""
+    import stat
+    cred_file = os.path.expanduser("~/.config/gemini/credentials")
+    try:
+        mode = os.stat(cred_file).st_mode & 0o777
+        if mode != 0o400:
+            print(f"ERROR: {cred_file} has permissions {oct(mode)}, expected 0400. Fix with: chmod 400 {cred_file}")
+            raise SystemExit(1)
+        with open(cred_file, 'r') as f:
+            key = f.read().strip()
+            if key:
+                return key
+    except FileNotFoundError:
+        pass
+    return None
+
+GEMINI_API_KEY = _read_gemini_api_key()
 
 # nltk.download('punkt') # we should prefetch
 # import pickle # Removed
@@ -117,11 +133,10 @@ with app.app_context():
     db.create_all()
 
 # Configure Gemini API Client
-# IMPORTANT: Set the GEMINI_API_KEY environment variable
-GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
+GEMINI_API_KEY = _read_gemini_api_key()
 gemini_client = None
 if not GEMINI_API_KEY:
-    print("Warning: GEMINI_API_KEY environment variable not set. Stress classification via Gemini will not work.")
+    print("Warning: ~/.config/gemini/credentials not found or empty. Stress classification via Gemini will not work.")
 else:
     try:
         gemini_client = genai.Client(api_key=GEMINI_API_KEY)
@@ -1927,7 +1942,7 @@ if __name__ == '__main__':
     args = parser.parse_args()
     print("GeneCup server starting...")
     print(f"  EDIRECT_PUBMED_MASTER={os.environ.get('EDIRECT_PUBMED_MASTER', '(not set)')}")
-    print(f"  GEMINI_API_KEY={'set' if os.environ.get('GEMINI_API_KEY') else '(not set)'}")
+    print(f"  GEMINI_API_KEY={'set (from ~/.config/gemini/credentials)' if GEMINI_API_KEY else '(not set)'}")
     print(f"  NLTK_DATA={os.environ.get('NLTK_DATA', '(not set)')}")
     print(f"  GENECUP_DATADIR={os.environ.get('GENECUP_DATADIR', '(not set, default: ./)')}")
     app.run(debug=args.debug, host='0.0.0.0', port=args.port)