Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
51 changes: 19 additions & 32 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,53 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
branches: [ master, dev ]

jobs:
ubuntu_3_11:
runs-on: ubuntu-latest
ubuntu_matrix:
runs-on: ubuntu-22.04 # latest fails testing python 3.7 - https://github.com/actions/setup-python/issues/962
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -e .
pip install -e ".[dev]"
- name: Run tests
run: python -m unittest discover

ubuntu_3_7:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.7'
- name: Install dependencies
run: |
pip install -e .
pip install -e ".[dev]"
- name: Run tests
run: python -m unittest discover
run: python -m unittest discover tests/

macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.11'
- name: Install dependencies
run: |
pip install -e .
pip install -e ".[dev]"
- name: Run tests
run: python -m unittest discover
run: python -m unittest discover tests/

windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.9'
python-version: '3.11'
- name: Install dependencies
run: |
pip install -e .
pip install -e ".[dev]"
- name: Run tests
run: python -m unittest discover

run: python -m unittest discover tests/
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ classifiers = [
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.10",
Expand Down
4 changes: 2 additions & 2 deletions src/UniProtMapper/field_base_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""

import re
from typing import Union
from typing import List, Union

from .utils import read_fields_table

Expand Down Expand Up @@ -38,7 +38,7 @@ class QueryBuilder:
'NOT reviewed:true OR (organism_id:9606 AND length:[100 TO 200])'
"""

def __init__(self, query: Union[list[Union[str, "AnyField"]], "AnyField"]) -> None:
def __init__(self, query: Union[List[Union[str, "AnyField"]], "AnyField"]) -> None:
"""Initialize QueryBuilder with a query."""
# Convert single field to list for consistency
self.query = [query] if hasattr(query, "field_name") else query
Expand Down
8 changes: 4 additions & 4 deletions src/UniProtMapper/idmapping_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ class ProtMapper(BaseUniProt):

def __init__(
self,
pooling_interval=3,
total_retries=5,
backoff_factor=0.25,
api_url="https://rest.uniprot.org",
pooling_interval: int = 3,
total_retries: int = 5,
backoff_factor: float = 0.25,
api_url: str = "https://rest.uniprot.org",
) -> None:
"""Initialize the class. This will set up the session and retry mechanism.

Expand Down
14 changes: 7 additions & 7 deletions src/UniProtMapper/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class BaseUniProt(ABC):

def __init__(
self,
pooling_interval=3,
total_retries=5,
backoff_factor=0.25,
api_url="https://rest.uniprot.org",
pooling_interval: int = 3,
total_retries: int = 5,
backoff_factor: float = 0.25,
api_url: str = "https://rest.uniprot.org",
) -> None:
"""Initialize the class. This will set up the session and retry mechanism.

Expand All @@ -46,7 +46,7 @@ def __init__(
self._re_next_link = re.compile(r'<(.+)>; rel="next"')

@property
def fields_table(self):
def fields_table(self) -> None:
return read_fields_table()

def _setup_retries(self, total_retries, backoff_factor) -> None:
Expand All @@ -59,14 +59,14 @@ def _setup_retries(self, total_retries, backoff_factor) -> None:
def _setup_session(self) -> None:
self.session.mount("https://", HTTPAdapter(max_retries=self.retries))

def check_response(self, response):
def check_response(self, response) -> None:
try:
response.raise_for_status()
except requests.HTTPError:
print(response.json())
raise

def get_next_link(self, headers):
def get_next_link(self, headers) -> str:
if "Link" in headers:
match = self._re_next_link.match(headers["Link"])
if match:
Expand Down
8 changes: 4 additions & 4 deletions src/UniProtMapper/uniprotkb_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
field classes found in `UniProtMapper.uniprotkb_fields`."""

from logging import info
from typing import Generator, Optional, Union
from typing import Generator, List, Optional, Tuple, Union

import pandas as pd
import requests
Expand Down Expand Up @@ -56,7 +56,7 @@ def __init__(
def _build_search_url(
self,
query: str,
fields: list[str],
fields: List[str],
format: str = "tsv",
include_isoform: bool = False,
compressed: bool = False,
Expand Down Expand Up @@ -111,7 +111,7 @@ def submit_query(

def _get_batches(
self, initial_response
) -> Generator[tuple[requests.Response, int], None, None]:
) -> Generator[Tuple[requests.Response, int], None, None]:
"""Generator that yields batches of results with pagination.

Args:
Expand All @@ -138,7 +138,7 @@ def _get_batches(
def get(
self,
query: Union[QueryBuilder, str],
fields: Optional[list[str]] = None,
fields: Optional[List[str]] = None,
include_isoform: bool = False,
compressed: bool = False,
size: int = 500,
Expand Down
22 changes: 14 additions & 8 deletions src/UniProtMapper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@
from typing import Optional

import pandas as pd
import pkg_resources
import requests


def get_resource_file(filename: str) -> str:
try:
import pkg_resources

return pkg_resources.resource_filename("UniProtMapper", filename)
except ImportError:
from importlib import resources

return str(resources.files("UniProtMapper") / filename)


def get_resources_root() -> Path:
"""Returns the path to the resources folder."""
return Path(pkg_resources.resource_filename("UniProtMapper", "resources"))
return Path(get_resource_file("resources"))


def fetch_cross_referenced_db_details(
Expand Down Expand Up @@ -60,19 +70,15 @@ def read_fields_table():
- `has_full_version`: whether the annotated field contains the full version of the
dataset or not (in case of cross-references).
- `type`: the type of data. Either "cross_reference" or "uniprot_field"."""
csv_path = pkg_resources.resource_filename(
"UniProtMapper", "resources/uniprot_return_fields.csv"
)
csv_path = get_resource_file("resources/uniprot_return_fields.csv")
return pd.read_csv(csv_path)


def supported_mapping_dbs():
"""Return a list of the supported datasets as UniProt cross references. This list
is used to validate the arguments `to_db` and `from_db` in the `FieldRetriever.get()` method.
"""
_mapping_dbs_path = pkg_resources.resource_filename(
"UniProtMapper", "resources/uniprot_mapping_dbs.json"
)
_mapping_dbs_path = get_resource_file("resources/uniprot_mapping_dbs.json")
with open(_mapping_dbs_path, "r") as f:
dbs_dict = json.load(f)
return sorted([dbs_dict[k][i] for k in dbs_dict for i in range(len(dbs_dict[k]))])
Expand Down
16 changes: 8 additions & 8 deletions tests/test_idmapping_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

import pandas as pd

from UniProtMapper.idmapping_api import ProtMapper
from UniProtMapper import ProtMapper

# Test data
test_ids = ["P30542", "Q16678", "Q02880"]

# Initialize the UniProtRetriever object
uni_retriever = ProtMapper()
mapper = ProtMapper()


class TestProtMapper(unittest.TestCase):
def setUp(self):
self.fields_table = ProtMapper().fields_table

def test_supported_dbs(self):
supported_dbs = uni_retriever._supported_dbs
supported_dbs = mapper._supported_dbs
self.assertIsInstance(supported_dbs, list)
self.assertIn("UniProtKB_AC-ID", supported_dbs)

Expand All @@ -25,7 +25,7 @@ def test_fields_table(self):
self.assertIn("accession", self.fields_table["returned_field"].values)

def test_retrieve_fields_default(self):
result_df, failed = uni_retriever(test_ids)
result_df, failed = mapper.get(test_ids)
self.assertIsInstance(result_df, pd.DataFrame)
self.assertEqual(len(result_df), len(test_ids))
self.assertEqual(len(failed), 0)
Expand All @@ -45,7 +45,7 @@ def test_retrieve_fields_custom(self):
result_columns = self.fields_table[
self.fields_table["returned_field"].isin(custom_fields)
]["label"]
result_df, failed = uni_retriever(test_ids, fields=custom_fields)
result_df, failed = mapper.get(test_ids, fields=custom_fields)
self.assertIsInstance(result_df, pd.DataFrame)
self.assertEqual(len(result_df), len(test_ids))
self.assertEqual(len(failed), 0)
Expand All @@ -54,15 +54,15 @@ def test_retrieve_fields_custom(self):

def test_retrieve_fields_invalid_field(self):
with self.assertRaises(ValueError):
uni_retriever(test_ids, fields=["invalid_field"])
mapper.get(test_ids, fields=["invalid_field"])

def test_retrieve_fields_invalid_from_db(self):
with self.assertRaises(ValueError):
uni_retriever(test_ids, from_db="InvalidDB")
mapper.get(test_ids, from_db="InvalidDB")

def test_retrieve_fields_invalid_to_db(self):
with self.assertRaises(ValueError):
uni_retriever(test_ids, to_db="InvalidDB")
mapper.get(test_ids, to_db="InvalidDB")


if __name__ == "__main__":
Expand Down
Loading