Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsonschema.exceptions.SchemaError when saving chart as html #2705

Closed
shnela opened this issue Nov 4, 2022 · 7 comments
Closed

jsonschema.exceptions.SchemaError when saving chart as html #2705

shnela opened this issue Nov 4, 2022 · 7 comments
Labels

Comments

@shnela
Copy link

shnela commented Nov 4, 2022

Hi, I'm uising newest version of altair==4.2.0 and code which worked previously now breaks with SchemaError.

I present whole code snippet and Stacktrace below.

from io import StringIO

import altair as alt
from vega_datasets import data


def save_to_stream(chart):
    buffer = StringIO()
    chart.save(buffer, format="html")


if __name__ == "__main__":
    source = data.cars()

    brush = alt.selection(type='interval')

    points = alt.Chart(source).mark_point().encode(
        x='Horsepower:Q',
        y='Miles_per_Gallon:Q',
        color=alt.condition(brush, 'Origin:N', alt.value('lightgray'))
    ).add_selection(
        brush
    )

    bars = alt.Chart(source).mark_bar().encode(
        y='Origin:N',
        color='Origin:N',
        x='count(Origin):Q'
    ).transform_filter(
        brush
    )

    chart = points & bars

    save_to_stream(points)  # works
    save_to_stream(bars)  # works
    save_to_stream(chart)  # breaks

"""
/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/utils/core.py:317: FutureWarning: iteritems is deprecated and will be removed in a future version. Use .items instead.
  for col_name, dtype in df.dtypes.iteritems():
Traceback (most recent call last):
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/jsonschema/_format.py", line 135, in check
    result = func(instance)
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/jsonschema/_format.py", line 360, in is_uri_reference
    return rfc3987.parse(instance, rule="URI_reference")
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/rfc3987.py", line 462, in parse
    raise ValueError('%r is not a valid %r.' % (string, rule))
ValueError: '#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>' is not a valid 'URI_reference'.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/jakub/Projects/neptune-client/alpha_integration_dev/tmp_upload2.py", line 37, in <module>
    save_to_stream(chart)  # breaks
  File "/home/jakub/Projects/neptune-client/alpha_integration_dev/tmp_upload2.py", line 9, in save_to_stream
    chart.save(buffer, format="html")
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/vegalite/v4/api.py", line 488, in save
    result = save(**kwds)
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/utils/save.py", line 83, in save
    spec = chart.to_dict()
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/vegalite/v4/api.py", line 384, in to_dict
    dct = super(TopLevelMixin, copy).to_dict(*args, **kwargs)
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/utils/schemapi.py", line 338, in to_dict
    self.validate(result)
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/altair/utils/schemapi.py", line 443, in validate
    return jsonschema.validate(
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/jsonschema/validators.py", line 1112, in validate
    cls.check_schema(schema)
  File "/home/jakub/.venv/neptune-client/lib/python3.8/site-packages/jsonschema/validators.py", line 227, in check_schema
    raise exceptions.SchemaError.create_from(error)
jsonschema.exceptions.SchemaError: '#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>' is not a 'uri-reference'

Failed validating 'format' in metaschema['properties']['$ref']:
    {'format': 'uri-reference', 'type': 'string'}

On schema['$ref']:
    '#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>'

Process finished with exit code 1
"""
@shnela shnela added the bug label Nov 4, 2022
@shnela
Copy link
Author

shnela commented Nov 4, 2022

I've checked previous versions of altair and I've noticed that it worked in 3.3.0 but broke on 4.0.0.

@joelostblom
Copy link
Contributor

What is your version of jsonschema? Your example works for me with Altair 4.2.0 and jsonschema 4.16.0

@shnela
Copy link
Author

shnela commented Nov 4, 2022

Oh, with jsonschema==4.16.0 it works.
I've had jsonschema==4.17.0 installed.

It's jsonschema problem then.

@shnela
Copy link
Author

shnela commented Nov 4, 2022

I think this may be problem with altair schema.

The check_schema method on jsonschema.protocols.Validator instances now enables format validation by default when run. This can catch some additional invalid schemas (e.g. containing invalid regular expressions) where the issue is indeed uncovered by validating against the metaschema with format validation enabled as an assertion.

From jsonschema v4.17 release note

@binste
Copy link
Contributor

binste commented Dec 24, 2022

Thank you @shnela for the hint with the format validation introduced in 4.17. I'm not sure yet how to fix it but leaving some notes here on how to reproduce it.

  • jsonschema==4.17 introduced format validation by default on check_schema as mentioned above
  • $ref is of format uri-reference. However, if you simply pip install jsonschema, their is not necessarily a format validator for uri-reference available and so it might not be validated and everything still works. You can see all enabled format checkers with
from jsonschema.validators import Draft7Validator
Draft7Validator.FORMAT_CHECKER
# <FormatChecker checkers=['date', 'email', 'idn-email', 'ipv4', 'ipv6', 'regex']>
<FormatChecker checkers=['date', 'email', 'idn-email', 'ipv4', 'ipv6', 'iri', 'iri-reference', 'regex', 'uri', 'uri-reference']>
  • You can now import it and reproduce the error
from jsonschema._format import is_uri_reference
is_uri_reference("#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[6], line 1
----> 1 is_uri_reference("#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>")

File /usr/local/lib/python3.8/site-packages/jsonschema/_format.py:360, in is_uri_reference(instance)
    358 if not isinstance(instance, str):
    359     return True
--> 360 return rfc3987.parse(instance, rule="URI_reference")

File /usr/local/lib/python3.8/site-packages/rfc3987.py:462, in parse(string, rule)
    460 m = match(string, rule)
    461 if not m:
--> 462     raise ValueError('%r is not a valid %r.' % (string, rule))
    463 if REGEX:
    464     return _i2u(m.groupdict())

ValueError: '#/definitions/TopLevelNormalizedVConcatSpec<GenericSpec>' is not a valid 'URI_reference'.

@AdamCiuris
Copy link

AdamCiuris commented Dec 30, 2022

I commented out the lines raising the error (jsonschema.validators.py::230-231) and it worked, lol. Still makes my concatenated charts fine which is what was raising the error.

@mattijn
Copy link
Contributor

mattijn commented Jan 4, 2023

Closed #2705 as completed via #2771.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants