Skip to content

Commit 1b0103d

Browse files
authored
Merge pull request #60 from OpenSemanticLab/some-work-on-core
enh: work on osw.core.OSW.query_instance and .load_entity
2 parents 13c7af3 + f7c3c1a commit 1b0103d

File tree

1 file changed

+74
-63
lines changed

1 file changed

+74
-63
lines changed

src/osw/core.py

Lines changed: 74 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
import re
88
import sys
99
from enum import Enum
10-
from typing import List, Optional, Union
10+
from typing import Dict, List, Optional, Union
1111
from uuid import UUID
1212

1313
from jsonpath_ng.ext import parse
1414
from pydantic import BaseModel, Field, create_model
15-
from pydantic.main import ModelMetaclass
15+
from pydantic.main import ModelMetaclass, PrivateAttr
1616

1717
import osw.model.entity as model
1818
from osw.model.static import OswBaseModel
@@ -490,29 +490,27 @@ def _fetch_schema(self, fetchSchemaParam: _FetchSchemaParam = None) -> None:
490490
self.site.disable_cache() # restore original state
491491

492492
class LoadEntityParam(BaseModel):
493-
"""Param for load_entity()
494-
495-
Attributes
496-
----------
497-
titles:
498-
one or multiple titles (wiki page name) of entities
499-
"""
493+
"""Param for load_entity()"""
500494

501495
titles: Union[str, List[str]]
502-
"""the pages titles to load"""
496+
"""The pages titles to load - one or multiple titles (wiki page name) of
497+
entities"""
503498
autofetch_schema: Optional[bool] = True
504-
"""if true, load the corresponding schemas / categories ad-hoc if not already present"""
499+
"""If true, load the corresponding schemas /
500+
categories ad-hoc if not already present"""
501+
disable_cache: bool = False
502+
"""If true, disable the cache for the loading process"""
505503

506-
class LoadEntityResult(BaseModel):
507-
"""Result of load_entity()
504+
def __init__(self, **data):
505+
super().__init__(**data)
506+
if not isinstance(self.titles, list):
507+
self.titles = [self.titles]
508508

509-
Attributes
510-
----------
511-
entities:
512-
the dataclass instance(s)
513-
"""
509+
class LoadEntityResult(BaseModel):
510+
"""Result of load_entity()"""
514511

515512
entities: Union[model.Entity, List[model.Entity]]
513+
"""The dataclass instance(s)"""
516514

517515
def load_entity(
518516
self, entity_title: Union[str, List[str], LoadEntityParam]
@@ -533,23 +531,23 @@ def load_entity(
533531
a list of dataclass instances if a list of titles is given
534532
a LoadEntityResult instance if a LoadEntityParam is given
535533
"""
536-
537-
titles = []
538-
if isinstance(entity_title, str): # single title
539-
titles = [entity_title]
540-
if isinstance(entity_title, list): # list of titles
541-
titles = entity_title
542-
load_param = OSW.LoadEntityParam(titles=titles)
543-
if isinstance(entity_title, OSW.LoadEntityParam): # LoadEntityParam
544-
load_param = entity_title
545-
titles = entity_title.titles
546-
entities = []
534+
if isinstance(entity_title, str):
535+
param = OSW.LoadEntityParam(titles=[entity_title])
536+
elif isinstance(entity_title, list):
537+
param = OSW.LoadEntityParam(titles=entity_title)
538+
else:
539+
param = entity_title
547540

548541
# store original cache state
549542
cache_state = self.site.get_cache_enabled()
550-
# enable cache to speed up loading
551-
self.site.enable_cache()
552-
pages = self.site.get_page(WtSite.GetPageParam(titles=titles)).pages
543+
if param.disable_cache:
544+
self.site.disable_cache()
545+
if not cache_state and param.disable_cache:
546+
# enable cache to speed up loading
547+
self.site.enable_cache()
548+
549+
entities = []
550+
pages = self.site.get_page(WtSite.GetPageParam(titles=param.titles)).pages
553551
for page in pages:
554552
entity = None
555553
schemas = []
@@ -566,7 +564,7 @@ def load_entity(
566564
# generate model if not already exists
567565
cls = schema["title"]
568566
if not hasattr(model, cls):
569-
if load_param.autofetch_schema:
567+
if param.autofetch_schema:
570568
self.fetch_schema(
571569
OSW.FetchSchemaParam(
572570
schema_title=category, mode="append"
@@ -585,7 +583,7 @@ def load_entity(
585583

586584
elif len(schemas) == 1:
587585
cls = schemas[0]["title"]
588-
entity = eval(f"model.{cls}(**jsondata)")
586+
entity: model.Entity = eval(f"model.{cls}(**jsondata)")
589587

590588
else:
591589
bases = []
@@ -608,8 +606,11 @@ def load_entity(
608606

609607
entities.append(entity)
610608
# restore original cache state
611-
if not cache_state:
609+
if cache_state:
610+
self.site.enable_cache()
611+
else:
612612
self.site.disable_cache()
613+
613614
if isinstance(entity_title, str): # single title
614615
if len(entities) >= 1:
615616
return entities[0]
@@ -740,10 +741,7 @@ def delete_entity(
740741
):
741742
"""Deletes the given entity/entities from the OSW instance."""
742743
if not isinstance(entity, OSW.DeleteEntityParam):
743-
if isinstance(entity, list):
744-
entity = OSW.DeleteEntityParam(entities=entity)
745-
else:
746-
entity = OSW.DeleteEntityParam(entities=[entity])
744+
entity = OSW.DeleteEntityParam(entities=entity)
747745
if comment is not None:
748746
entity.comment = comment
749747

@@ -797,6 +795,32 @@ class QueryInstancesParam(OswBaseModel):
797795
parallel: Optional[bool] = None
798796
debug: Optional[bool] = False
799797
limit: Optional[int] = 1000
798+
_category_string_parts: List[Dict[str, str]] = PrivateAttr()
799+
_titles: List[str] = PrivateAttr()
800+
801+
@staticmethod
802+
def get_full_page_name_parts(
803+
category_: Union[str, OswBaseModel]
804+
) -> Dict[str, str]:
805+
error_msg = (
806+
f"Category must be a string or a dataclass instance with "
807+
f"a 'type' attribute. This error occurred on '{str(category_)}'"
808+
)
809+
if isinstance(category_, str):
810+
string_to_split = category_
811+
elif isinstance(category_, OswBaseModel):
812+
type_ = getattr(category_, "type", None)
813+
if type_ is None:
814+
raise TypeError(error_msg)
815+
string_to_split = type_[0]
816+
else:
817+
raise TypeError(error_msg)
818+
if "Category:" not in string_to_split:
819+
raise TypeError(error_msg)
820+
return {
821+
"namespace": string_to_split.split(":")[0],
822+
"title": string_to_split.split(":")[-1],
823+
}
800824

801825
def __init__(self, **data):
802826
super().__init__(**data)
@@ -806,36 +830,23 @@ def __init__(self, **data):
806830
self.parallel = True
807831
if self.parallel is None:
808832
self.parallel = False
833+
self._category_string_parts = [
834+
OSW.QueryInstancesParam.get_full_page_name_parts(cat)
835+
for cat in self.categories
836+
]
837+
self._titles = [parts["title"] for parts in self._category_string_parts]
809838

810839
def query_instances(
811840
self, category: Union[str, OswBaseModel, OSW.QueryInstancesParam]
812841
) -> List[str]:
813-
def get_page_title(category_: Union[str, OswBaseModel]) -> str:
814-
error_msg = (
815-
"Category must be a string, a dataclass instance with "
816-
"a 'type' attribute or osw.wiki_tools.SearchParam."
817-
)
818-
if isinstance(category_, str):
819-
return category_.split(":")[-1] # page title w/o namespace
820-
elif isinstance(category_, OswBaseModel):
821-
type_ = getattr(category_, "type", None)
822-
if type_:
823-
full_page_title = type_[0]
824-
return full_page_title.split(":")[-1] # page title w/o namespace
825-
else:
826-
raise TypeError(error_msg)
827-
else:
828-
raise TypeError(error_msg)
829-
830-
if isinstance(category, OSW.QueryInstancesParam):
831-
page_titles = [get_page_title(cat) for cat in category.categories]
832-
else:
833-
page_titles = [get_page_title(category)]
834-
category = OSW.QueryInstancesParam(categories=page_titles)
835-
842+
if not isinstance(category, OSW.QueryInstancesParam):
843+
category = OSW.QueryInstancesParam(categories=category)
844+
page_titles = category._titles
836845
search_param = SearchParam(
837846
query=[f"[[HasType::Category:{page_title}]]" for page_title in page_titles],
838-
**category.dict(exclude={"categories"}),
847+
**category.dict(
848+
exclude={"categories", "_category_string_parts", "_titles"}
849+
),
839850
)
840851
full_page_titles = self.site.semantic_search(search_param)
841852
return full_page_titles

0 commit comments

Comments
 (0)