Skip to content

Commit

Permalink
Merge pull request #4 from wfondrie/v1.0.0rc1
Browse files Browse the repository at this point in the history
Release candidate for version 1.0.0
  • Loading branch information
Will Fondrie authored May 14, 2021
2 parents 5788e2c + c811f4e commit afdb6f5
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 5 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog for ppx

## [Unreleased]
## [1.0.0] - 2021-05-14
### Changed
- **We did a complete rework of the API!** This will break nearly all previous
code using ppx, but greatly improves its versatility.
Expand All @@ -11,5 +11,8 @@
### Added
- A command line interface for downloading files from PRIDE and MassIVE
projects.
- Additional unit tests.
- A ppx logo
- This changelog.
- ppx is now available on bioconda!

2 changes: 2 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(
}

/** Signature bg **/
.rst-content dl:not(.docutils) dt,
html.writer-html4 .rst-content dl:not(.docutils)>dt,
html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt {
background: #C9F4ED;
Expand Down Expand Up @@ -54,3 +55,4 @@ html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(
color: #444444;
}
**/
.rst-content dl:not(.docutils) dt:
1 change: 1 addition & 0 deletions docs/api/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ Functions
.. autofunction:: ppx.find_project
.. autofunction:: ppx.get_data_dir
.. autofunction:: ppx.set_data_dir
.. autofunction:: ppx.pride.list_projects
.. autofunction:: ppx.massive.list_projects
1 change: 1 addition & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ objects have methods to find and download files of interest.
find_project
get_data_dir
set_data_dir
pride.list_projects
massive.list_projects
PrideProject
MassiveProject
1 change: 1 addition & 0 deletions ppx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
except DistributionNotFound:
pass

from . import pride
from . import massive
from .factory import find_project
from .pride import PrideProject
Expand Down
13 changes: 11 additions & 2 deletions ppx/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ def path(self, path):
if path is None:
try:
path = Path(os.environ["PPX_DATA_DIR"]).expanduser().resolve()
if not path.exists():
raise FileNotFoundError(
f"The specified PPX_DATA_DIR ({path}) does not exist."
)
except KeyError:
path = Path(Path.home(), ".ppx")
path.mkdir(exist_ok=True)
else:
path = Path(path).expanduser().resolve()
if not path.exists():
Expand All @@ -49,7 +52,13 @@ def get_data_dir():


def set_data_dir(path=None):
"""Set the data dir"""
"""Set the ppx data directory.
Parameters
----------
path : str or Path object, optional
The path for ppx to use as its data directory.
"""
config.path = path


Expand Down
2 changes: 1 addition & 1 deletion ppx/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def find_project(identifier, local=None, repo=None, fetch=False):
raise ValueError("Unsupported repository.")

# Try and figure it out:
if identifier.startswith("MSV"):
if identifier.startswith("MSV") or identifier.startswith("RMS"):
return MassiveProject(identifier, local=local, fetch=fetch)

if re.match("P[XR]D", identifier):
Expand Down
4 changes: 3 additions & 1 deletion ppx/massive.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _validate_id(self, identifier):
The validated identifier.
"""
identifier = str(identifier).upper()
if not re.match("MSV[0-9]{9}", identifier):
if not re.match("(MSV|RMS)[0-9]{9}", identifier):
raise ValueError("Malformed MassIVE identifier.")

return identifier
Expand Down Expand Up @@ -137,6 +137,8 @@ def remote_files(self, glob=None):
def list_projects():
"""List all available projects on MassIVE.
MassIVE: `<https://massive.ucsd.edu>`_
Returns
-------
list of str
Expand Down
20 changes: 20 additions & 0 deletions ppx/pride.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PrideProject(BaseProject):
id : str
local : Path object
url : str
title : str
description : str
doi : str
data_processing_protocol : str
Expand Down Expand Up @@ -178,3 +179,22 @@ def get(url):
raise requests.HTTPError(f"Error {res.status_code}: {res.text}")

return res.json()


def list_projects():
"""List all available projects on PRIDE
PRIDE Archive: `<https://www.ebi.ac.uk/pride/archive/>`_
Returns
-------
list of str
A list of PRIDE identifiers.
"""
url = "https://www.ebi.ac.uk/pride/ws/archive/v2/misc/sitemap"
res = requests.get(url)
if res.status_code != 200:
raise requests.HTTPError(f"Error {res.status_code}: {res.text})")

res = [p.split("/")[-1] for p in res.text.splitlines()]
return [p for p in res if re.match("P[RX]D[0-9]{6}", p)]
3 changes: 3 additions & 0 deletions ppx/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def local(self):
def local(self, path):
"""Set the local data directory for this project."""
if path is None:
if config.path == Path(Path.home(), ".ppx"):
config.path.mkdir(exist_ok=True)

self._local = Path(config.path, self.id)
else:
self._local = Path(path)
Expand Down
44 changes: 44 additions & 0 deletions tests/unit_tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Test the configuration"""
import os
from pathlib import Path

import pytest
import ppx

PXID = "PXD000001"


def test_reset_dir(monkeypatch):
"""Test resetting the data directory"""
monkeypatch.delenv("PPX_DATA_DIR")
ppx.set_data_dir()
assert ppx.get_data_dir() == Path(Path.home(), ".ppx")

ppx.PrideProject(PXID)
assert Path(Path.home(), ".ppx").exists()


def test_change_dir(monkeypatch, tmp_path):
"""Test changing the data dir"""
test_dir = tmp_path / "test"
with pytest.raises(FileNotFoundError):
ppx.set_data_dir(test_dir)

test_dir.mkdir()
ppx.set_data_dir(test_dir)
assert ppx.get_data_dir() == test_dir

proj = ppx.PrideProject(PXID)
assert proj.local == test_dir / PXID

test_dir = tmp_path / "test2"
monkeypatch.setenv("PPX_DATA_DIR", str(test_dir))
with pytest.raises(FileNotFoundError):
ppx.set_data_dir()

test_dir.mkdir()
ppx.set_data_dir(test_dir)
assert ppx.get_data_dir() == test_dir

proj = ppx.PrideProject(PXID)
assert proj.local == test_dir / PXID
17 changes: 17 additions & 0 deletions tests/unit_tests/test_list_projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Test that the list_projects() functions work"""
import pytest
import ppx


def test_pride():
"""Test that we can get pride projects"""
proj = ppx.pride.list_projects()
assert len(proj) > 10000
assert all((p.startswith("PXD") or p.startswith("PRD")) for p in proj)


def test_massive():
"""Test that we can get massive projects"""
proj = ppx.massive.list_projects()
assert len(proj) > 10000
assert all((p.startswith("MSV") or p.startswith("RMS")) for p in proj)
29 changes: 29 additions & 0 deletions tests/unit_tests/test_pride.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,35 @@ def test_metadata(mock_pride_project_response):

assert meta == true_meta

title = (
"TMT spikes - Using R and Bioconductor for proteomics data analysis"
)
assert proj.title == title

desc = (
"Expected reporter ion ratios: Erwinia peptides: 1:1:1:1:1:1 "
"Enolase spike (sp|P00924|ENO1_YEAST): 10:5:2.5:1:2.5:10 BSA spike "
"(sp|P02769|ALBU_BOVIN): 1:2.5:5:10:5:1 PhosB spike "
"(sp|P00489|PYGM_RABIT): 2:2:2:2:1:1 Cytochrome C spike "
"(sp|P62894|CYC_BOVIN): 1:1:1:1:1:2"
)
assert proj.description == desc
assert proj.sample_processing_protocol == "Not available"

data_prot = (
"Two extra files have been added post-publication:<br>"
'<a href="ftp://ftp.pride.ebi.ac.uk/pride/data/archive/2012/03/'
"PXD000001/TMT_Erwinia_1uLSike_Top10HCD_isol2_45stepped_60min_01-"
'20141210.mzML" target="_top">TMT_Erwinia_1uLSike_Top10HCD_isol2_'
'45stepped_60min_01-20141210.mzML</a><br><a href="ftp://ftp.pride.'
"ebi.ac.uk/pride/data/archive/2012/03/PXD000001/TMT_Erwinia_1uLSike_"
'Top10HCD_isol2_45stepped_60min_01-20141210.mzXML" target="_top">'
"TMT_Erwinia_1uLSike_Top10HCD_isol2_45stepped_60min_01-20141210.mzXML"
"</a>"
)
assert proj.data_processing_protocol == data_prot
assert proj.doi == "10.6019/PXD000001"


def test_remote_files(mock_pride_files_response):
"""Test that listing remote files works"""
Expand Down

0 comments on commit afdb6f5

Please sign in to comment.