Skip to content

Commit

Permalink
Merge pull request #136 from pepkit/133_tests
Browse files Browse the repository at this point in the history
133 tests
  • Loading branch information
khoroshevskyi authored Jun 28, 2024
2 parents 70f94fb + b2a1527 commit a19bbbf
Show file tree
Hide file tree
Showing 14 changed files with 1,331 additions and 1,068 deletions.
6 changes: 6 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format.

## [0.9.0] -- 2024-06-25
- Introduced new sample ordering with linked list [#133](https://github.com/pepkit/pepdbagent/issues/133)
- Efficiency improvements of project update function
- Test restructuring


## [0.8.0] -- 2024-02-26
- Fixed forking schema
- Improved forking efficiency [#129](https://github.com/pepkit/pepdbagent/issues/129)
Expand Down
2 changes: 1 addition & 1 deletion pepdbagent/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.8.0"
__version__ = "0.9.0"
12 changes: 12 additions & 0 deletions pepdbagent/db_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,15 @@ def check_db_connection(self):
self.session_execute(select(Projects).limit(1))
except ProgrammingError:
raise SchemaError()

def delete_schema(self, engine=None) -> None:
"""
Delete sql schema in the database.
:param engine: sqlalchemy engine [Default: None]
:return: None
"""
if not engine:
engine = self._engine
Base.metadata.drop_all(engine)
return None
9 changes: 8 additions & 1 deletion pepdbagent/modules/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def _get_samples(self, session: Session, prj_id: int, with_id: bool) -> List[Dic
for sample in samples_results:
sample_dict = sample.sample
if with_id:
sample_dict["ph_id"] = sample.guid
sample_dict[PEPHUB_SAMPLE_ID_KEY] = sample.guid

result_dict[sample.guid] = {
"sample": sample_dict,
Expand Down Expand Up @@ -477,6 +477,13 @@ def update(
is_private: Optional[bool]
tag: Optional[str]
name: Optional[str]
description: Optional[str]
is_private: Optional[bool]
pep_schema: Optional[str]
config: Optional[dict]
samples: Optional[List[dict]]
subsamples: Optional[List[List[dict]]]
pop: Optional[bool]
}
:param namespace: project namespace
:param name: project name
Expand Down
33 changes: 17 additions & 16 deletions pepdbagent/pepdbagent.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,47 +45,48 @@ def __init__(
)
sa_engine = pep_db_engine.engine

self.__sa_engine = sa_engine
self.pep_db_engine = pep_db_engine
self._sa_engine = sa_engine

self.__project = PEPDatabaseProject(pep_db_engine)
self.__annotation = PEPDatabaseAnnotation(pep_db_engine)
self.__namespace = PEPDatabaseNamespace(pep_db_engine)
self.__sample = PEPDatabaseSample(pep_db_engine)
self.__user = PEPDatabaseUser(pep_db_engine)
self.__view = PEPDatabaseView(pep_db_engine)
self._project = PEPDatabaseProject(pep_db_engine)
self._annotation = PEPDatabaseAnnotation(pep_db_engine)
self._namespace = PEPDatabaseNamespace(pep_db_engine)
self._sample = PEPDatabaseSample(pep_db_engine)
self._user = PEPDatabaseUser(pep_db_engine)
self._view = PEPDatabaseView(pep_db_engine)

self.__db_name = database
self._db_name = database

@property
def project(self) -> PEPDatabaseProject:
return self.__project
return self._project

@property
def annotation(self) -> PEPDatabaseAnnotation:
return self.__annotation
return self._annotation

@property
def namespace(self) -> PEPDatabaseNamespace:
return self.__namespace
return self._namespace

@property
def user(self) -> PEPDatabaseUser:
return self.__user
return self._user

@property
def sample(self) -> PEPDatabaseSample:
return self.__sample
return self._sample

@property
def view(self) -> PEPDatabaseView:
return self.__view
return self._view

def __str__(self):
return f"Connection to the database: '{self.__db_name}' is set!"

def __exit__(self):
self.__sa_engine.__exit__()
self._sa_engine.__exit__()

@property
def connection(self):
return self.__sa_engine
return self._sa_engine
6 changes: 4 additions & 2 deletions pepdbagent/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import ubiquerg
from peppy.const import SAMPLE_RAW_DICT_KEY

from .exceptions import RegistryPathError
from pepdbagent.exceptions import RegistryPathError


def is_valid_registry_path(rpath: str) -> bool:
Expand Down Expand Up @@ -101,7 +101,7 @@ def convert_date_string_to_date(date_string: str) -> datetime.datetime:
"""
Convert string into datetime format
:param date_str: date string in format [YYYY/MM/DD]. e.g. 2022/02/22
:param date_string: date string in format [YYYY/MM/DD]. e.g. 2022/02/22
:return: datetime format
"""
return datetime.datetime.strptime(date_string, "%Y/%m/%d") + datetime.timedelta(days=1)
Expand All @@ -111,6 +111,8 @@ def order_samples(results: dict) -> List[dict]:
"""
Order samples by their parent_guid
# TODO: To make this function more efficient, we should write it in Rust!
:param results: dictionary of samples. Structure: {
"sample": sample_dict,
"guid": sample.guid,
Expand Down
166 changes: 83 additions & 83 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,83 @@
import os

import peppy
import pytest
from sqlalchemy import create_engine, text

from pepdbagent import PEPDatabaseAgent

DNS = "postgresql+psycopg://postgres:docker@localhost:5432/pep-db"


DATA_PATH = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"tests",
"data",
)


def get_path_to_example_file(namespace, project_name):
return os.path.join(DATA_PATH, namespace, project_name, "project_config.yaml")


@pytest.fixture
def list_of_available_peps():
pep_namespaces = os.listdir(DATA_PATH)
projects = {}
for np in pep_namespaces:
pep_name = os.listdir(os.path.join(DATA_PATH, np))
projects[np] = {p: get_path_to_example_file(np, p) for p in pep_name}
return projects


@pytest.fixture(scope="function")
def initiate_pepdb_con(
list_of_available_peps,
):
sa_engine = create_engine(DNS)
with sa_engine.begin() as conn:
conn.execute(text("DROP table IF EXISTS projects CASCADE"))
conn.execute(text("DROP table IF EXISTS samples CASCADE"))
conn.execute(text("DROP table IF EXISTS subsamples CASCADE"))
conn.execute(text("DROP table IF EXISTS stars CASCADE"))
conn.execute(text("DROP table IF EXISTS users CASCADE"))
conn.execute(text("DROP table IF EXISTS views CASCADE"))
conn.execute(text("DROP table IF EXISTS views_samples CASCADE"))

pepdb_con = PEPDatabaseAgent(dsn=DNS, echo=True)
for namespace, item in list_of_available_peps.items():
if namespace == "private_test":
private = True
else:
private = False
for name, path in item.items():
prj = peppy.Project(path)
pepdb_con.project.create(
namespace=namespace,
name=name,
tag="default",
is_private=private,
project=prj,
overwrite=True,
pep_schema="random_schema_name",
)

yield pepdb_con


@pytest.fixture(scope="function")
def initiate_empty_pepdb_con(
list_of_available_peps,
):
"""
create connection without adding peps to the db
"""
# sa_engine = create_engine(DNS)
# with sa_engine.begin() as conn:
# conn.execute(text("DROP table IF EXISTS projects CASCADE"))
# conn.execute(text("DROP table IF EXISTS samples CASCADE"))
# conn.execute(text("DROP table IF EXISTS subsamples CASCADE"))

pepdb_con = PEPDatabaseAgent(dsn=DNS, echo=False)

yield pepdb_con
# import os
#
# import peppy
# import pytest
# from sqlalchemy import create_engine, text
#
# from pepdbagent import PEPDatabaseAgent
#
# DNS = "postgresql+psycopg://postgres:docker@localhost:5432/pep-db"
#
#
# DATA_PATH = os.path.join(
# os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
# "tests",
# "data",
# )
#
#
# def get_path_to_example_file(namespace, project_name):
# return os.path.join(DATA_PATH, namespace, project_name, "project_config.yaml")
#
#
# @pytest.fixture
# def list_of_available_peps():
# pep_namespaces = os.listdir(DATA_PATH)
# projects = {}
# for np in pep_namespaces:
# pep_name = os.listdir(os.path.join(DATA_PATH, np))
# projects[np] = {p: get_path_to_example_file(np, p) for p in pep_name}
# return projects
#
#
# @pytest.fixture(scope="function")
# def initiate_pepdb_con(
# list_of_available_peps,
# ):
# sa_engine = create_engine(DNS)
# with sa_engine.begin() as conn:
# conn.execute(text("DROP table IF EXISTS projects CASCADE"))
# conn.execute(text("DROP table IF EXISTS samples CASCADE"))
# conn.execute(text("DROP table IF EXISTS subsamples CASCADE"))
# conn.execute(text("DROP table IF EXISTS stars CASCADE"))
# conn.execute(text("DROP table IF EXISTS users CASCADE"))
# conn.execute(text("DROP table IF EXISTS views CASCADE"))
# conn.execute(text("DROP table IF EXISTS views_samples CASCADE"))
#
# pepdb_con = PEPDatabaseAgent(dsn=DNS, echo=True)
# for namespace, item in list_of_available_peps.items():
# if namespace == "private_test":
# private = True
# else:
# private = False
# for name, path in item.items():
# prj = peppy.Project(path)
# pepdb_con.project.create(
# namespace=namespace,
# name=name,
# tag="default",
# is_private=private,
# project=prj,
# overwrite=True,
# pep_schema="random_schema_name",
# )
#
# yield pepdb_con
#
#
# @pytest.fixture(scope="function")
# def initiate_empty_pepdb_con(
# list_of_available_peps,
# ):
# """
# create connection without adding peps to the db
# """
# # sa_engine = create_engine(DNS)
# # with sa_engine.begin() as conn:
# # conn.execute(text("DROP table IF EXISTS projects CASCADE"))
# # conn.execute(text("DROP table IF EXISTS samples CASCADE"))
# # conn.execute(text("DROP table IF EXISTS subsamples CASCADE"))
#
# pepdb_con = PEPDatabaseAgent(dsn=DNS, echo=False)
#
# yield pepdb_con
Loading

0 comments on commit a19bbbf

Please sign in to comment.