Skip to content

Commit 66e4681

Browse files
committed
Add a Software Heritage provider
Software Heritage¹ is a non-profit multi-stakeholder initiative which collects, preserves and shares all software that is publicly available in source code form. It provides a public API allowing to retrieve any piece of source code that has been ingested and is identified via its SWHID², including a growing number of jupyter notbooks. Thanks to the recent support for SWHID added in repo2docker, this now bring support to SWHID to binderhub as a Provider. ¹ https://www.softwareheritage.org ² https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html#persistent-identifiers
1 parent 81660eb commit 66e4681

File tree

9 files changed

+87
-3
lines changed

9 files changed

+87
-3
lines changed

binderhub/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from .repoproviders import (GitHubRepoProvider, GitRepoProvider,
3737
GitLabRepoProvider, GistRepoProvider,
3838
ZenodoProvider, FigshareProvider, HydroshareProvider,
39-
DataverseProvider)
39+
DataverseProvider, SWHIDProvider)
4040
from .metrics import MetricsHandler
4141

4242
from .utils import ByteSpecification, url_path_join
@@ -436,6 +436,7 @@ def _add_slash(self, proposal):
436436
'figshare': FigshareProvider,
437437
'hydroshare': HydroshareProvider,
438438
'dataverse': DataverseProvider,
439+
'swh': SWHIDProvider,
439440
},
440441
config=True,
441442
help="""

binderhub/event-schemas/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"Zenodo",
1515
"Figshare",
1616
"Hydroshare",
17-
"Dataverse"
17+
"Dataverse",
18+
"Software Heritage"
1819
],
1920
"description": "Provider for the repository being launched"
2021
},

binderhub/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"figshare": "Figshare",
2020
"hydroshare": "Hydroshare",
2121
"dataverse": "Dataverse",
22+
"swh": "Software Heritage",
2223
}
2324

2425

binderhub/repoproviders.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,3 +886,40 @@ async def get_resolved_spec(self):
886886

887887
def get_build_slug(self):
888888
return self.gist_id
889+
890+
891+
class SWHIDProvider(RepoProvider):
892+
"""Provide contents of a SWHID record
893+
894+
Users must provide a spec consisting of the SWHID of a directory or revision.
895+
"""
896+
name = Unicode("SWHID")
897+
898+
async def get_resolved_ref(self):
899+
client = AsyncHTTPClient()
900+
req = HTTPRequest("https://archive.softwareheritage.org/api/1/known/",
901+
headers={'content-type': 'application/json'},
902+
body=json.dumps([self.spec]),
903+
user_agent="BinderHub")
904+
r = await client.fetch(req)
905+
r.rethrow()
906+
907+
response = json.loads(r.body)
908+
if response[self.spec]["known"]:
909+
return self.spec
910+
raise RuntimeError(f"Unknown SWHID {self.spec}")
911+
912+
913+
async def get_resolved_spec(self):
914+
return self.spec
915+
916+
def get_repo_url(self):
917+
# While called repo URL, the return value of this function is passed
918+
# as argument to repo2docker, hence we return the spec as is.
919+
return self.spec
920+
921+
async def get_resolved_ref_url(self):
922+
return self.spec
923+
924+
def get_build_slug(self):
925+
return "swh-{}".format(self.spec)

binderhub/static/js/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ function updateRepoText() {
9999
$("#ref").prop("disabled", true);
100100
$("label[for=ref]").prop("disabled", true);
101101
}
102+
else if (provider === "swh") {
103+
text = "Software Heritage SWHID (swh:1:rev:c30614ec4587418fb264efb466cba58991029f16)";
104+
$("#ref").prop("disabled", true);
105+
$("label[for=ref]").prop("disabled", true);
106+
}
102107
$("#repository").attr('placeholder', text);
103108
$("label[for=repository]").text(text);
104109
$("#ref").attr('placeholder', placeholder);
@@ -123,7 +128,7 @@ function getBuildFormValues() {
123128

124129
var ref = $('#ref').val().trim() || $("#ref").attr("placeholder");
125130
if (providerPrefix === 'zenodo' || providerPrefix === 'figshare' || providerPrefix === 'dataverse' ||
126-
providerPrefix === 'hydroshare') {
131+
providerPrefix === 'hydroshare' || providerPrefix === 'swh') {
127132
ref = "";
128133
}
129134
var path = $('#filepath').val().trim();

binderhub/templates/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ <h4 id="form-header" class='row'>Build and launch a repository</h4>
6060
<li class="dropdown-item" value="figshare"><a href="#">Figshare DOI</a></li>
6161
<li class="dropdown-item" value="hydroshare"><a href="#">Hydroshare resource</a></li>
6262
<li class="dropdown-item" value="dataverse"><a href="#">Dataverse DOI</a></li>
63+
<li class="dropdown-item" value="swh"><a href="#">Software Heritage SWHID</a></li>
6364
</ul>
6465
</div>
6566
<input class="form-control" type="text" id="repository" data-lpignore="true" placeholder="GitHub repository name or link"/>

binderhub/tests/test_repoproviders.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
GitLabRepoProvider,
1313
GitRepoProvider,
1414
HydroshareProvider,
15+
SWHIDProvider,
1516
ZenodoProvider,
1617
strip_suffix,
1718
tokenize_spec,
@@ -490,3 +491,27 @@ def test_gist_secret():
490491

491492
provider = GistRepoProvider(spec=spec, allow_secret_gist=True)
492493
assert IOLoop().run_sync(provider.get_resolved_ref) is not None
494+
495+
496+
@pytest.mark.parametrize('spec,resolved_spec,resolved_ref,resolved_ref_url,build_slug', [
497+
['swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
498+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
499+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
500+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
501+
'swh-swh:1:rev:c30614ec4587418fb264efb466cba58991029f16'],
502+
])
503+
async def test_swh(spec, resolved_spec, resolved_ref, resolved_ref_url, build_slug):
504+
provider = SWHIDProvider(spec=spec)
505+
506+
# have to resolve the ref first
507+
ref = await provider.get_resolved_ref()
508+
assert ref == resolved_ref
509+
510+
slug = provider.get_build_slug()
511+
assert slug == build_slug
512+
repo_url = provider.get_repo_url()
513+
assert repo_url == spec
514+
ref_url = await provider.get_resolved_ref_url()
515+
assert ref_url == resolved_ref_url
516+
spec = await provider.get_resolved_spec()
517+
assert spec == resolved_spec

doc/developer/repoproviders.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ Currently supported providers, their prefixes and specs are:
3838
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
3939
| Git | ``git`` | ``<url-escaped-url>/<commit-sha>`` | A generic repository provider for URLs that point directly to a git repository. |
4040
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
41+
| SWHID | ``swh`` | ``<SWHID>`` | A `Software Heritage persistent identifier`_. |
42+
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
43+
44+
45+
.. _`Software Heritage persistent identifier`: https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html#persistent-identifiers
46+
4147

4248
Adding a new repository provider
4349
================================

doc/reference/repoproviders.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,10 @@ Module: :mod:`binderhub.repoproviders`
7171

7272
.. autoconfigurable:: GitRepoProvider
7373
:members:
74+
75+
76+
:class:`SWHIDProvider`
77+
---------------------------
78+
79+
.. autoconfigurable:: SWHIDProvider
80+
:members:

0 commit comments

Comments
 (0)