Skip to content

Commit

Permalink
no disk caching (#20)
Browse files Browse the repository at this point in the history
* better caching

* no disk caching at all

* update manifest

* remove gitignore

* fix network requests

* remove unused imports

* remove potential key error

* rename url

* change ns check

* undo path modification
  • Loading branch information
tlambert03 authored Aug 6, 2020
1 parent 4c667ff commit bb37ec0
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 47 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ jobs:
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -U setuptools setuptools_scm wheel
pip install -U setuptools setuptools_scm wheel check-manifest
pip install -e .[autogen]
- name: Build Distribution
run: |
TAG="${GITHUB_REF/refs\/tags\/v/}"
echo "::set-env name=tag::$TAG"
check-manifest
python setup.py sdist bdist_wheel
- name: Create Release
id: create_release
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,4 @@ venv.bak/
.DS_Store
_test_data
src/ome_types/model/
src/ome_types/*.pkl
src/ome_types/_version.py
src/ome_types/_version.py
4 changes: 3 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
include LICENSE README.md setup.py pyproject.toml
include LICENSE README.md setup.py pyproject.toml
recursive-include src *.xsd
recursive-exclude testing *
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
[build-system]
requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4", "black", "isort<5.0", "xmlschema", "pydantic"]
build-backend = "setuptools.build_meta"

[tool.check-manifest]
ignore = [
"*src/ome_types/model/*",
"mypy.ini",
"src/ome_types/_version.py", # added by setuptools_scm during build
]
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ install_requires =
pydantic[email]>=1.0
xmlschema>=1.0.16

[options.package_data]
* = *.xsd

[options.extras_require]
autogen = isort<5.0; black

Expand Down
File renamed without changes.
74 changes: 43 additions & 31 deletions src/ome_types/schema.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import pickle
import re
from os.path import dirname, exists, join
from functools import lru_cache
from pathlib import Path
from typing import Any, Dict, Optional, Union
from xml.etree import ElementTree
from typing import Any, Dict, Optional

import xmlschema
from xmlschema.converters import XMLSchemaConverter

from .model import _field_plurals


NS_OME = "{http://www.openmicroscopy.org/Schemas/OME/2016-06}"
URI_OME = "http://www.openmicroscopy.org/Schemas/OME/2016-06"
NS_OME = "{" + URI_OME + "}"

__cache__: Dict[str, xmlschema.XMLSchema] = {}

Expand All @@ -23,32 +23,44 @@ def camel_to_snake(name: str) -> str:
return result


def get_schema(xml: str) -> xmlschema.XMLSchema:
url = xmlschema.fetch_schema(xml)
version = (
re.split("(.com|.org)", url)[-1]
.replace("/", "_")
.lstrip("_")
.replace(".xsd", "")
)
if version not in __cache__:
local = join(dirname(__file__), f"{version}.pkl")
if exists(local):
with open(local, "rb") as f:
__cache__[version] = pickle.load(f)
else:
schema = xmlschema.XMLSchema(url)

# FIXME Hack to work around xmlschema poor support for keyrefs to
# substitution groups
ls_sgs = schema.maps.substitution_groups[f"{NS_OME}LightSourceGroup"]
ls_id_maps = schema.maps.identities[f"{NS_OME}LightSourceIDKey"]
ls_id_maps.elements = {e: None for e in ls_sgs}

__cache__[version] = schema
with open(local, "wb") as f:
pickle.dump(__cache__[version], f)
return __cache__[version]
@lru_cache(maxsize=8)
def _build_schema(namespace: str) -> xmlschema.XMLSchema:
"""Return Schema object for a url.
For the special case of retrieving the 2016-06 OME Schema, use local file.
"""
if namespace == URI_OME:
schema = xmlschema.XMLSchema(str(Path(__file__).parent / "ome-2016-06.xsd"))
# FIXME Hack to work around xmlschema poor support for keyrefs to
# substitution groups
ls_sgs = schema.maps.substitution_groups[f"{NS_OME}LightSourceGroup"]
ls_id_maps = schema.maps.identities[f"{NS_OME}LightSourceIDKey"]
ls_id_maps.elements = {e: None for e in ls_sgs}
else:
schema = xmlschema.XMLSchema(namespace)
return schema


def get_schema(source: Union[xmlschema.XMLResource, str]) -> xmlschema.XMLSchema:
"""Fetch an XMLSchema object given XML source.
Parameters
----------
source : XMLResource or str
can be an :class:`xmlschema.XMLResource` instance, a file-like object, a path
to a file or an URI of a resource or an Element instance or an ElementTree
instance or a string containing the XML data.
Returns
-------
xmlschema.XMLSchema
An XMLSchema object for the source
"""
if not isinstance(source, xmlschema.XMLResource):
resource = xmlschema.XMLResource(source)
else:
resource = source
return _build_schema(resource.namespace)


def validate(xml: str, schema: Optional[xmlschema.XMLSchema] = None) -> None:
Expand Down
26 changes: 14 additions & 12 deletions testing/test_autogen.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import importlib
import os
import sys
from glob import glob
from pathlib import Path

import pytest
from xmlschema.validators.exceptions import XMLSchemaValidationError

TESTING_DIR = Path(__file__).parent
SRC_MODEL = TESTING_DIR.parent / "src" / "ome_types" / "model"
SRC = TESTING_DIR.parent / "src" / "ome_types"
SRC_MODEL = SRC / "model"


@pytest.fixture(scope="session")
Expand All @@ -18,15 +17,18 @@ def model(tmp_path_factory, request):
raise RuntimeError(
f"Please generate local {SRC_MODEL} before using --nogen"
)
sys.path.insert(0, str(SRC_MODEL.parent))
return importlib.import_module(SRC_MODEL.name)
from ome_autogen import convert_schema

target_dir = tmp_path_factory.mktemp("test_model")
xsd = TESTING_DIR / "ome-2016-06.xsd"
convert_schema(url=xsd, target_dir=target_dir)
sys.path.insert(0, str(target_dir.parent))
return importlib.import_module(target_dir.name)
sys.path.insert(0, str(SRC))
model = importlib.import_module(SRC_MODEL.name)
else:
from ome_autogen import convert_schema

target_dir = tmp_path_factory.mktemp("test_model")
xsd = SRC / "ome-2016-06.xsd"
convert_schema(url=xsd, target_dir=target_dir)
sys.path.insert(0, str(target_dir.parent))
model = importlib.import_module(target_dir.name)
sys.path.pop(0)
return model


SHOULD_FAIL = {
Expand Down

0 comments on commit bb37ec0

Please sign in to comment.