Skip to content

Commit

Permalink
Added schemas, changed spoint to send results in json
Browse files Browse the repository at this point in the history
  • Loading branch information
Cbameron12 committed Jan 30, 2025
1 parent 1dd457c commit 4996970
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 20 deletions.
35 changes: 21 additions & 14 deletions api/endpoints/singlepoint_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,22 @@

import logging
from pathlib import Path
from typing import Any

from fastapi import APIRouter, HTTPException
from janus_core.helpers.janus_types import Architectures, Properties
from pydantic import BaseModel
from fastapi.responses import JSONResponse

from api.schemas.singlepoint_schemas import SinglePointRequest
from api.utils.singlepoint_helper import singlepoint

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/singlepoint", tags=["calculations"])


class SinglePointRequest(BaseModel):
"""Class validation for singlepoint requests."""

struct: str
arch: Architectures
properties: list[Properties]
range_selector: str
DATA_DIR = Path("/home/ubuntu/janus-api/janus-web/data")


@router.post("/")
def get_singlepoint(request: SinglePointRequest) -> dict[str, Any]:
async def get_singlepoint(request: SinglePointRequest):
"""
Endpoint to perform single point calculations and return results.
Expand All @@ -48,14 +40,29 @@ def get_singlepoint(request: SinglePointRequest) -> dict[str, Any]:
"""
base_dir = Path("data")
struct_path = base_dir / request.struct
logger.info("Request contents:", request)
logger.info(f"Request contents: {request}")

try:
return singlepoint(
results = singlepoint(
struct=struct_path,
arch=request.arch,
properties=request.properties,
range_selector=request.range_selector,
)

results_file_path = results.pop("results_path", None)
with results_file_path.open("rb") as file:
file_content = file.read()

return JSONResponse(
content={
"results": results,
"file": {
"filename": results_file_path.name,
"content": file_content.decode("utf-8"),
},
}
)
except Exception as e:
logger.error(e)
raise HTTPException(status_code=500, detail="Internal Server Error") from e
4 changes: 2 additions & 2 deletions api/endpoints/upload_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ async def upload_single(
"""
try:
file_content = await file.read()
logger.info(f"Hash matches: {calculate_md5_checksum(file_content, file_hash)}")

# Disabled hash check for now
# logger.info(f"Hash matches: {calculate_md5_checksum(file_content,file_hash)}")
save_file(file_content, file.filename)
except Exception as e:
logger.error(f"Error during file upload: {e}")
Expand Down
27 changes: 27 additions & 0 deletions api/schemas/singlepoint_schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Schemas for singlepoint calculation functions."""

from __future__ import annotations

from pathlib import Path

from janus_core.helpers.janus_types import Architectures, Properties
from pydantic import BaseModel


class SinglePointResults(BaseModel):
"""Class validation for singlepoint results."""

results_path: Path | None
forces: Properties | None
energy: Properties | None
stress: Properties | None
hessian: Properties | None


class SinglePointRequest(BaseModel):
"""Class validation for singlepoint requests."""

struct: str
arch: Architectures
properties: list[Properties]
range_selector: str
24 changes: 20 additions & 4 deletions api/utils/singlepoint_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
from janus_core.helpers.janus_types import Architectures, Properties
import numpy as np

from api.schemas.singlepoint_schemas import SinglePointResults

logger = logging.getLogger(__name__)

DATA_DIR = Path("/home/ubuntu/janus-api/janus-web/data")


def convert_ndarray_to_list(
data: dict[str, Any] | list | np.ndarray | float,
Expand Down Expand Up @@ -43,38 +47,50 @@ def singlepoint(
arch: Architectures | None = "mace_mp",
properties: list[Properties] | None = None,
range_selector: str | None = ":",
) -> dict[str, Any]:
write_results: bool | None = True,
results_path: Path | None = DATA_DIR / "results/",
) -> SinglePointResults:
"""
Perform single point calculations and return results.
Parameters
----------
struct : str
Filename of structure to simulate.
struct : Path
Path of structure to simulate.
arch : Architectures
MLIP architecture to use for single point calculations. Default is "mace_mp".
properties : List[Properties]
Physical properties to calculate. Default is ("energy", "forces", "stress").
range_selector : str
Range of indices to include from the structure. Default is all.
write_results : bool | None, default is True
Tells function if to save the results of the calculation or not.
results_path : Path | None
Location to save the results.
Returns
-------
dict[str, Any]
Results of the single point calculations.
"""
read_kwargs = {"index": range_selector}
results_path = results_path / f"{struct.stem}-results.extxyz"
write_kwargs = {"filename": results_path}

singlepoint_kwargs = {
"struct_path": struct,
"properties": properties,
"arch": arch,
"device": "cpu",
"read_kwargs": read_kwargs,
"write_results": write_results,
"write_kwargs": write_kwargs,
}

s_point = SinglePoint(**singlepoint_kwargs)

s_point.run()
results = convert_ndarray_to_list(s_point.results)
results["results_path"] = results_path

return convert_ndarray_to_list(s_point.results)
return results

0 comments on commit 4996970

Please sign in to comment.