Skip to content

Commit

Permalink
Merge branch 'drop-python3.7-support' of https://github.com/Darkbeast…
Browse files Browse the repository at this point in the history
…-glitch/ersilia into drop-python3.7-support
  • Loading branch information
Darkbeast-glitch committed Oct 14, 2024
2 parents 772b6f4 + b3b2772 commit 50c986b
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 80 deletions.
6 changes: 3 additions & 3 deletions ersilia/cli/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def catalog(self):
m = importlib.import_module("ersilia.cli.commands.catalog")
m.catalog_cmd()

def clear(self):
m = importlib.import_module("ersilia.cli.commands.clear")
m.clear_cmd()
def uninstall(self):
m = importlib.import_module("ersilia.cli.commands.uninstall")
m.uninstall_cmd()

def close(self):
m = importlib.import_module("ersilia.cli.commands.close")
Expand Down
15 changes: 11 additions & 4 deletions ersilia/cli/commands/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def catalog_cmd():
help="Show more information than just the EOS identifier",
)
@click.option(
"--card",
"--card",
is_flag=True,
default=False,
help="Use this flag to display model card for a given model ID",
Expand All @@ -40,9 +40,15 @@ def catalog_cmd():
type=click.STRING,
required=False,
)
@click.option(
"--as-table",
is_flag=True,
default=False,
help="Show catalog in table format",
)
def catalog(
local=False, file_name=None, browser=False, more=False, card=False, model=None
):
local=False, file_name=None, browser=False, more=False, card=False, model=None, as_table=False
):
if card and not model:
click.echo(
click.style("Error: --card option requires a model ID", fg="red"),
Expand Down Expand Up @@ -80,6 +86,7 @@ def catalog(
mc.airtable()
return
catalog_table = mc.local() if local else mc.hub()

if local and not catalog_table.data:
click.echo(
click.style(
Expand All @@ -89,7 +96,7 @@ def catalog(
)
return
if file_name is None:
catalog = catalog_table.as_json()
catalog = catalog_table.as_table() if as_table else catalog_table.as_json()
else:
catalog_table.write(file_name)
catalog = None
Expand Down
15 changes: 0 additions & 15 deletions ersilia/cli/commands/clear.py

This file was deleted.

15 changes: 15 additions & 0 deletions ersilia/cli/commands/uninstall.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from . import ersilia_cli
from ...utils.uninstall import Uninstaller


def uninstall_cmd():
"""Uninstalls all Ersilia artifacts present locally on the user's system"""

# Example usage: ersilia setup
@ersilia_cli.command(
short_help="Uninstall ersilia",
help="Uninstalls all Ersilia artifacts present locally on the user's system.",
)
def uninstall():
ui = Uninstaller()
ui.uninstall()
2 changes: 1 addition & 1 deletion ersilia/cli/create_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def create_ersilia_cli():

cmd.auth()
cmd.catalog()
cmd.clear()
cmd.uninstall()
cmd.close()
cmd.delete()
cmd.example()
Expand Down
18 changes: 18 additions & 0 deletions ersilia/default.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pathlib import Path
import shutil
import os
from enum import Enum

# EOS environmental variables
EOS = os.path.join(str(Path.home()), "eos")
Expand Down Expand Up @@ -29,6 +30,7 @@
DEFAULT_API_NAME = "run"
PACKMODE_FILE = "pack_mode.txt"
CARD_FILE = "card.json"
UNPROCESSABLE_INPUT="UNPROCESSABLE_INPUT"
DOTENV_FILE = ".env"
API_SCHEMA_FILE = "api_schema.json"
MODEL_SIZE_FILE = "size.json"
Expand Down Expand Up @@ -104,6 +106,22 @@
os.path.join(ROOT, "utils", "supp", _resolve_script), resolve_script
)

# Catalog table border constants
class TableConstants(str, Enum):
TOP_LEFT = "┌"
TOP_MIDDLE = "┬"
TOP_RIGHT = "┐"
HORIZONTAL = "─"
VERTICAL = "│"
MIDDLE_LEFT = "├"
MIDDLE_MIDDLE = "┼"
MIDDLE_RIGHT = "┤"
BOTTOM_LEFT = "└"
BOTTOM_MIDDLE = "┴"
BOTTOM_RIGHT = "┘"
CELL_PADDING = " "
COLUMN_SEPARATOR = " | "

snippet = (
"""
# >>> ersilia >>>
Expand Down
136 changes: 132 additions & 4 deletions ersilia/hub/content/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from ...utils.identifiers.model import ModelIdentifier
from ...auth.auth import Auth
from ...default import GITHUB_ORG, BENTOML_PATH, MODEL_SOURCE_FILE
from ...default import TableConstants
from ... import logger

try:
Expand Down Expand Up @@ -42,6 +43,122 @@ def as_json(self):
R = self.as_list_of_dicts()
return json.dumps(R, indent=4)

def generate_separator_line(self, left, middle, right, horizontal, widths):
"""
Generates a separator line for the table based on the given borders and column widths.
The line starts with a 'left' border, followed by repeated 'horizontal'
sections for each column's width, joined by 'middle' separators, and ends
with a 'right' border.
Args:
left (str): The character to use for the left border of the line.
middle (str): The character to use between columns (as separators).
right (str): The character to use for the right border of the line.
horizontal (str): The character used to draw the horizontal border.
widths (list[int]): A list of column widths to determine how much
horizontal space each column takes.
Returns:
str: The formatted separator line as a string.
"""
return left + middle.join(horizontal * (width + 2) for width in widths) + right

def as_table(self):
"""
Returns the catalog data in table format. The method calculates the
column widths dynamically by determining the maximum width of each column,
based on the data and column headers.
A row format string is then constructed using the column widths,
specifying that each cell is left-aligned and padded with a column seperator sperating the rows.
The method starts by constructing the top border using the
'generate_separator_line' helper. It then adds the headers,
formatted to fit the column widths, followed by a separator line
also created by the helper function.
A 'for' loop iterates over the data rows, adding each row to the
table with borders and padding. After each row, a separator line is inserted.
Finally, the bottom border is added using the helper function, completing the table.
"""
column_widths = [
max(
len(str(item)) if item is not None else 0
for item in [col] + [row[i] for row in self.data]
)
for i, col in enumerate(self.columns)
]

table_constants = TableConstants

row_format = table_constants.COLUMN_SEPARATOR.join(
f"{{:<{width}}}" for width in column_widths
)

table = (
self.generate_separator_line(
table_constants.TOP_LEFT,
table_constants.TOP_MIDDLE,
table_constants.TOP_RIGHT,
table_constants.HORIZONTAL,
column_widths,
)
+ "\n"
)
table += (
table_constants.VERTICAL
+ table_constants.CELL_PADDING
+ row_format.format(*self.columns)
+ table_constants.CELL_PADDING
+ table_constants.VERTICAL
+ "\n"
)
table += (
self.generate_separator_line(
table_constants.MIDDLE_LEFT,
table_constants.MIDDLE_MIDDLE,
table_constants.MIDDLE_RIGHT,
table_constants.HORIZONTAL,
column_widths,
)
+ "\n"
)

for index, row in enumerate(self.data):
row = [str(item) if item is not None else "" for item in row]
table += (
table_constants.VERTICAL
+ table_constants.CELL_PADDING
+ row_format.format(*row)
+ table_constants.CELL_PADDING
+ table_constants.VERTICAL
+ "\n"
)

if index < len(self.data) - 1:
table += (
self.generate_separator_line(
table_constants.MIDDLE_LEFT,
table_constants.MIDDLE_MIDDLE,
table_constants.MIDDLE_RIGHT,
table_constants.HORIZONTAL,
column_widths,
)
+ "\n"
)

table += self.generate_separator_line(
table_constants.BOTTOM_LEFT,
table_constants.BOTTOM_MIDDLE,
table_constants.BOTTOM_RIGHT,
table_constants.HORIZONTAL,
column_widths,
)

return table

def write(self, file_name):
with open(file_name, "w") as f:
if file_name.endswith(".csv"):
Expand Down Expand Up @@ -73,7 +190,7 @@ def _is_eos(self, s):
if not self.mi.is_test(s):
return True
return False

def _get_item(self, card, item):
if "card" in card:
card = card["card"]
Expand All @@ -100,15 +217,15 @@ def _get_input(self, card):

def _get_output(self, card):
return self._get_item(card, "output")[0]

def _get_model_source(self, model_id):
model_source_file = os.path.join(self._model_path(model_id), MODEL_SOURCE_FILE)
if os.path.exists(model_source_file):
with open(model_source_file) as f:
return f.read().rstrip()
else:
return None

def _get_service_class(self, card):
if "service_class" in card:
return card["service_class"]
Expand Down Expand Up @@ -207,7 +324,18 @@ def local(self):
output = self._get_output(card)
model_source = self._get_model_source(model_id)
service_class = self._get_service_class(card)
R += [[model_id, slug, title, status, inputs, output, model_source, service_class]]
R += [
[
model_id,
slug,
title,
status,
inputs,
output,
model_source,
service_class,
]
]
columns = [
"Identifier",
"Slug",
Expand Down
6 changes: 2 additions & 4 deletions ersilia/io/types/compound.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os
import csv
import random
import importlib

from ...utils.identifiers.arbitrary import ArbitraryIdentifier
from ...setup.requirements.compound import (
Expand All @@ -12,6 +11,7 @@
from ..shape import InputShapeSingle, InputShapeList, InputShapePairOfLists
from .examples import compound as test_examples
from . import EXAMPLES_FOLDER
from ...utils.identifiers.compound import CompoundIdentifier


EXAMPLES = "compound.tsv"
Expand All @@ -23,9 +23,7 @@ def __init__(self, input_shape):
self.input_shape = input_shape
self.example_file = os.path.join(EXAMPLES_FOLDER, EXAMPLES)
self.setup()
self.identifier = importlib.import_module(
"ersilia.utils.identifiers.compound"
).CompoundIdentifier()
self.identifier = CompoundIdentifier()
self.arbitrary_identifier = ArbitraryIdentifier()
if type(self.input_shape) is InputShapeSingle:
self.logger.debug(
Expand Down
2 changes: 1 addition & 1 deletion ersilia/setup/requirements/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self):
self.install()

def install(self):
run_command("python -m pip install rdkit-pypi")
run_command("python -m pip install rdkit==2023.9.1")


class ChemblWebResourceClientRequirement(object):
Expand Down
29 changes: 0 additions & 29 deletions ersilia/utils/clear.py

This file was deleted.

Loading

0 comments on commit 50c986b

Please sign in to comment.