diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..acdd4d5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM openjdk:8-jdk as buildContainer + +RUN apt-get update +RUN apt-get install -y maven + +WORKDIR /opt/app +COPY . /opt/app + +RUN chmod +x ./make.sh +RUN bash ./make.sh + +CMD bash \ No newline at end of file diff --git a/README.md b/README.md index c6e00ea..3a06723 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ target/lychi-0.5.1-jar-with-dependencies.jar The self-contained jar file can be invoked directly. For example: ``` -java -jar target/lychi-0.5.1-jar-with-dependencies.jar tests/standardizer_case1.smi +java -jar target/lychi-0.7.1-jar-with-dependencies.jar tests/standardizer_case1.smi ``` diff --git a/api/api.py b/api/api.py new file mode 100644 index 0000000..d17b068 --- /dev/null +++ b/api/api.py @@ -0,0 +1,55 @@ +from flask import Flask, request, jsonify, render_template +import subprocess +import tempfile +import os + +lychify = Flask("lychify") + +@lychify.route('/') +def index(): + return render_template('index.html') + +@lychify.route('/standardize', methods=['POST']) +def standardize(): + # Get the list of SMILES objects from the request + smiles_list = request.json['smiles_list'] + counter = 0 + if len(smiles_list) == 0: + return jsonify({'result': []}) + # Write the SMILES objects to a temporary file + with tempfile.NamedTemporaryFile(delete=False, mode='w') as f: + for obj in smiles_list: + if ("id" in obj): + f.write(obj['smiles'] + '\t' + str(obj['id']) + '\n') + else: + counter += 1 + f.write(obj["smiles"] + '\t' + "no_id:" + str(counter) + '\n') + filepath = f.name + + # Create the command to call the Java application with the input file + command = ['java', '-jar', 'lychi-0.7.1-jar-with-dependencies.jar', filepath] + + # Call the Java application using subprocess + process = subprocess.run(command, capture_output=True, text=True) + + # Remove the temporary file + os.remove(filepath) + + # Check if the command completed successfully + if process.returncode != 0: + return jsonify({'error': 'Failed to run Java application', + 'output': process.stdout.strip().split('\n')}) + + # Parse the output from the Java application and format the response + output = process.stdout.strip().split('\n') + formatted_output = [] + for i, line in enumerate(output): + smiles, id, lychi = line.split('\t') + formatted_output.append({'smiles': smiles, 'id': id, 'lychi': lychi}) + + # Return the formatted output as a JSON response + return jsonify({'result': formatted_output}) + + +if __name__ == '__main__': + lychify.run(debug=True) diff --git a/api/lychi-0.7.1-jar-with-dependencies.jar b/api/lychi-0.7.1-jar-with-dependencies.jar new file mode 100644 index 0000000..9389281 Binary files /dev/null and b/api/lychi-0.7.1-jar-with-dependencies.jar differ diff --git a/api/templates/index.html b/api/templates/index.html new file mode 100644 index 0000000..49594fb --- /dev/null +++ b/api/templates/index.html @@ -0,0 +1,18 @@ + + +
+This is a web service to calculate lychi keys for any given chemical structure. See the repo here: https://github.com/ncats/lychi.
+To use this application, send a POST request to /standardize with a JSON payload containing a list of SMILES strings. The response will contain a JSON payload with the standardized SMILES strings.
+Here's an example payload:
+{
+ "smiles_list": [
+ {"smiles": "CCO", "id": "1"},
+ {"smiles": "COC", "id": "2"}
+ ]
+}
+
+
diff --git a/api/testapi.py b/api/testapi.py
new file mode 100644
index 0000000..3699780
--- /dev/null
+++ b/api/testapi.py
@@ -0,0 +1,31 @@
+import requests
+
+url = 'http://localhost:5000/standardize'
+
+response = requests.post(url, json={'smiles_list': []})
+print (response.json())
+
+long_smiles = "".join(['C' for i in range(10)])
+response = requests.post(url, json={'smiles_list': [{"smiles": long_smiles}]})
+print(response.json())
+
+invalid_list = [
+ {'smiles':'invalid','id':'1'},
+ {'smiles':'SMILES','id':'2'},
+ {'smiles':'strings','id':'3'}
+]
+response = requests.post(url, json={'smiles_list': invalid_list})
+print(response.json()) # Should return an error message or an empty result
+
+duplicate_list = [
+ {"smiles": "C", "id": "1"},
+ {"smiles": "CC", "id": "2"},
+ {"smiles": "C", "id": "3"},
+ {"smiles": "CCC", "id": "4"}
+]
+response = requests.post(url, json={'smiles_list': duplicate_list})
+print(response.json())
+
+aminophylline = [{"smiles":"Cn1c2nc[nH]c2c(=O)n(C)c1=O", "id": "aminophylline"}]
+response = requests.post(url, json={'smiles_list': aminophylline})
+print(response.json())
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..88786f3
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,7 @@
+version: '3'
+services:
+ dev:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ tty: true
\ No newline at end of file