HUPO-PSI / proxi-schemas

ProXI: Schema definitions for the Proteomics eXpression Interface
3 stars 3 forks source link

Develop JSON Schema validator #70

Open RalfG opened 3 years ago

RalfG commented 3 years ago

As discussed during today's call, we need a validator for the JSON response that goes further than only checking whether there is a response or not.

RalfG commented 3 years ago

I guess some of these might come in handy: https://github.com/json-schema-org/JSON-Schema-Test-Suite#python

RalfG commented 3 years ago

@edeutsch, @bittremieux,

Here's a simple Python script that does exactly what we want:

"""
Validate API response with OpenAPI YAML schema.

For example:

$ python proxi_validator.py --openapi-yaml "specs/swagger.yaml" --request-url "http://proteomecentral.proteomexchange.org/api/proxi/v0.1/spectra?resultType=full&usi=mzspec:PXL000006:02-14-2019:index:1250"

"""

import click
import requests
import yaml
from jsonschema import validate
from openapi_schema_to_json_schema import to_json_schema

def jsonschema_from_yaml_file(path_to_yaml):
    """Read OpenAPI schema yaml file and return as JSON Schema dictionary."""
    with open(path_to_yaml, 'r') as stream:
        open_api_schema = yaml.safe_load(stream)
    jsonschema = to_json_schema(open_api_schema)
    return jsonschema

def get_api_response(url):
    """Get API response JSON object."""
    response = requests.get(url)
    return response.json()

@click.command()
@click.argument("openapi-yaml", type=str)
@click.argument("request-url", type=str)
def main(**kwargs):
    """Validate API response with OpenAPI YAML schema."""
    validate(
        get_api_response(kwargs["request_url"]),
        schema=jsonschema_from_yaml_file(kwargs["openapi_yaml"])
    )

if __name__ == "__main__":
    main()

A ValidationError is thrown if the API response is invalid for the given swagger.yaml file.

Do I open a PR to add the script to the repository?

bittremieux commented 3 years ago

Ah crap, I should've checked GitHub first, because I started on my own script.

With the flex library you can actually avoid having to convert the Swagger file to JSON schema, so that should be a bit more efficient.

The code is very simple:

import requests
from flex.core import load, validate_api_call

schema = load('https://raw.githubusercontent.com/HUPO-PSI/proxi-schemas/master/specs/swagger.yaml')

url = 'http://proteomecentral.proteomexchange.org/api/proxi/v0.1/spectra?resultType=full&usi=mzspec:PXL000006:02-14-2019:index:1250'
response = requests.get(url)

validate_api_call(schema, raw_request=response.request, raw_response=response)

See also the flex documentation on API call validation.

There seem to be several issues with the Swagger definition file and the API response preventing successful validation. So I guess it's good to have a validator. 😉