Skip to content

Commit 4cad438

Browse files
author
Roberto Vera Alvarez
committed
Fixing bugs
1 parent a91f43a commit 4cad438

File tree

10 files changed

+674
-66
lines changed

10 files changed

+674
-66
lines changed

.github/workflows/python-app.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,5 @@ jobs:
2424
run: pip install poetry
2525
- name: Install dependencies
2626
run: poetry install
27-
- name: Install Flake
28-
run: pip install flake8
29-
- name: Lint with flake8
30-
run: |
31-
poetry run flake8 src/ --count --select=E9,F63,F7,F82 --show-source --statistics
32-
poetry run flake8 src/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
33-
- name: Test with pytest
34-
run: poetry run pytest
27+
- name: Test with tox
28+
run: poetry run tox

poetry.lock

Lines changed: 585 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ python = ">=3.9,<4.0"
3737
requests = "*"
3838
PyYAML = "*"
3939

40+
[tool.poetry.group.dev.dependencies]
41+
pytest = "*"
42+
pytest-cov = "*"
43+
flake8 = "*"
44+
4045
[tool.poetry.scripts]
4146
bioconda2biocontainer = "bioconda2biocontainer.entry_point:main"
4247
biocontainers-search = "bioconda2biocontainer.entry_point_search:main"

requirements/base.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

requirements/test.txt

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
2+
from typing import Optional, Union
33
import requests
44

55
base_url = "http://api.biocontainers.pro/ga4gh/trs/v2/tools"
@@ -14,7 +14,7 @@ def request_url_to_dict(url):
1414

1515
def find_package_by_name(package_name):
1616
data = request_url_to_dict('{0}/{1}'.format(base_url, package_name))
17-
if type(data) == int:
17+
if isinstance(data, int):
1818
return data
1919
if data and 'versions' in data:
2020
versions = data['versions']
@@ -44,32 +44,62 @@ def filter_by_container_registry(container_type, registry_host, i):
4444
return False
4545

4646

47-
def find_latest_image(package_name, package_version, all=False, sort_by_size=False,
48-
sort_by_download=False, container_type=None, registry_host=None):
49-
data = request_url_to_dict('{0}/{1}/versions/{1}-{2}'.format(
50-
base_url, package_name, package_version))
51-
if type(data) == dict or type(data) == list:
52-
versions = []
53-
if data and 'images' in data:
54-
for i in data['images']:
55-
if filter_by_container_registry(container_type, registry_host, i):
56-
if 'downloads' not in i:
57-
i['downloads'] = 0
58-
if 'updated' not in i:
59-
i['updated'] = ''
60-
if 'size' not in i:
61-
i['size'] = 0
62-
versions.append(i)
63-
if sort_by_size:
64-
versions = sorted(versions, key=lambda i: i['size'])
65-
elif sort_by_download:
66-
versions = sorted(versions, key=lambda i: i['downloads'], reverse=True)
67-
else:
68-
versions = sorted(versions, key=lambda i: i['updated'], reverse=True)
69-
if all:
70-
return versions
71-
if versions:
72-
return versions[0]
73-
else:
74-
return None
75-
return data
47+
def _normalize_image_fields(image: dict) -> dict:
48+
"""Ensure required fields exist in the image dict."""
49+
image.setdefault("downloads", 0)
50+
image.setdefault("updated", "")
51+
image.setdefault("size", 0)
52+
return image
53+
54+
55+
def _sort_images(images: list[dict], sort_by_size: bool, sort_by_download: bool) -> list[dict]:
56+
"""Sort images based on size, downloads, or updated date."""
57+
if sort_by_size:
58+
return sorted(images, key=lambda i: i["size"])
59+
if sort_by_download:
60+
return sorted(images, key=lambda i: i["downloads"], reverse=True)
61+
return sorted(images, key=lambda i: i["updated"], reverse=True)
62+
63+
64+
def find_latest_image(
65+
package_name: str,
66+
package_version: str,
67+
all: bool = False,
68+
sort_by_size: bool = False,
69+
sort_by_download: bool = False,
70+
container_type: Optional[str] = None,
71+
registry_host: Optional[str] = None,
72+
) -> Union[dict, list[dict], int, None]:
73+
"""
74+
Retrieve the latest container image for a given package version.
75+
76+
Args:
77+
package_name: Bioconda package name.
78+
package_version: Specific version string.
79+
all: If True, return all matching images instead of only the latest.
80+
sort_by_size: Sort by image size ascending.
81+
sort_by_download: Sort by download count descending.
82+
container_type: Optional filter by container type (e.g., 'Docker').
83+
registry_host: Optional filter by registry host.
84+
85+
Returns:
86+
The latest image dict, a list of image dicts if all=True,
87+
an HTTP status code (int) on error, or None if no images found.
88+
"""
89+
url = f"{base_url}/{package_name}/versions/{package_name}-{package_version}"
90+
data = request_url_to_dict(url)
91+
92+
if not isinstance(data, dict) or "images" not in data:
93+
return data
94+
95+
images = [
96+
_normalize_image_fields(i)
97+
for i in data["images"]
98+
if filter_by_container_registry(container_type, registry_host, i)
99+
]
100+
101+
sorted_images = _sort_images(images, sort_by_size, sort_by_download)
102+
103+
if all:
104+
return sorted_images
105+
return sorted_images[0] if sorted_images else None

src/bioconda2biocontainer/entry_point.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
def find_tool(package_name, print_json):
1010
tool = find_package_by_name(package_name)
11-
if type(tool) == dict:
11+
if isinstance(tool, dict):
1212
if print_json:
1313
print(json.dumps(tool, indent=4))
1414
else:
@@ -23,7 +23,7 @@ def find_latest_image_main(package_name, package_version, json, all, sort_by_siz
2323
sort_by_download, container_type, registry_host):
2424
images = find_latest_image(package_name, package_version, all, sort_by_size,
2525
sort_by_download, container_type, registry_host)
26-
if type(images) == list:
26+
if isinstance(images, list):
2727
if json:
2828
print(json.dumps(images, indent=4))
2929
elif all:
@@ -38,7 +38,7 @@ def find_latest_image_main(package_name, package_version, json, all, sort_by_siz
3838
image_name, updated,
3939
size, downloads,
4040
image_type))
41-
elif type(images) == dict:
41+
elif isinstance(images, dict):
4242
print(images['image_name'])
4343
else:
4444
if container_type:

src/bioconda2biocontainer/entry_point_search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def main():
3333
search_term = args.search_term
3434

3535
data = find_package_by_term(search_term)
36-
if type(data) == int:
36+
if isinstance(data, int):
3737
print('No packages found with search term: {}'.format(search_term))
3838
elif args.json:
3939
print(json.dumps(data, indent=4))

tests/test_bioconda2biocontainer.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,43 @@ def test_find_package_by_name(self):
1212
assert tool['id'] == 'bedtools'
1313

1414
def test_find_latest_image(self):
15-
images = find_latest_image('bedtools', '2.27.0', False, False, False, 'Docker', 'quay.io')
15+
images = find_latest_image('bedtools', '2.27.1', False, False, False, 'Docker', 'quay.io')
1616
assert type(images) == dict
1717

1818
def test_find_latest_image_all(self):
19-
images = find_latest_image('bedtools', '2.27.0', True, False, False, 'Docker', 'quay.io')
19+
images = find_latest_image('bedtools', '2.27.1', True, False, False, 'Docker', 'quay.io')
2020
flag = False
2121
for i in images:
22-
if i['updated'] == '2019-10-26T00:00:00Z':
22+
print(i)
23+
if i['updated'] == '2024-12-10T00:00:00Z':
2324
flag = True
24-
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.0--he513fc3_4'
25+
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.1--h077b44d_9'
2526
assert flag
2627

2728
def test_find_package_by_name_status_code(self):
2829
tool = find_package_by_name('bedtoolss')
2930
assert tool == 204
3031

3132
def test_find_latest_image_sort_by_size(self):
32-
images = find_latest_image('bedtools', '2.27.0', True, True, False, 'Docker', 'quay.io')
33+
images = find_latest_image('bedtools', '2.27.1', True, True, False, 'Docker', 'quay.io')
3334
flag = False
3435
for i in images:
35-
if i['updated'] == '2019-10-26T00:00:00Z':
36+
if i['updated'] == '2024-12-10T00:00:00Z':
3637
flag = True
37-
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.0--he513fc3_4'
38+
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.1--h077b44d_9'
3839
assert flag
3940

4041
def test_find_latest_image_sort_by_downloads(self):
41-
images = find_latest_image('bedtools', '2.27.0', True, False, True, 'Docker', 'quay.io')
42+
images = find_latest_image('bedtools', '2.27.1', True, False, True, 'Docker', 'quay.io')
4243
flag = False
4344
for i in images:
44-
if i['updated'] == '2019-10-26T00:00:00Z':
45+
if i['updated'] == '2024-12-10T00:00:00Z':
4546
flag = True
46-
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.0--he513fc3_4'
47+
assert i['image_name'] == 'quay.io/biocontainers/bedtools:2.27.1--h077b44d_9'
4748
assert flag
4849

4950
def test_find_latest_image_status_code(self):
50-
images = find_latest_image('bedtoolss', '2.27.0', True, False, True, 'Docker', 'quay.io')
51+
images = find_latest_image('bedtoolss', '2.27.1', True, False, True, 'Docker', 'quay.io')
5152
assert images == 204
5253

5354
def test_search_tool(self):

tox.ini

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ envlist = py{39,310,311,312},flake8
44

55
[testenv]
66
skip_install = true
7-
commands_pre = poetry install --no-root
8-
commands = poetry run pytest {posargs:--cov pm4ngs --cov tests --cov-report term-missing --cov-report html --cov-report xml:coverage.xml}
7+
allowlist_externals = poetry
8+
commands_pre = poetry install
9+
commands = poetry run pytest {posargs:--cov bioconda2biocontainer --cov tests --cov-report term-missing --cov-report html --cov-report xml:coverage.xml}
910

1011

1112
[testenv:flake8]
1213
skip_install = True
14+
allowlist_externals = poetry
1315
commands_pre = poetry install --no-root
14-
deps = flake8
15-
commands = poetry run flake8 src/ tests/
16-
17-
basepython = python3.9
16+
commands = poetry run flake8 src/
1817

1918

2019
[pytest]

0 commit comments

Comments
 (0)