CINXE.COM

For Developers - EUDAT Documentation

<!doctype html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="canonical" href="https://docs.eudat.eu/b2safe/fordevelopers/"> <link rel="prev" href="../foradministrators/"> <link rel="next" href="../about/"> <link rel="icon" href="../../assets/images/favicon.png"> <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.3"> <title>For Developers - EUDAT Documentation</title> <link rel="stylesheet" href="../../assets/stylesheets/main.d7758b05.min.css"> <link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"> <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style> <link rel="stylesheet" href="../../config/extra.css"> <script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script> </head> <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo"> <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <label class="md-overlay" for="__drawer"></label> <div data-md-component="skip"> <a href="#best-practices-for-developers" class="md-skip"> Skip to content </a> </div> <div data-md-component="announce"> </div> <header class="md-header" data-md-component="header"> <nav class="md-header__inner md-grid" aria-label="Header"> <a href="../.." title="EUDAT Documentation" class="md-header__button md-logo" aria-label="EUDAT Documentation" data-md-component="logo"> <img src="../../images/EUDAT_Partial_White.png" alt="logo"> </a> <label class="md-header__button md-icon" for="__drawer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class="md-header__title" data-md-component="header-title"> <div class="md-header__ellipsis"> <div class="md-header__topic"> <span class="md-ellipsis"> EUDAT Documentation </span> </div> <div class="md-header__topic" data-md-component="header-topic"> <span class="md-ellipsis"> For Developers </span> </div> </div> </div> <form class="md-header__option" data-md-component="palette"> <input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0"> <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 0-7 7c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.26c1.81-1.27 3-3.36 3-5.74a7 7 0 0 0-7-7M9 21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1H9z"/></svg> </label> <input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1"> <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 1 7 7c0 2.38-1.19 4.47-3 5.74V17a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 0 1 7-7M9 21v-1h6v1a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1m3-17a5 5 0 0 0-5 5c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58a5 5 0 0 0-5-5"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class="md-search" data-md-component="search" role="dialog"> <label class="md-search__overlay" for="__search"></label> <div class="md-search__inner" role="search"> <form class="md-search__form" name="search"> <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required> <label class="md-search__icon md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class="md-search__options" aria-label="Search"> <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> <div class="md-search__suggest" data-md-component="search-suggest"></div> </form> <div class="md-search__output"> <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix> <div class="md-search-result" data-md-component="search-result"> <div class="md-search-result__meta"> Initializing search </div> <ol class="md-search-result__list" role="presentation"></ol> </div> </div> </div> </div> </div> </nav> </header> <div class="md-container" data-md-component="container"> <nav class="md-tabs" aria-label="Tabs" data-md-component="tabs"> <div class="md-grid"> <ul class="md-tabs__list"> <li class="md-tabs__item"> <a href="../.." class="md-tabs__link"> Documentation </a> </li> <li class="md-tabs__item"> <a href="../../b2access/" class="md-tabs__link"> B2ACCESS </a> </li> <li class="md-tabs__item"> <a href="../../b2drop/" class="md-tabs__link"> B2DROP </a> </li> <li class="md-tabs__item"> <a href="../../b2find/" class="md-tabs__link"> B2FIND </a> </li> <li class="md-tabs__item"> <a href="../../b2handle/" class="md-tabs__link"> B2HANDLE </a> </li> <li class="md-tabs__item"> <a href="../../b2inst/" class="md-tabs__link"> B2INST </a> </li> <li class="md-tabs__item md-tabs__item--active"> <a href="../" class="md-tabs__link"> B2SAFE </a> </li> <li class="md-tabs__item"> <a href="../../b2share/overview/" class="md-tabs__link"> B2SHARE </a> </li> <li class="md-tabs__item"> <a href="../../datacite/" class="md-tabs__link"> DataCite </a> </li> <li class="md-tabs__item"> <a href="https://eudat.eu" class="md-tabs__link"> EUDAT website </a> </li> <li class="md-tabs__item"> <a href="https://eudat.eu/contact-support-request" class="md-tabs__link"> Feedback + Support </a> </li> </ul> </div> </nav> <main class="md-main" data-md-component="main"> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0"> <label class="md-nav__title" for="__drawer"> <a href="../.." title="EUDAT Documentation" class="md-nav__button md-logo" aria-label="EUDAT Documentation" data-md-component="logo"> <img src="../../images/EUDAT_Partial_White.png" alt="logo"> </a> EUDAT Documentation </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../.." class="md-nav__link"> <span class="md-ellipsis"> Documentation </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" > <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0"> <span class="md-ellipsis"> B2ACCESS </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2"> <span class="md-nav__icon md-icon"></span> B2ACCESS </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2access/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/assurance/" class="md-nav__link"> <span class="md-ellipsis"> Assurance </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/concepts/" class="md-nav__link"> <span class="md-ellipsis"> Concepts </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4" > <label class="md-nav__link" for="__nav_2_4" id="__nav_2_4_label" tabindex="0"> <span class="md-ellipsis"> For Users </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2_4"> <span class="md-nav__icon md-icon"></span> For Users </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2access/howto-mfa/" class="md-nav__link"> <span class="md-ellipsis"> Enabling MFA </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/howto-update-email/" class="md-nav__link"> <span class="md-ellipsis"> Updating Email </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/list-of-connected-organisations/" class="md-nav__link"> <span class="md-ellipsis"> List of connected organisations </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_4" > <label class="md-nav__link" for="__nav_2_4_4" id="__nav_2_4_4_label" tabindex="0"> <span class="md-ellipsis"> For group administrators </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2_4_4"> <span class="md-nav__icon md-icon"></span> For group administrators </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2access/howto-vos/" class="md-nav__link"> <span class="md-ellipsis"> Requesting a group </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/howto-vo-management/" class="md-nav__link"> <span class="md-ellipsis"> Managing a group </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_5" > <label class="md-nav__link" for="__nav_2_4_5" id="__nav_2_4_5_label" tabindex="0"> <span class="md-ellipsis"> For Service Providers </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_5_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2_4_5"> <span class="md-nav__icon md-icon"></span> For Service Providers </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2access/howto-services/" class="md-nav__link"> <span class="md-ellipsis"> Registering a services </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/attributes-sp/" class="md-nav__link"> <span class="md-ellipsis"> Available attributes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_6" > <label class="md-nav__link" for="__nav_2_4_6" id="__nav_2_4_6_label" tabindex="0"> <span class="md-ellipsis"> For Identity Providers </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_6_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2_4_6"> <span class="md-nav__icon md-icon"></span> For Identity Providers </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2access/howto-idps/" class="md-nav__link"> <span class="md-ellipsis"> Joining as an Identity Provider </span> </a> </li> <li class="md-nav__item"> <a href="../../b2access/attributes-idp/" class="md-nav__link"> <span class="md-ellipsis"> Consumed attributes </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../b2access/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" > <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0"> <span class="md-ellipsis"> B2DROP </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3"> <span class="md-nav__icon md-icon"></span> B2DROP </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2drop/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_2" > <label class="md-nav__link" for="__nav_3_2" id="__nav_3_2_label" tabindex="0"> <span class="md-ellipsis"> For Users </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3_2"> <span class="md-nav__icon md-icon"></span> For Users </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2drop/user/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_2_2" > <label class="md-nav__link" for="__nav_3_2_2" id="__nav_3_2_2_label" tabindex="0"> <span class="md-ellipsis"> For groups </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_3_2_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3_2_2"> <span class="md-nav__icon md-icon"></span> For groups </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2drop/groups/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_3" > <label class="md-nav__link" for="__nav_3_3" id="__nav_3_3_label" tabindex="0"> <span class="md-ellipsis"> For Administrators </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3_3"> <span class="md-nav__icon md-icon"></span> For Administrators </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2drop/admin/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2drop/b2sharebridge/" class="md-nav__link"> <span class="md-ellipsis"> Enabling the B2SHAREbridge </span> </a> </li> <li class="md-nav__item"> <a href="../../b2drop/setup/" class="md-nav__link"> <span class="md-ellipsis"> Install B2DROP </span> </a> </li> <li class="md-nav__item"> <a href="../../b2drop/integration/" class="md-nav__link"> <span class="md-ellipsis"> Integrate with B2ACCESS </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../b2drop/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" > <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0"> <span class="md-ellipsis"> B2FIND </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_4"> <span class="md-nav__icon md-icon"></span> B2FIND </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2find/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2find/forusers/" class="md-nav__link"> <span class="md-ellipsis"> For Users </span> </a> </li> <li class="md-nav__item"> <a href="../../b2find/forproviders/" class="md-nav__link"> <span class="md-ellipsis"> For Providers </span> </a> </li> <li class="md-nav__item"> <a href="../../b2find/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" > <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0"> <span class="md-ellipsis"> B2HANDLE </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_5"> <span class="md-nav__icon md-icon"></span> B2HANDLE </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2handle/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/foradministrators/" class="md-nav__link"> <span class="md-ellipsis"> For Administrators </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" > <label class="md-nav__link" for="__nav_5_3" id="__nav_5_3_label" tabindex="0"> <span class="md-ellipsis"> For Developers </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_5_3"> <span class="md-nav__icon md-icon"></span> For Developers </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2handle/fordevelopers/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/fordevelopers_pyhandle/" class="md-nav__link"> <span class="md-ellipsis"> PyHandle for Developers </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/fordevelopers_b2handle/" class="md-nav__link"> <span class="md-ellipsis"> B2Handle for Developers </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/fordevelopers_api/" class="md-nav__link"> <span class="md-ellipsis"> API for Developers </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_4" > <label class="md-nav__link" for="__nav_5_4" id="__nav_5_4_label" tabindex="0"> <span class="md-ellipsis"> Information </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_5_4"> <span class="md-nav__icon md-icon"></span> Information </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2handle/ownership/" class="md-nav__link"> <span class="md-ellipsis"> Ownership </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/security/" class="md-nav__link"> <span class="md-ellipsis"> Security </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../b2handle/more/" class="md-nav__link"> <span class="md-ellipsis"> More Info </span> </a> </li> <li class="md-nav__item"> <a href="../../b2handle/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" > <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0"> <span class="md-ellipsis"> B2INST </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_6"> <span class="md-nav__icon md-icon"></span> B2INST </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2inst/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_2" > <label class="md-nav__link" for="__nav_6_2" id="__nav_6_2_label" tabindex="0"> <span class="md-ellipsis"> For Users </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_6_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_6_2"> <span class="md-nav__icon md-icon"></span> For Users </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2inst/forusers/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2inst/advancedsearch/" class="md-nav__link"> <span class="md-ellipsis"> Advanced Search </span> </a> </li> <li class="md-nav__item"> <a href="../../b2inst/httpapi/" class="md-nav__link"> <span class="md-ellipsis"> HTTP REST API </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../b2inst/foradministrators/" class="md-nav__link"> <span class="md-ellipsis"> For Administrators </span> </a> </li> <li class="md-nav__item"> <a href="../../b2inst/fordevelopers/" class="md-nav__link"> <span class="md-ellipsis"> For Developers </span> </a> </li> <li class="md-nav__item"> <a href="../../b2inst/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" checked> <label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex=""> <span class="md-ellipsis"> B2SAFE </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="true"> <label class="md-nav__title" for="__nav_7"> <span class="md-nav__icon md-icon"></span> B2SAFE </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../forusers/" class="md-nav__link"> <span class="md-ellipsis"> For Users </span> </a> </li> <li class="md-nav__item"> <a href="../foradministrators/" class="md-nav__link"> <span class="md-ellipsis"> For Administrators </span> </a> </li> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc"> <span class="md-ellipsis"> For Developers </span> <span class="md-nav__icon md-icon"></span> </label> <a href="./" class="md-nav__link md-nav__link--active"> <span class="md-ellipsis"> For Developers </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#definitions" class="md-nav__link"> <span class="md-ellipsis"> Definitions </span> </a> </li> <li class="md-nav__item"> <a href="#examples" class="md-nav__link"> <span class="md-ellipsis"> Examples </span> </a> <nav class="md-nav" aria-label="Examples"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#immutable-data-policy" class="md-nav__link"> <span class="md-ellipsis"> Immutable data policy </span> </a> </li> <li class="md-nav__item"> <a href="#mutable-data-policy" class="md-nav__link"> <span class="md-ellipsis"> Mutable data policy </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" > <label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0"> <span class="md-ellipsis"> B2SHARE </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_8"> <span class="md-nav__icon md-icon"></span> B2SHARE </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2share/overview/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8_2" > <label class="md-nav__link" for="__nav_8_2" id="__nav_8_2_label" tabindex="0"> <span class="md-ellipsis"> For Users </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_8_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_8_2"> <span class="md-nav__icon md-icon"></span> For Users </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2share/forusers/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2share/advancedsearch/" class="md-nav__link"> <span class="md-ellipsis"> Advance Search </span> </a> </li> <li class="md-nav__item"> <a href="../../b2share/httpapi/" class="md-nav__link"> <span class="md-ellipsis"> HTTP REST API </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8_3" > <label class="md-nav__link" for="__nav_8_3" id="__nav_8_3_label" tabindex="0"> <span class="md-ellipsis"> For Developers </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_8_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_8_3"> <span class="md-nav__icon md-icon"></span> For Developers </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2share/fordevelopers/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8_4" > <label class="md-nav__link" for="__nav_8_4" id="__nav_8_4_label" tabindex="0"> <span class="md-ellipsis"> For Administrators </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_8_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_8_4"> <span class="md-nav__icon md-icon"></span> For Administrators </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../b2share/foradministrators/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../b2share/cli/" class="md-nav__link"> <span class="md-ellipsis"> Command Line Interface (CLI) </span> </a> </li> <li class="md-nav__item"> <a href="../../b2share/httpapi/" class="md-nav__link"> <span class="md-ellipsis"> HTTP REST API </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../b2share/faq/" class="md-nav__link"> <span class="md-ellipsis"> F.A.Q.s </span> </a> </li> <li class="md-nav__item"> <a href="../../b2share/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_9" > <label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="0"> <span class="md-ellipsis"> DataCite </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_9"> <span class="md-nav__icon md-icon"></span> DataCite </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../datacite/" class="md-nav__link"> <span class="md-ellipsis"> Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../datacite/forusers/" class="md-nav__link"> <span class="md-ellipsis"> For Users </span> </a> </li> <li class="md-nav__item"> <a href="../../datacite/about/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="https://eudat.eu" class="md-nav__link"> <span class="md-ellipsis"> EUDAT website </span> </a> </li> <li class="md-nav__item"> <a href="https://eudat.eu/contact-support-request" class="md-nav__link"> <span class="md-ellipsis"> Feedback + Support </span> </a> </li> </ul> </nav> </div> </div> </div> <div class="md-content" data-md-component="content"> <article class="md-content__inner md-typeset"> <h1 id="best-practices-for-developers">Best practices for developers<a class="headerlink" href="#best-practices-for-developers" title="Permanent link">#</a></h1> <h2 id="definitions">Definitions<a class="headerlink" href="#definitions" title="Permanent link">#</a></h2> <p>The B2SAFE service relies on iRODS to implements data policies. The implementation is based on set of operations, which we call rules. Multiple rules can be combined to form <a href="https://gitlab.eudat.eu/b2safe/B2SAFE-core/-/wikis/Workflows" title="workflows">workflows</a>. Each rule or workflow can be triggered manually, client side, or automatically, server side, setting a trigger condition in the irods configuration files (usually in the file core.re in /etc/irods). In iRODS exists an object called workflow (WSO, Workflow Structured Object), but we are not referring to that, just to a generic set of rules. Based on our definition, every set of rules, a workflow, it is a rule, but we tend to call workflows only the set of rules which become quite complex. </p> <p>Example of rule:<br /> <code>EUDATCreateAVU("EUDAT/FIO", *newPID, *path);</code><br /> (it adds the key-value pair (&ldquo;EUDAT/FIO&rdquo;, *newPID) to the object stored in the input path) </p> <p>Example of workflow:<br /> <code>EUDATCreatePID(*parent_pid, *path, *ror, *fio, *fixed, *newPID);</code> (see the combined set of rules <a href="https://gitlab.eudat.eu/b2safe/B2SAFE-core/-/raw/master/rulebase/pid-service.re" title="pid ruleset">here</a>) </p> <p>Example of trigger:<br /> <div class="highlight"><pre><span></span><code>acPostProcForCollCreate { ON($collName like &quot;/MyZone/home/username/*&quot;) { *fixed=&quot;false&quot;; EUDATPidsForColl($collName, *fixed); writeLine(&quot;serverLog&quot;,&quot;PID Created: for collection $collName&quot;); } } </code></pre></div> The above condition: <code>acPostProcForCollCreate</code>, is triggered every time a new collection is created.<br /> Inside a trigger you can add further filters. The example above uses: <code>ON($collName like "/MyZone/home/username/*")</code><br /> to apply the condition only to the collections created inside a specific path.<br /> A list of triggered conditions (called static Policy Enforcement Points, PEP) is available in the Appendix A at page 215 and in the Appendix B at page 217 of the <a href="http://datafed.org/dev/wp-content/uploads/2016/05/DFC-policy-examples.pdf" title="workbook">workbook</a>. Another one is in the <a href="https://docs.irods.org/master/plugins/dynamic_policy_enforcement_points" title="dynamic PEP">iRODS manual</a>. </p> <h2 id="examples">Examples<a class="headerlink" href="#examples" title="Permanent link">#</a></h2> <p>Let&rsquo;s now consider an important data policy: the uploaded data is immutable. And the opposite one: the uploaded data is mutable. If the uploaded data is immutable what it is needed to enforce such policy?</p> <h3 id="immutable-data-policy">Immutable data policy<a class="headerlink" href="#immutable-data-policy" title="Permanent link">#</a></h3> <p>This kind of policy is usually agreed with the data owners, for example a scientific community. Therefore the B2SAFE administrator can rely on the fact that the scientific community will not break the policy and just set the following trigger in the iRODS core.re to create a PID for each uploaded object: <div class="highlight"><pre><span></span><code>acPostProcForPut { ON($objPath like &quot;/MyZone/home/community/*&quot;) { *fixed = &quot;true&quot;; EUDATCreatePID(&quot;None&quot;, $objPath, &quot;None&quot;, &quot;None&quot;, *fixed, *PID); writeLine(&quot;serverLog&quot;,&quot;PID Created: *PID for object $objPath&quot;); } } </code></pre></div> The attribute <em>fixed</em> is a way to declare explicitly that the object is not expected to change.<br /> However our B2SAFE administrator does not trust the community&rsquo;s users, she wants to enforce, server side, this policy.<br /> In order to do so, she has two options:<br /> 1. to intercept every attempt to modify the uploaded objects:<br /> 2. to define a staging space where the users can upload the data and, after each upload, move them to another space where the users have only read access. </p> <p>1) in this case, she could define a trigger like the following one: <div class="highlight"><pre><span></span><code>acPreProcForModifyDataObjMeta { ON($objPath like &quot;/MyZone/home/community/*&quot;) { writeLine(&quot;serverLog&quot;,&quot;attempt to modify $objPath&quot;); msiExit(&quot;-1&quot;, &quot;user is not allowed to perform the requested action&quot;); } } </code></pre></div> 2) in this case it is necessary something more complex: <div class="highlight"><pre><span></span><code>dataArchiveCopy(*collPath, *archivePath) { foreach ( *res in SELECT DATA_NAME WHERE COLL_NAME = &#39;*collPath&#39; ) { *objName = *res.DATA_NAME; *objPath = *collPath ++ &quot;/&quot; ++ *objName; msiSetACL(&quot;default&quot;, &quot;admin:own&quot;, *adminUser, *objPath); *destination = *archivePath ++ &quot;/&quot; ++ *objName; msiDataObjCopy(*objPath, *destination); msiDataObjUnlink(*objPath, *out); *fixed = &quot;true&quot;; EUDATCreatePID(&quot;None&quot;, *destination, &quot;None&quot;, &quot;None&quot;, *fixed, *PID); writeLine(&quot;serverLog&quot;,&quot;PID Created: *PID for object *destination&quot;); *owners = list(); foreach ( *R in SELECT DATA_OWNER_NAME, DATA_NAME WHERE COLL_NAME = &#39;*collPath&#39; AND DATA_NAME = &#39;*objName&#39; ) { *owners = cons(*R.DATA_OWNER_NAME, *owners); } if (size(*owners) &gt; 0) { foreach (*user in *owners) { msiSetACL(&quot;default&quot;, &quot;read&quot;, *user, *destination); } } } } </code></pre></div> The above rule should be executed periodically by the B2SAFE administrator.<br /> The first approach could work for few collections, but it would not scale for many collections and multiple communities. The latter is more general, but it requires more care during its configuration. </p> <h3 id="mutable-data-policy">Mutable data policy<a class="headerlink" href="#mutable-data-policy" title="Permanent link">#</a></h3> <p>What happens, at the opposite, if the community asks to keep open the data set for future changes?<br /> Assuming the data have PIDs and are replicated across different iRODS zones, the update of an object implies to propagate the changes both to the PID record&rsquo;s attributes and to the object&rsquo;s replicas. Does B2SAFE supports such propagation? It does, in the sense that it provides the means to define a workflow to manage those updates.<br /> For example, in the case of the PID record, if you overwrite an object, you need to update the checksum. Then the B2SAFE administrator can configure the following trigger:<br /> <div class="highlight"><pre><span></span><code>acPostProcForModifyDataObjMeta { ON($objPath like &quot;/MyZone/home/community/*&quot;) { getEpicApiParameters(*credStoreType, *credStorePath, *epicApi, *serverID, *epicDebug); EUDATSearchPID($objPath, *existing_pid); EUDATeCHECKSUMupdate(*existing_pid, $objPath); writeLine(&quot;serverLog&quot;,&quot;checksum updated for object: $objPath&quot;); } } </code></pre></div> And in the case of the object&rsquo;s replica, she can add this code to the same trigger: <div class="highlight"><pre><span></span><code>[...] *replicaList = list(); EUDATgetLastAVU($objPath, &quot;EUDAT/REPLICA&quot;, *replicas); if ((*replicas != &quot;&quot;) &amp;&amp; (*replica != &quot;None&quot;)) { *replicaList = split(*replicas, &quot;,&quot;); foreach (*replica in *replicaList) { EUDATeURLsearch(*replica, *URL); *hostAndPath = elem(split(*URL, &quot;://&quot;), 1); *replicaPath = &quot;/&quot; ++ triml(*hostAndPath, &quot;/&quot;); msiDataObjUnlink(*replicaPath, *out); *registered = &quot;true&quot;; *recursive = &quot;true&quot;; EUDATReplication($objPath, *replicaPath, *registered, *recursive, *response); writeLine(&quot;serverLog&quot;,&quot;Updated replica *replicaPath for object $objPath: *response&quot;); } } [...] </code></pre></div> If the B2SAFE administrator needs to change the local path of a collection, it can define similar triggers with other B2SAFE rules: <em>EUDATeURLupdate(<em>PID, </em>newURL)</em> to update the URL of a PID record or <em>EUDATeURLupdateColl(<em>PID, </em>newURL)</em> to update recursively the URL of a collection and of all the objects and sub-collections under the main one.</p> <hr /> <p>Those are examples of possible solutions to implement the most common data policies. They are not granted to work as they are, they could require to be adapted to the specific B2SAFE environment. But they intend to show that B2SAFE provides the building blocks to support the various data workflows and it is flexible enough to meet different scenarios. </p> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type="button" class="md-top md-icon" data-md-component="top" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class="md-footer"> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> <div class="md-copyright__highlight"> This documentation is licensed under <a href='https://creativecommons.org/licenses/by-sa/3.0/legalcode'>CC BY-SA 3.0 &nbsp; &nbsp; &nbsp;<img src='/images/cc-by-sa_icon.png'></a> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <!-- a href=''>Imprint</a --> </div> </div> <div class="md-social"> <a href="https://gitlab.eudat.eu/sa.apweiler/eudat-documentation" target="_blank" rel="noopener" title="gitlab.eudat.eu" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"base": "../..", "features": ["navigation.sections", "navigation.tabs", "navigation.top", "toc.integrate", "search.suggest"], "search": "../../assets/javascripts/workers/search.f8cc74c7.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script> <script src="../../assets/javascripts/bundle.f1b6f286.min.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10