Skip to content

Commit

Permalink
Hotfix for server title update and other stuff (#60)
Browse files Browse the repository at this point in the history
* some unittest fixes

* adding static folder

* creating info file

* fix for server title, caching
  • Loading branch information
Abellegese authored Mar 9, 2025
1 parent 0fc39b5 commit 0a9f7f7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
12 changes: 5 additions & 7 deletions src/ersilia_pack/templates/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import sys

from typing import Any, Dict

from fastapi import Depends, FastAPI, Request
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from prometheus_fastapi_instrumentator import Instrumentator, metrics
from slowapi.middleware import SlowAPIMiddleware
Expand All @@ -17,16 +15,16 @@
from .exceptions.handlers import register_exception_handlers
from .middleware.rcontext import RequestContextMiddleware
from .routers import docs, metadata, run, health
from .utils import get_metadata, create_limiter, init_redis
from .utils import get_sync_metadata, create_limiter, init_redis

sys.path.insert(0, ROOT)

limiter = create_limiter()


metadata_card = get_sync_metadata()["card"]
app = FastAPI(
title="Ersilia Pack Model Server",
description=API_DESCIPTION,
title=f"{metadata_card['Identifier']}:{metadata_card['Slug']} Server",
description=f"{metadata_card['Title']}. {API_DESCIPTION}",
docs_url=None,
redoc_url=None,
)
Expand Down
5 changes: 4 additions & 1 deletion src/ersilia_pack/templates/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
REDOC_JS_URL = "https://unpkg.com/redoc@next/bundles/redoc.standalone.js"
MATE_CSS_URL = "https://cdn.jsdelivr.net/gh/ajatkj/swagger-ui-improved-theme/css/swagger-ui-improved.css"
API_DESCIPTION = """
Ersilia Pack is an open-source model serving framework built for researchers and scientists, offering endpoints for seamless model deployment and monitoring. It provides `/metrics` for Prometheus-based performance insights, `/metadata`\n for detailed model information, and `/info` to quickly retrieve the prediction endpoint name. The core `/run` endpoint offers sub-routes for example inputs/outputs, input/output column details, and a POST method that handles\n predictions with dynamic resource planning and multiprocessing. Additionally, the `/health` endpoint delivers system status and circuit breaker information—which trips after five consecutive failures with a 30-second reset—while enforcing a rate-\nlimit of 100 requests per minute.
This server offers endpoints for seamless model deployment and monitoring. It provides `/metrics` for Prometheus-based performance insights, `/metadata`\n for detailed model information, and `/info` to quickly retrieve the prediction endpoint name. The core `/run` endpoint offers sub-routes for example inputs/outputs, input/output column details, and a POST method that handles\n predictions with dynamic resource planning and multiprocessing. Additionally, the `/health` endpoint delivers system status and circuit breaker information—which trips after five consecutive failures with a 30-second reset—while enforcing a rate-\nlimit of 100 requests per minute.
"""
FRAMEWORK_FOLDER = os.path.abspath(os.path.join(ROOT, "..", "model", "framework"))
MODEL_ROOT = os.path.abspath(os.path.join(ROOT, "..", "model"))
Expand Down Expand Up @@ -76,8 +76,11 @@ class OrientEnum(str, Enum):
class CardField(str, Enum):
identifier = "Identifier"
slug = "Slug"
title = "Title"
description = "Description"
input = "Input"
task = "Task"
subtask = "Subtask"


API_ID = str(uuid.uuid4())
Expand Down
28 changes: 19 additions & 9 deletions src/ersilia_pack/templates/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ def values_serializer(values):
record = collections.OrderedDict()
for j in range(len(columns)):
record[columns[j]] = values_serializer([values[i][j]])[0]
key = make_hashable(index[i])
data[key] = record
data[index[i]] = record
return data

elif orient == "columns":
Expand Down Expand Up @@ -177,7 +176,7 @@ def get_api_names_from_sh(framework_dir):
def get_example_path(example_file):
example_path = os.path.join(FRAMEWORK_FOLDER, "examples", example_file)
api_name = get_api_names_from_sh(FRAMEWORK_FOLDER)
if api_name:
if api_name:
api_name = api_name[0]
if not os.path.exists(example_path):
example_path = os.path.join(
Expand All @@ -203,6 +202,12 @@ async def get_metadata():
return data["card"]


def get_sync_metadata():
file_path = os.path.join(BUNDLE_FOLDER, "information.json")
contents = _read_file(file_path)
return json.loads(contents)


def read_example():
example_input_path = get_example_path(generic_example_input_file)
if not os.path.exists(example_input_path):
Expand Down Expand Up @@ -301,14 +306,19 @@ def get_cpu_count(logical):


def run_in_parallel(num_workers, tag, chunks):
num_tasks = len(chunks)
chunksize = max(1, num_tasks // (num_workers * 4))

with multiprocessing.Pool(processes=num_workers) as pool:
chunk_args = [(chunk, idx, tag) for idx, chunk in enumerate(chunks)]
processed = pool.starmap_async(process_chunk, chunk_args, chunksize=1)
_results = processed.get()
results, headers = [], []
for result, header in _results:
results.extend(result)
headers.append(header)
async_result = pool.starmap_async(process_chunk, chunk_args, chunksize=chunksize)
results_headers = async_result.get()

results, headers = [], []
for result, header in results_headers:
results.extend(result)
headers.append(header)

return results, headers[0]


Expand Down

0 comments on commit 0a9f7f7

Please sign in to comment.