Skip to content

Commit

Permalink
Merge branch 'jh-dev-exp' into jh-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jayeshhireox committed Oct 6, 2024
2 parents 20b3977 + 810c720 commit ca8d742
Show file tree
Hide file tree
Showing 10 changed files with 784 additions and 839 deletions.
2 changes: 1 addition & 1 deletion Dockerfile-local
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ EXPOSE 5055

# Command to run Gunicorn
#CMD ["poetry", "run", "gunicorn", "-w", "1", "-b", "0.0.0.0:5055", "mdvtools.dbutils.mdv_server_app:app"]
CMD ["poetry", "run", "python", "-m", "mdvtools.dbutils.mdv_server_app"]
CMD ["poetry", "run", "python", "-u", "-m", "mdvtools.dbutils.mdv_server_app"]


9 changes: 8 additions & 1 deletion docker-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ services:
mdv_app:
build:
context: .
dockerfile: Dockerfile
dockerfile: Dockerfile-local
#image: jayeshire/mdv-frontend:latest
ports:
- "5055:5055"
volumes:
- ./python:/app/python
- mdv-data:/app/mdv
- ./secrets/db_user:/run/secrets/db_user:ro
- ./secrets/db_password:/run/secrets/db_password:ro
- ./secrets/db_name:/run/secrets/db_name:ro
environment:
- FLASK_ENV=development
- FLASK_DEBUG=1
- PYTHONUNBUFFERED=1
depends_on:
- mdv_db
restart: always


mdv_db:
Expand All @@ -26,6 +32,7 @@ services:
POSTGRES_USER_FILE: /run/secrets/db_user
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
POSTGRES_DB_FILE: /run/secrets/db_name
restart: always


volumes:
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"python-setup": "python -m venv venv && source venv/bin/activate && cd python && poetry install --with dev && npm run build-flask-vite",
"mdv_desktop": "source venv/bin/activate && python -m mdvtools.mdv_desktop",
"docker_build": "docker-compose build && docker-compose -f docker-compose-dev.yml up -d --force-recreate",
"docker_dev": "docker-compose -f docker-compose-dev.yml up -d --force-recreate",
"docker_dev": "docker-compose -f docker-local.yml up -d --force-recreate",
"docker_purge": "docker rm -f $(docker ps -a -q) && docker rmi -f $(docker images -q) && docker volume rm $(docker volume ls -q)",
"docker_stack_rm": "docker stack rm mdv_stack",
"docker_createandpush": "docker build -t my_mdv_app_image:latest . && docker tag my_mdv_app_image:latest jayeshire/my_mdv_app_image:latest && docker push jayeshire/my_mdv_app_image:latest",
"docker_stack_deploy": "docker stack deploy -c docker-compose-stack.yml mdv_stack",
Expand Down
Empty file.
Empty file.
Empty file.
4 changes: 2 additions & 2 deletions python/mdvtools/dbutils/test/unit/test_dbservice.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import unittest
from unittest.mock import patch, MagicMock
from project_service import ProjectService, FileService
from mdvtools.dbutils.dbservice import ProjectService, FileService
from mdvtools.dbutils.dbmodels import Project, File
from datetime import datetime

class TestProjectService(unittest.TestCase):

@patch('project_service.Project.query')
@patch('mdvtools.dbutils.dbmodels.Project.query')
def test_get_active_projects_success(self, mock_query):
mock_query.filter_by.return_value.all.return_value = [MagicMock(), MagicMock()]
result = ProjectService.get_active_projects()
Expand Down
85 changes: 72 additions & 13 deletions python/mdvtools/mdvproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .charts.view import View
import time
import copy
from mdvtools.dbutils.dbservice import ProjectService, FileService

DataSourceName = str # NewType("DataSourceName", str)
ColumnName = str # NewType("ColumnName", str)
Expand Down Expand Up @@ -259,7 +260,7 @@ def add_images_to_datasource(
print(f"Added image set {name} to {ds} datasource")
self.set_datasource_metadata(ds_metadata)

def add_or_update_image_datasource(self, tiff_metadata, datasource_name):
def add_or_update_image_datasource(self, tiff_metadata, datasource_name, file, project_id):
"""Add or update an image datasource in datasources.json"""
try:
# Load current datasources
Expand All @@ -272,36 +273,92 @@ def add_or_update_image_datasource(self, tiff_metadata, datasource_name):
# Update the existing datasource and check the result
update_success = self.update_datasource(datasource, tiff_metadata)
if not update_success:
error_message = "update_datasource failed"
print(f"Failed to update datasource '{datasource_name}'.")
return False
else:
# Create a new datasource
# Uncomment and implement the following line if needed
# creation_success = self.create_new_datasource(tiff_metadata, datasource_name)
print(f"Datasource '{datasource_name}' does not exist and creation is not implemented yet.")
print(f"Datasource '{datasource_name}' does not exist")
return False

# Upload the TIFF file only if the datasource update was successful
upload_success = self.upload_image_file(file, project_id)
if not upload_success:
print(f"Failed to upload TIFF file for datasource '{datasource_name}'.")
return False

# If both update and upload succeed, return True
#file_path = ''
#db_update_success = FileService.add_or_update_file_in_project(
# file_name=file.filename,
# file_path=file.filename, # Assuming 'file_path' is the filename in this example, adjust as necessary
# project_id=project_id
#)
return True
except Exception as e:
print(f"Error updating or adding datasource '{datasource_name}': {e}")
return False

def upload_image_file(self, file, project_id):
"""Upload the TIFF file to the imagefolder, saving it with the original filename."""
try:
# Define the target folder inside imagefolder (e.g., /images/avivator)
target_folder = os.path.join(self.imagefolder, 'avivator')
print(target_folder)
# Ensure the target folder exists
if not os.path.exists(target_folder):
os.makedirs(target_folder)

# Get the original filename from the file
original_filename = file.filename # This will give you the name of the uploaded file

# Create the full file path inside /images/avivator
file_path = os.path.join(target_folder, original_filename)

# Save the file to the /images/avivator folder
file.save(file_path)
print(f"File uploaded successfully to {file_path}")

# Update the database with the file information
db_file = FileService.add_or_update_file_in_project(
file_name=original_filename,
file_path=file_path, # The full path where the file was saved
project_id=project_id
)

# Check if the file was successfully added or updated in the database
if db_file is None:
raise ValueError(f"Failed to add file '{original_filename}' to the database.")
else:
print(f"Added file to DB: {db_file}")

return True
except Exception as e:
print(f"Error uploading file: {e}")
return False


def update_datasource(self, datasource, tiff_metadata):
"""Update an existing datasource with new image metadata."""
try:
# Extract image metadata from tiff_metadata
width = tiff_metadata['OME']['Image']['Pixels']['SizeX']
height = tiff_metadata['OME']['Image']['Pixels']['SizeY']
scale = tiff_metadata['OME']['Image']['Pixels']['PhysicalSizeX']
scale_unit = tiff_metadata['OME']['Image']['Pixels'].get('PhysicalSizeUnit', 'µm') # Default to µm if not present

print("*****1")

# Corrected path to access size and scale information
pixels_data = tiff_metadata['Pixels']
width = pixels_data['SizeX']
height = pixels_data['SizeY']
scale = pixels_data['PhysicalSizeX']
scale_unit = pixels_data.get('PhysicalSizeXUnit', 'µm') # Default to µm if not present

print("*****2")
# Ensure datasource has a 'regions' field
if "regions" not in datasource:
datasource["regions"] = {"all_regions": {}}

# Determine region name
region_name = tiff_metadata.get('name', 'unknown') # Default to 'unknown' if not present in metadata
region_name = tiff_metadata.get('Name', 'unknown') # Use 'Name' from metadata or 'unknown'

# Define new region with metadata
new_region = {
Expand All @@ -324,25 +381,27 @@ def update_datasource(self, datasource, tiff_metadata):
}

image_metadata = {
'path': tiff_metadata['path']
'path': tiff_metadata.get('path', '') # Use the 'path' key if it exists, or default to ''
}

# Update or add the region in the datasource
datasource["regions"]["all_regions"][region_name] = new_region
datasource['size'] = len(datasource['regions']['all_regions'])

print("*****3")
# Save the updated datasource
self.set_datasource_metadata(datasource)

print("*****4")
# Update views and images
self.add_viv_viewer(region_name, [{'name': 'DAPI'}])
self.add_viv_images(region_name, image_metadata, link_images=True)
#self.add_viv_viewer(region_name, [{'name': 'DAPI'}])
#self.add_viv_images(region_name, image_metadata, link_images=True)

print(f"Datasource '{datasource.get('name', 'unknown')}' updated successfully.")
return True
except Exception as e:
print(f"Error updating datasource '{datasource.get('name', 'unknown')}': {e}")
return False




Expand Down
39 changes: 26 additions & 13 deletions python/mdvtools/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,24 +248,37 @@ def save_data():
@project_bp.route("/add_or_update_image_datasource", methods=["POST"])
def add_or_update_image_datasource():
try:
# Extract data from the request
data = request.json
if not data:
return "Request must contain JSON data with tiffMetadata & datasourceName", 400
tiff_metadata = data.get('tiffMetadata')
datasource_name = data.get('datasourceName')

if not tiff_metadata or not datasource_name:
return "Request must contain JSON data with tiffMetadata & datasourceName", 400
# Check if request has a file part
if 'file' not in request.files:
return "No file part in the request", 400

# Get the file from the request
file = request.files['file']

# Get the text fields from the request form
datasource_name = request.form.get('datasourceName') # ""
tiff_metadata = request.form.get('tiffMetadata')

# Validate the presence of required fields
if not file or not tiff_metadata:
return jsonify({"status": "error", "message": "Missing file, tiffMetadata, or datasourceName"}), 400

# If tiff_metadata is sent as JSON string, deserialize it
try:
tiff_metadata = json.loads(tiff_metadata)
except Exception as e:
return jsonify({"status": "error", "message": f"Invalid JSON format for tiffMetadata: {e}"}), 400

# Call your method to add or update the image datasource
success = project.add_or_update_image_datasource(tiff_metadata, datasource_name, file, project.id)

# Call the method in the project class to add or update image datasource
success = project.add_or_update_image_datasource(tiff_metadata, datasource_name)
if success:
return "Image datasource updated successfully", 200
return jsonify({"status": "success", "message": "Image datasource updated and file uploaded successfully"}), 200
else:
return "Failed to update image datasource", 500
except Exception as e:
return str(e), 500
return jsonify({"status": "error", "message": str(e)}), 500


@project_bp.route("/add_datasource", methods=["POST"])
def add_datasource():
Expand Down
Loading

0 comments on commit ca8d742

Please sign in to comment.