ds-wizard / ds-wizard

DSW Common Repository
https://ds-wizard.org
17 stars 1 forks source link

FAIRsharing integration #280

Closed froggypaule closed 1 year ago

froggypaule commented 1 year ago

What is your question?

First, apologies to @MarekSuchanek as we discussed this ages ago but I let it drop and only coming back to it now.

DSW self-hosted, V3.23.

Following FAIRsharing's doc, this works

import requests
import json

url = "https://api.fairsharing.org/users/sign_in"

payload={"user": {"login":"plieby","password":"xxxx"} }
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=json.dumps(payload))

# Get the JWT from the response.text to use in the next part.
data = response.json()
jwt = data['jwt']
url = "https://api.fairsharing.org/fairsharing_records/1"

headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'Authorization': "Bearer {0}".format(jwt),
}

response = requests.request("GET", url, headers=headers)
print(response.text)

This works too, making it a one call pass (jwt takes the saved value from above)

jwt = "xxx"
url = "https://api.fairsharing.org/search/fairsharing_records?fairsharing_registry=standard&q=Mouse Adult Gross Anatomy Ontology"
response = requests.request("POST", url, headers=headers)
print(response.json())
froggypaule commented 1 year ago

Following this, I thought of saving apiUrl and apiKey in an integration.yml file, as follows

fairsharing:
  apiKey:  xxx
  apiUrl: https://api.fairsharing.org

but this gives me the following error

Screenshot from 2023-05-17 09-27-21

So obviously I don't know how to handle this.

froggypaule commented 1 year ago

Also, I note that the configuration found in the Common DSW KM is different from the requests I built as explained in the FAIRsharing doc: Screenshot from 2023-05-17 09-28-52

so,

${apiUrl}/search/?q=${q}&registry=${registry}

instead of

url = "https://api.fairsharing.org/search/fairsharing_records
url = "https://api.fairsharing.org/search/fairsharing_records?fairsharing_registry=standard&q=Mouse Adult Gross Anatomy Ontology"
'Authorization': "Bearer {0}".format(jwt),

instead of Api-Key, and

response = requests.request("POST", url, headers=headers)

instead of GET

So I am a bit confused .... ;) thanks for helping out.

MarekSuchanek commented 1 year ago

Indeed, the old approach does not work anymore with FAIRsharing as they changed the API and mainly its authentication procedure. DSW cannot make additional authentication requests before (potentially each) API query... to overcome this, we developed a simple proxy service (there are still some things to improve, but it works well for now).

  1. You need to have account to FAIRsharing with username and password (and related to an organisation).
  2. Then, you should use BASE64 to encode: username:password (e.g. run echo -n 'username:password' | base64)
  3. Finally, you should have your integration.yml like this:
fairsharing:
  apiUrl: https://fairsharing4dsw.ds-wizard.org/legacy
  apiKey: "<base64credentials>"

The proxy basically does the two steps and imitates the way how the old FAIRsharing API worked (filtering and result format). We plan to improve it with some caching later on and improve documentation, but not a huge priority at this point.

You can test it to "fake" the request from DSW:

curl --header "Accept: application/json" \
     --header "Api-Key: <base64credentials>" \
     "https://fairsharing4dsw.ds-wizard.org/legacy/search/?q=banana&registry=database"

Final remark, the proxy is allowed to be used only for DSW purposes (integration from DSW or testing it in order to use it in DSW).

Do you have any suggestion where would be the best place to document this?

froggypaule commented 1 year ago

Hello Marek! Ha!! this makes sense: that we are using a legacy proxy, I understand now you configuration. I suggest to document this in https://guide.ds-wizard.org/en/latest/more/development/integration-questions/integration-api.html where there is a FAIRsharing example. So that people like me don't keep asking the same question... ;)

froggypaule commented 1 year ago

One more thing: where is the integration.yml supposed to sit? because in my case, it is still not read properly. Otherwise, yes, the curl cmd is working!

MarekSuchanek commented 1 year ago

It should be in /app/config/integration.yml (next to the app configuration file). But you can also configure it in Settings (see guide).

froggypaule commented 1 year ago

!!!! Victory!!! many thanks :)