Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Airtable field update and add unit testing #1514

Merged
merged 5 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/scripts/airtableops.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ def write_information(self, data: BaseInformation, readme_path=None):
text += "* Output Type: `{0}`\n".format(", ".join(d["Output Type"]))
text += "* Output Shape: `{0}`\n".format(d["Output Shape"])
text += "* Interpretation: {0}\n\n".format(d["Interpretation"])
text += "## Baseline Performance\n\n"
text += "* Computational Performance For One Input: `{0}`\n".format(d["Computational Performance 1"])
text += "* Computational Performance For Ten Input: `{0}`\n".format(d["Computational Performance 10"])
text += "* Computational Performance For Hundred Input: `{0}`\n".format(d["Computational Performance 100"])
text += "## References\n\n"
text += "* [Publication]({0})\n".format(d["Publication"])
text += "* [Source Code]({0})\n".format(d["Source Code"])
Expand Down Expand Up @@ -260,7 +264,6 @@ def insert_metadata_to_airtable(model, contributor, api_key):
airtable_data["Source Code"] = data["Source Code"]
ai.table.create(airtable_data)


def update_metadata_to_airtable(user, repo, branch, api_key):
# Works with airtable-update option
rm = RepoMetadataFile(model_id=repo, config_json=None)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests_and_cleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:

- name: Run pytest
run: |
pip install pytest pytest-benchmark pytest-asyncio rdkit-pypi nox rich fuzzywuzzy scipy
pip install pytest pytest-benchmark pytest-asyncio rdkit-pypi nox rich fuzzywuzzy scipy pyairtable
DhanshreeA marked this conversation as resolved.
Show resolved Hide resolved
pytest

run-cli-test-single:
Expand Down
254 changes: 252 additions & 2 deletions ersilia/hub/content/base_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
from ...utils.exceptions_utils.base_information_exceptions import (
BiomedicalAreaBaseInformationError,
BothIdentifiersBaseInformationError,
ComputationalPerformanceHundredBaseInformationError,
ComputationalPerformanceOneBaseInformationError,
ComputationalPerformanceTenBaseInformationError,
DescriptionBaseInformationError,
DockerArchitectureBaseInformationError,
DockerhubBaseInformationError,
EnvironmentSizeMbBaseInformationError,
GithubBaseInformationError,
IdentifierBaseInformationError,
ImageSizeMbBaseInformationError,
InputBaseInformationError,
InputShapeBaseInformationError,
LicenseBaseInformationError,
Expand Down Expand Up @@ -56,7 +61,78 @@ class BaseInformation(ErsiliaBase):
Configuration data in JSON format.
"""

def __init__(self, config_json):
def __init__(self, config_json=None):
"""
Initialize the base information object with a provided configuration.

Parameters
----------
config_json : dict
A JSON-compatible dictionary containing configuration data.

Attributes
----------
_github : None
Placeholder for GitHub-related data.
_identifier : None
Placeholder for a unique identifier string.
_slug : None
Placeholder for a descriptive slug string.
_status : None
Placeholder for the current status of the object.
_title : None
Placeholder for the object’s title.
_description : None
Placeholder for a description of the object.
_mode : None
Placeholder for the runtime mode.
_task : None
Placeholder for the primary task associated with this object.
_input : None
Placeholder for input data specifications.
_input_shape : None
Placeholder for the shape of the input data.
_output : None
Placeholder for output data specifications.
_output_type : None
Placeholder for the type of output data.
_output_shape : None
Placeholder for the shape of the output data.
_output_dimension : None
Placeholder for dimensional notes about the output.
_output_consistency : None
Placeholder for output consistency metrics.
_interpretation : None
Placeholder for interpretation details.
_tag : None
Placeholder for tag information.
_publication : None
Placeholder for publication references.
_source_code : None
Placeholder for source code metadata.
_license : None
Placeholder for license information.
_contributor : None
Placeholder for contributor information.
_dockerhub : None
Placeholder for Docker Hub repository details.
_docker_architecture : None
Placeholder for Docker image architecture details.
_s3 : None
Placeholder for related AWS S3 information.
_memory_gb : None
Placeholder for memory requirement in gigabytes.
_environment_size_mb : None
Placeholder for environment size in megabytes.
_image_size_mb : None
Placeholder for Docker image size in megabytes.
_computational_performance_one : None
Placeholder for single-run computational performance.
_computational_performance_ten : None
Placeholder for ten-run computational performance.
_computational_performance_hund : None
Placeholder for hundred-run computational performance.
"""
ErsiliaBase.__init__(self, config_json=config_json, credentials_json=None)
self._github = None
self._identifier = None
Expand All @@ -66,6 +142,11 @@ def __init__(self, config_json):
self._description = None
self._mode = None
self._task = None
self._subtask = None
DhanshreeA marked this conversation as resolved.
Show resolved Hide resolved
self._biomedical_area = None
self._target_organism = None
self._publication_type = None
self._publication_year = None
self._input = None
self._input_shape = None
self._output = None
Expand All @@ -83,6 +164,13 @@ def __init__(self, config_json):
self._docker_architecture = None
self._s3 = None
self._memory_gb = None
self._source = None
DhanshreeA marked this conversation as resolved.
Show resolved Hide resolved
self._source_type = None
self._environment_size_mb = None
self._image_size_mb = None
self._computational_performance_one = None
self._computational_performance_ten = None
self._computational_performance_hund = None

def _is_valid_url(self, url_string: str) -> bool:
result = validators.url(url_string)
Expand Down Expand Up @@ -1171,6 +1259,153 @@ def memory_gb(self, new_memory_gb):
raise MemoryGbBaseInformationError
self._memory_gb = new_memory_gb

@property
def environment_size(self):
"""
Get the model evironment Size in Mb.

Returns
-------
int
The model evironment Size in Mb.
"""
return self._environment_size_mb

@environment_size.setter
def environment_size(self, new_environment_size):
"""
Set the environment size in MB.

Parameters
----------
new_environment_size : int
The new environment size in MB.

Raises
------
EnvironmentSizeMbBaseInformationError
If the environment size value is not valid.
"""
if not isinstance(new_environment_size, (int, float)):
raise EnvironmentSizeMbBaseInformationError
self._environment_size_mb = new_environment_size

@property
def image_size_mb(self):
"""Get the image size in megabytes.

Returns
-------
int
The size of the image in MB.
"""
return self._image_size_mb

@image_size_mb.setter
def image_size_mb(self, new_image_size_mb):
"""Set the image size in megabytes.

Parameters
----------
new_image_size_mb : int
The new image size in MB.

Raises
------
ImageSizeMbBaseInformationError
If `new_image_size_mb` is not an integer.
"""
if not isinstance(new_image_size_mb, (int, float)):
raise ImageSizeMbBaseInformationError
self._image_size_mb = new_image_size_mb

@property
def computational_performance_one(self):
"""Get the computational performance at level one.

Returns
-------
int or float
The computational performance metric at level one.
"""
return self._computational_performance_one

@computational_performance_one.setter
def computational_performance_one(self, new_value):
"""Set the computational performance at level one.

Parameters
----------
new_value : int or float
The new computational performance value.

Raises
------
ComputationalPerformanceOneBaseInformationError
If `new_value` is not an int or float.
"""
if not isinstance(new_value, (int, float)):
raise ComputationalPerformanceOneBaseInformationError
self._computational_performance_one = new_value

@property
def computational_performance_ten(self):
"""Get the computational performance at level ten.

Returns
-------
int or float
The computational performance metric at level ten.
"""
return self._computational_performance_ten

@computational_performance_ten.setter
def computational_performance_ten(self, new_value):
"""Set the computational performance at level ten.

Parameters
----------
new_value : int or float
The new computational performance value.

Raises
------
ComputationalPerformanceTenBaseInformationError
If `new_value` is not an int or float.
"""
if not isinstance(new_value, (int, float)):
raise ComputationalPerformanceTenBaseInformationError
self._computational_performance_ten = new_value

@property
def computational_performance_hund(self):
"""Get the computational performance at level hundred.

Returns
-------
int or float
The computational performance metric at level hundred.
"""
return self._computational_performance_hund

@computational_performance_hund.setter
def computational_performance_hund(self, new_value):
"""Set the computational performance at level hundred.

Parameters
----------
new_value : int or float
The new computational performance value.

Raises
------
ComputationalPerformanceHundredBaseInformationError
If `new_value` is not an int or float.
"""
if not isinstance(new_value, (int, float)):
raise ComputationalPerformanceHundredBaseInformationError
self._computational_performance_hund = new_value

def as_dict(self):
"""
Convert the model information to a dictionary.
Expand Down Expand Up @@ -1212,6 +1447,11 @@ def as_dict(self):
"Docker Architecture": self.docker_architecture,
"S3": self.s3,
"Memory Gb": self.memory_gb,
"Environment Size": self.environment_size,
"Image Size": self.image_size_mb,
"Computational Performance 1": self.computational_performance_one,
"Computational Performance 10": self.computational_performance_ten,
"Computational Performance 100": self.computational_performance_hund,
}
data = dict((k, v) for k, v in data.items() if v is not None)
return data
Expand Down Expand Up @@ -1258,4 +1498,14 @@ def from_dict(self, data):
self._assign("dockerhub", "DockerHub", data)
self._assign("docker_architecture", "Docker Architecture", data)
self._assign("s3", "S3", data)
self._assign("memory_gb", "Memory Gb", data)
self._assign("environment_size", "Environment Size", data)
self._assign("image_size_mb", "Image Size", data)
self._assign(
"computational_performance_one", "Computational Performance 1", data
)
self._assign(
"computational_performance_ten", "Computational Performance 10", data
)
self._assign(
"computational_performance_hund", "Computational Performance 100", data
)
35 changes: 35 additions & 0 deletions ersilia/utils/exceptions_utils/base_information_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,38 @@ def __init__(self):
self.message = "Memory Gb field error"
self.hints = "Memory Gb field must be specified as an integer indicating GB of memory limit"
ErsiliaError.__init__(self, self.message, self.hints)


class EnvironmentSizeMbBaseInformationError(ErsiliaError):
def __init__(self):
self.message = "Environment Size field error"
self.hints = "Environment Size field must be specified as a valid numeric value indicating MB of model environment and dependencies"
ErsiliaError.__init__(self, self.message, self.hints)


class ImageSizeMbBaseInformationError(ErsiliaError):
def __init__(self):
self.message = "Image Size field error"
self.hints = "Image Size field must be specified as a valid numeric value indicating MB of model docker image"
ErsiliaError.__init__(self, self.message, self.hints)


class ComputationalPerformanceOneBaseInformationError(ErsiliaError):
def __init__(self):
self.message = "Computational Performance One field error"
self.hints = "Computational Performance field must be specified as a valid numeric value indicating the 1 input prediction per second"
ErsiliaError.__init__(self, self.message, self.hints)


class ComputationalPerformanceTenBaseInformationError(ErsiliaError):
def __init__(self):
self.message = "Computational Performance Ten field error"
self.hints = "Computational Performance field must be specified as a valid numeric value indicating the 10 input prediction per second"
ErsiliaError.__init__(self, self.message, self.hints)


class ComputationalPerformanceHundredBaseInformationError(ErsiliaError):
def __init__(self):
self.message = "Computational Performance Hundred field error"
self.hints = "Computational Performance field must be specified as a valid numeric value indicating the 100 input prediction per second"
ErsiliaError.__init__(self, self.message, self.hints)
Loading
Loading