Jaimodiji commited on
Commit
a1417c9
·
verified ·
1 Parent(s): 8b4755a

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +37 -30
Dockerfile CHANGED
@@ -1,86 +1,93 @@
1
  # 1. Base Image
2
  FROM python:3.9-slim
3
 
4
- # 2. System dependencies for Java (STOUT) and RDKit
5
- RUN apt-get update && apt-get install -y \
6
- openjdk-17-jdk-headless \
7
  libxrender1 \
8
  libxext6 \
 
 
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
- # 3. Environment variables
12
  ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
13
  PATH=$JAVA_HOME/bin:$PATH \
14
  TF_ENABLE_ONEDNN_OPTS=1 \
15
- HOME=/home/user \
16
- PATH=/home/user/.local/bin:$PATH
17
 
18
  # 4. Hugging Face User Setup (UID 1000)
19
  RUN useradd -m -u 1000 user
20
  USER user
21
  WORKDIR /home/user/app
 
22
 
23
- # 5. Install Python Stack
24
- RUN pip install --no-cache-dir \
 
25
  fastapi uvicorn gunicorn STOUT-pypi rdkit-pypi "numpy<2.0"
26
 
27
- # 6. Create app.py using 'cat'
28
  RUN cat <<EOF > app.py
29
  from fastapi import FastAPI, HTTPException, Body
30
  from STOUT import translate_forward, translate_reverse
31
  from rdkit import Chem
32
  from typing import List
 
33
 
34
  app = FastAPI(title="STOUT V2 API")
35
 
36
  def clean_smi(s):
37
- m = Chem.MolFromSmiles(s)
38
- if not m: raise ValueError("Invalid")
39
- return Chem.MolToSmiles(m, isomericSmiles=True)
 
 
40
 
41
  @app.get("/")
42
  def root():
43
  return {
44
  "message": "STOUT V2 API - SMILES to IUPAC Translator",
45
  "endpoints": {
46
- "/smiles_to_iupac": "GET/POST - Convert SMILES to IUPAC name",
47
- "/iupac_to_smiles": "GET/POST - Convert IUPAC name to SMILES",
48
- "/batch/smiles_to_iupac": "POST - Convert multiple SMILES to IUPAC names",
49
- "/batch/iupac_to_smiles": "POST - Convert multiple IUPAC names to SMILES",
50
- "/health": "GET - Health check"
51
  }
52
  }
53
 
54
  @app.api_route("/smiles_to_iupac", methods=["GET", "POST"])
55
  def s2i(smiles: str):
56
- try:
57
- return {"smiles": smiles, "iupac": translate_forward(clean_smi(smiles))}
58
- except: raise HTTPException(400, "Invalid SMILES")
59
 
60
  @app.api_route("/iupac_to_smiles", methods=["GET", "POST"])
61
  def i2s(iupac: str):
62
- try:
63
- return {"iupac": iupac, "smiles": translate_reverse(iupac)}
64
  except: raise HTTPException(400, "Invalid IUPAC")
65
 
66
  @app.post("/batch/smiles_to_iupac")
67
  def batch_s2i(smiles_list: List[str] = Body(...)):
68
- return [{"smiles": s, "iupac": translate_forward(clean_smi(s))} for s in smiles_list if Chem.MolFromSmiles(s)]
69
-
70
- @app.post("/batch/iupac_to_smiles")
71
- def batch_i2s(iupac_list: List[str] = Body(...)):
72
- return [{"iupac": i, "smiles": translate_reverse(i)} for i in iupac_list]
 
 
 
73
 
74
  @app.get("/health")
75
  def health(): return {"status": "healthy"}
76
-
77
  EOF
78
 
79
- # 7. Expose Port and Start Gunicorn with 4 Workers
80
  EXPOSE 7860
81
 
 
82
  CMD ["gunicorn", "app:app", \
83
  "--workers", "4", \
84
  "--worker-class", "uvicorn.workers.UvicornWorker", \
85
  "--bind", "0.0.0.0:7860", \
86
- "--timeout", "200"]
 
1
  # 1. Base Image
2
  FROM python:3.9-slim
3
 
4
+ # 2. System dependencies (Updated package names for better compatibility)
5
+ RUN apt-get update && apt-get install -y --no-install-recommends \
6
+ openjdk-17-jre-headless \
7
  libxrender1 \
8
  libxext6 \
9
+ gcc \
10
+ python3-dev \
11
  && rm -rf /var/lib/apt/lists/*
12
 
13
+ # 3. Environment variables (Java path usually ends in /jre on slim images)
14
  ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
15
  PATH=$JAVA_HOME/bin:$PATH \
16
  TF_ENABLE_ONEDNN_OPTS=1 \
17
+ HOME=/home/user
 
18
 
19
  # 4. Hugging Face User Setup (UID 1000)
20
  RUN useradd -m -u 1000 user
21
  USER user
22
  WORKDIR /home/user/app
23
+ ENV PATH=/home/user/.local/bin:$PATH
24
 
25
+ # 5. Install Python Stack (Explicitly install wheel first)
26
+ RUN pip install --no-cache-dir wheel && \
27
+ pip install --no-cache-dir \
28
  fastapi uvicorn gunicorn STOUT-pypi rdkit-pypi "numpy<2.0"
29
 
30
+ # 6. Create app.py
31
  RUN cat <<EOF > app.py
32
  from fastapi import FastAPI, HTTPException, Body
33
  from STOUT import translate_forward, translate_reverse
34
  from rdkit import Chem
35
  from typing import List
36
+ import os
37
 
38
  app = FastAPI(title="STOUT V2 API")
39
 
40
  def clean_smi(s):
41
+ try:
42
+ m = Chem.MolFromSmiles(s)
43
+ if not m: return None
44
+ return Chem.MolToSmiles(m, isomericSmiles=True)
45
+ except: return None
46
 
47
  @app.get("/")
48
  def root():
49
  return {
50
  "message": "STOUT V2 API - SMILES to IUPAC Translator",
51
  "endpoints": {
52
+ "/smiles_to_iupac": "GET/POST",
53
+ "/iupac_to_smiles": "GET/POST",
54
+ "/batch/smiles_to_iupac": "POST",
55
+ "/health": "GET"
 
56
  }
57
  }
58
 
59
  @app.api_route("/smiles_to_iupac", methods=["GET", "POST"])
60
  def s2i(smiles: str):
61
+ s = clean_smi(smiles)
62
+ if not s: raise HTTPException(400, "Invalid SMILES")
63
+ return {"smiles": smiles, "iupac": translate_forward(s)}
64
 
65
  @app.api_route("/iupac_to_smiles", methods=["GET", "POST"])
66
  def i2s(iupac: str):
67
+ try: return {"iupac": iupac, "smiles": translate_reverse(iupac)}
 
68
  except: raise HTTPException(400, "Invalid IUPAC")
69
 
70
  @app.post("/batch/smiles_to_iupac")
71
  def batch_s2i(smiles_list: List[str] = Body(...)):
72
+ results = []
73
+ for s in smiles_list:
74
+ clean = clean_smi(s)
75
+ if clean:
76
+ results.append({"smiles": s, "iupac": translate_forward(clean)})
77
+ else:
78
+ results.append({"smiles": s, "iupac": "Invalid SMILES"})
79
+ return results
80
 
81
  @app.get("/health")
82
  def health(): return {"status": "healthy"}
 
83
  EOF
84
 
85
+ # 7. Expose Port and Start Gunicorn
86
  EXPOSE 7860
87
 
88
+ # We use 4 workers to match your C3 8vCPU/32GB RAM instance
89
  CMD ["gunicorn", "app:app", \
90
  "--workers", "4", \
91
  "--worker-class", "uvicorn.workers.UvicornWorker", \
92
  "--bind", "0.0.0.0:7860", \
93
+ "--timeout", "300"]