Skip to content

Commit 92c084d

Browse files
authored
Merge pull request #113 from templateflow/ci/manual-trigger
CI: Add manual trigger, bump action versions
2 parents 6a460b1 + 6bed295 commit 92c084d

File tree

3 files changed

+148
-55
lines changed

3 files changed

+148
-55
lines changed

.github/workflows/pythonpackage.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
name: Python package
55

66
on:
7+
workflow_dispatch:
78
push:
89
branches: [ master ]
910
tags: [ '*' ]
@@ -23,13 +24,13 @@ jobs:
2324
outputs:
2425
version: ${{ steps.get_version.outputs.version }}
2526
steps:
26-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2728
with:
2829
fetch-depth: 0
29-
- uses: actions/setup-python@v4
30+
- uses: actions/setup-python@v5
3031
with:
3132
python-version: 3
32-
- uses: actions/cache@v3
33+
- uses: actions/cache@v4
3334
with:
3435
path: ~/.cache/pip
3536
key: pip-cache-v1
@@ -39,7 +40,7 @@ jobs:
3940
- name: Build sdist and wheel
4041
run: python -m build
4142
- run: twine check dist/*
42-
- uses: actions/upload-artifact@v3
43+
- uses: actions/upload-artifact@v4
4344
with:
4445
name: dist
4546
path: dist/
@@ -73,20 +74,20 @@ jobs:
7374
TEMPLATEFLOW_HOME: /tmp/home
7475
THISVERSION: ${{ needs.build.outputs.version }}
7576
steps:
76-
- uses: actions/checkout@v3
77+
- uses: actions/checkout@v4
7778
if: matrix.mode == 'repo' || matrix.mode == 'editable'
7879
with:
7980
fetch-depth: 0
80-
- uses: actions/download-artifact@v3
81+
- uses: actions/download-artifact@v4
8182
if: matrix.mode == 'sdist' || matrix.mode == 'wheel'
8283
with:
8384
name: dist
8485
path: /tmp/package/
8586
- name: Set up Python ${{ matrix.python-version }}
86-
uses: actions/setup-python@v4
87+
uses: actions/setup-python@v5
8788
with:
8889
python-version: ${{ matrix.python-version }}
89-
- uses: actions/cache@v3
90+
- uses: actions/cache@v4
9091
with:
9192
path: ~/.cache/pip
9293
key: pip-cache-v1

templateflow/api.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,12 @@ def _to_bibtex(doi, template, idx):
333333
)
334334
return doi
335335

336-
return response.text
336+
# doi.org may not honor requested charset, to safeguard force a bytestream with
337+
# response.content, then decode into UTF-8.
338+
bibtex = response.content.decode()
339+
340+
# doi.org / crossref may still point to the no longer preferred proxy service
341+
return bibtex.replace('http://dx.doi.org/', 'https://doi.org/')
337342

338343

339344
def _normalize_ext(value):

templateflow/tests/test_api.py

Lines changed: 133 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,77 @@
11
"""Test citations."""
2+
23
import pytest
34

45
from .. import api
56

67

8+
class Bibtex:
9+
def __init__(self, bibtex):
10+
self.text = bibtex
11+
self.url_only = False
12+
self.etype = None
13+
self.citekey = None
14+
self.pairs = {}
15+
16+
# DOI could not be converted
17+
if self.text.startswith("http"):
18+
self.url_only = True
19+
else:
20+
self._parse_bibtex()
21+
22+
def _parse_bibtex(self):
23+
import re
24+
25+
try:
26+
self.etype = re.search(r"@(\w+)", self.text).group(1)
27+
except AttributeError:
28+
raise TypeError(f"Invalid bibtex: {self.text}")
29+
try:
30+
self.citekey = re.search(r"@[^{]*{([^,\s]+)", self.text).group(1)
31+
except AttributeError:
32+
raise TypeError(f"Invalid bibtex: {self.text}")
33+
self.pairs = {
34+
key: val for key, val in re.findall(r"(\w+)=(\{[^{}]+\})", self.text)
35+
}
36+
37+
def get(self, val):
38+
return self.pairs.get(val)
39+
40+
def __str__(self):
41+
return self.text
42+
43+
def __repr__(self):
44+
return f'@{self.etype}{{{self.citekey}, {", ".join([f"{key} = {val}" for key, val in self.pairs.items()])}}}'
45+
46+
def __eq__(self, other):
47+
if isinstance(other, Bibtex):
48+
if self.url_only and self.text == other.text:
49+
return True
50+
if (
51+
self.etype == other.etype
52+
and self.citekey == other.citekey
53+
and self.pairs == other.pairs
54+
):
55+
return True
56+
return False
57+
58+
def assert_same(self, other):
59+
"""Convenience method to find deviations between two Bibtex objects"""
60+
assert isinstance(other, Bibtex)
61+
assert self.etype == other.etype, "Mismatched entry types"
62+
assert self.citekey == other.citekey, "Mismatched citekeys"
63+
for key in self.pairs.keys():
64+
assert key in other.pairs, f"Key ({key}) missing from other"
65+
assert (
66+
self.pairs[key] == other.pairs[key]
67+
), f"Key ({key}) mismatched\n\n{self.pairs[key]}\n\n{other.pairs[key]}"
68+
69+
for key in other.pairs.keys():
70+
assert key in self.pairs, f"Key ({key}) missing from pairs"
71+
72+
assert self.pairs == other.pairs, "Dictionaries do not match"
73+
74+
775
# test setup to avoid cluttering pytest parameterize
876
mni2009_urls = [
977
"https://doi.org/10.1016/j.neuroimage.2010.07.033",
@@ -14,30 +82,32 @@
1482

1583
mni2009_fbib = """\
1684
@article{Fonov_2011,
17-
\tdoi = {10.1016/j.neuroimage.2010.07.033},
18-
\turl = {https://doi.org/10.1016%2Fj.neuroimage.2010.07.033},
19-
\tyear = 2011,
20-
\tmonth = {jan},
21-
\tpublisher = {Elsevier {BV}},
22-
\tvolume = {54},
23-
\tnumber = {1},
24-
\tpages = {313--327},
25-
\tauthor = {Vladimir Fonov and Alan C. Evans and Kelly Botteron and C. Robert \
26-
Almli and Robert C. McKinstry and D. Louis Collins},
27-
\ttitle = {Unbiased average age-appropriate atlases for pediatric studies},
28-
\tjournal = {{NeuroImage}}
85+
DOI={10.1016/j.neuroimage.2010.07.033},
86+
url={https://doi.org/10.1016/j.neuroimage.2010.07.033},
87+
year={2011},
88+
publisher={Elsevier BV},
89+
ISSN={1053-8119},
90+
volume={54},
91+
number={1},
92+
pages={313327},
93+
author={Fonov, Vladimir and Evans, Alan C. and Botteron, Kelly and Almli, C. Robert \
94+
and McKinstry, Robert C. and Collins, D. Louis},
95+
title={Unbiased average age-appropriate atlases for pediatric studies},
96+
journal={NeuroImage}
2997
}"""
3098

3199
mni2009_lbib = """\
32-
@incollection{Collins_1999,
33-
\tdoi = {10.1007/3-540-48714-x_16},
34-
\turl = {https://doi.org/10.1007%2F3-540-48714-x_16},
35-
\tyear = 1999,
36-
\tpublisher = {Springer Berlin Heidelberg},
37-
\tpages = {210--223},
38-
\tauthor = {D. Louis Collins and Alex P. Zijdenbos and Wim F. C. Baar{\\'{e}} and Alan C. Evans},
39-
\ttitle = {{ANIMAL}$\\mathplus${INSECT}: Improved Cortical Structure Segmentation},
40-
\tbooktitle = {Lecture Notes in Computer Science}
100+
@inbook{Collins_1999,
101+
DOI={10.1007/3-540-48714-x_16},
102+
url={https://doi.org/10.1007/3-540-48714-X_16},
103+
year={1999},
104+
publisher={Springer Berlin Heidelberg},
105+
pages={210–223},
106+
ISBN={9783540487142},
107+
ISSN={0302-9743}
108+
author={Collins, D. Louis and Zijdenbos, Alex P. and Baaré, Wim F. C. and Evans, Alan C.},
109+
title={ANIMAL+INSECT: Improved Cortical Structure Segmentation},
110+
booktitle={Information Processing in Medical Imaging}
41111
}"""
42112

43113
fslr_urls = [
@@ -47,18 +117,18 @@
47117

48118
fslr_fbib = """\
49119
@article{Van_Essen_2011,
50-
\tdoi = {10.1093/cercor/bhr291},
51-
\turl = {https://doi.org/10.1093%2Fcercor%2Fbhr291},
52-
\tyear = 2011,
53-
\tmonth = {nov},
54-
\tpublisher = {Oxford University Press ({OUP})},
55-
\tvolume = {22},
56-
\tnumber = {10},
57-
\tpages = {2241--2262},
58-
\tauthor = {D. C. Van Essen and M. F. Glasser and D. L. Dierker and J. Harwell and T. Coalson},
59-
\ttitle = {Parcellations and Hemispheric Asymmetries of Human Cerebral Cortex Analyzed on \
120+
DOI={10.1093/cercor/bhr291},
121+
ISSN={1460-2199},
122+
url={https://doi.org/10.1093/cercor/bhr291},
123+
year={2011},
124+
publisher={Oxford University Press (OUP)},
125+
volume={22},
126+
number={10},
127+
pages={22412262},
128+
author={Van Essen, D. C. and Glasser, M. F. and Dierker, D. L. and Harwell, J. and Coalson, T.},
129+
title={Parcellations and Hemispheric Asymmetries of Human Cerebral Cortex Analyzed on \
60130
Surface-Based Atlases},
61-
\tjournal = {Cerebral Cortex}
131+
journal={Cerebral Cortex}
62132
}"""
63133

64134
fslr_lbib = (
@@ -67,33 +137,50 @@
67137

68138
fsaverage_fbib = """\
69139
@article{Fischl_1999,
70-
\tdoi = {10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
71-
\turl = {https://doi.org/10.1002%2F%28sici%291097-0193%281999%298%3A4%3C272%3A%3Aaid-hbm10%3E3.0.co%3B2-4},
72-
\tyear = 1999,
73-
\tpublisher = {Wiley},
74-
\tvolume = {8},
75-
\tnumber = {4},
76-
\tpages = {272--284},
77-
\tauthor = {Bruce Fischl and Martin I. Sereno and Roger B.H. Tootell and Anders M. Dale},
78-
\ttitle = {High-resolution intersubject averaging and a coordinate system for the cortical surface},
79-
\tjournal = {Human Brain Mapping}
140+
DOI={10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
141+
ISSN={1097-0193},
142+
url={https://doi.org/10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
143+
year={1999},
144+
publisher={Wiley},
145+
volume={8},
146+
number={4},
147+
pages={272–284},
148+
author={Fischl, Bruce and Sereno, Martin I. and Tootell, Roger B.H. and Dale, Anders M.},
149+
title={High-resolution intersubject averaging and a coordinate system for the cortical surface},
150+
journal={Human Brain Mapping}
80151
}"""
81152

153+
82154
@pytest.mark.parametrize(
83155
"template,urls,fbib,lbib",
84156
[
85157
("MNI152NLin2009cAsym", mni2009_urls, mni2009_fbib, mni2009_lbib),
86158
("fsLR", fslr_urls, fslr_fbib, fslr_lbib),
87-
("fsaverage", ["https://doi.org/10.1002/(sici)1097-0193(1999)8:4%3C272::aid-hbm10%3E3.0.co;2-4"], fsaverage_fbib, None),
159+
(
160+
"fsaverage",
161+
[
162+
"https://doi.org/10.1002/(sici)1097-0193(1999)8:4%3C272::aid-hbm10%3E3.0.co;2-4"
163+
],
164+
fsaverage_fbib,
165+
None,
166+
),
88167
],
89168
)
90169
def test_citations(tmp_path, template, urls, fbib, lbib):
91170
"""Check the correct composition of citations."""
92171
assert api.get_citations(template) == urls
93172
bibs = api.get_citations(template, bibtex=True)
94173
if bibs:
95-
assert "".join(bibs[0]) == fbib
96-
assert len(bibs) == 1 if lbib is None else "".join(bibs[-1]) == lbib
174+
bib0 = Bibtex(bibs[0])
175+
exp0 = Bibtex(fbib)
176+
assert bib0 == exp0
177+
if lbib is not None:
178+
bib1 = Bibtex(bibs[-1])
179+
exp1 = Bibtex(lbib)
180+
assert bib1 == exp1
181+
else:
182+
assert len(bibs) == 1
183+
97184
else:
98185
# no citations currently
99186
assert False
@@ -108,7 +195,7 @@ def test_pybids_magic_get():
108195

109196
with pytest.raises(TypeError):
110197
api.ls_atlases("MNI152NLin6ASym")
111-
198+
112199
# Existing layout.get_* should not be bubbled to the layout
113200
# (that means, raise an AttributeError instead of a BIDSEntityError)
114201
with pytest.raises(AttributeError):

0 commit comments

Comments
 (0)