Skip to content

Commit

Permalink
Add explicit model mapping (#208)
Browse files Browse the repository at this point in the history
* Add explicit model mapping

* Bump package version
  • Loading branch information
pbylicki authored Mar 31, 2020
1 parent e9bd195 commit 81a95c2
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 74 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
aiofiles==0.4.0
Click==7.1.1
dataclasses==0.6
fastapi==0.52.0
fastapi==0.53.1
h11==0.8.1
httptools==0.1.1
jinja2==2.11.1
Expand Down
8 changes: 4 additions & 4 deletions rfhub2/api/endpoints/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def get_collection(
*, repository: CollectionRepository = Depends(get_collection_repository), id: int
):
collection: Optional[DBCollection] = repository.get(id)
return or_404(collection)
return or_404(collection).to_model()


@router.post("/", response_model=Collection, status_code=201)
Expand All @@ -65,8 +65,8 @@ def create_collection(
repository: CollectionRepository = Depends(get_collection_repository),
collection: CollectionUpdate,
):
db_collection: DBCollection = DBCollection(**collection.dict())
return repository.add(db_collection)
db_collection: DBCollection = repository.add(DBCollection.create(collection))
return db_collection.to_model()


@router.put("/{id}/", response_model=Collection)
Expand All @@ -81,7 +81,7 @@ def update_collection(
updated: DBCollection = repository.update(
db_collection, collection_update.dict(exclude_unset=True)
)
return updated
return updated.to_model()


@router.delete("/{id}/")
Expand Down
5 changes: 2 additions & 3 deletions rfhub2/api/endpoints/keyword_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ def get_statistics(
limit: int = 100,
ordering: List[OrderingItem] = Depends(get_ordering),
):
statistics: List[DBStatistics] = repository.get_many(
return repository.get_many(
filter_params=filter_params, skip=skip, limit=limit, ordering=ordering
)
return statistics


@router.post("/", status_code=201)
Expand All @@ -64,7 +63,7 @@ def create_statistics(
statistics: List[KeywordStatistics],
):
db_statistics: List[DBStatistics] = [
DBStatistics(**stat.dict()) for stat in statistics
DBStatistics.create(stat) for stat in statistics
]
try:
inserted: int = repository.add_many(db_statistics)
Expand Down
8 changes: 4 additions & 4 deletions rfhub2/api/endpoints/keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def get_keyword(
*, repository: KeywordRepository = Depends(get_keyword_repository), id: int
):
keyword: Optional[DBKeyword] = repository.get(id)
return or_404(keyword)
return or_404(keyword).to_model()


@router.post("/", response_model=Keyword, status_code=201)
Expand All @@ -104,8 +104,8 @@ def create_keyword(
)
if not collection:
raise HTTPException(status_code=400, detail="Collection does not exist")
db_keyword: DBKeyword = DBKeyword(**keyword.dict())
return repository.add(db_keyword)
db_keyword: DBKeyword = repository.add(DBKeyword.create(keyword))
return db_keyword.to_model()


@router.put("/{id}/", response_model=Keyword)
Expand All @@ -120,7 +120,7 @@ def update_keyword(
updated: DBKeyword = repository.update(
db_keyword, keyword_update.dict(exclude_unset=True)
)
return updated
return updated.to_model()


@router.delete("/{id}/")
Expand Down
34 changes: 34 additions & 0 deletions rfhub2/db/model/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from rfhub2.db.model.base_class import Base
from rfhub2.db.model.mixins import DocMixin
from rfhub2.db.repository.ordering import OrderingItem
from rfhub2 import model


class Collection(Base, DocMixin):
Expand Down Expand Up @@ -37,3 +38,36 @@ def __repr__(self): # pragma: no cover
@classmethod
def default_ordering(cls) -> List[OrderingItem]:
return [OrderingItem("name")]

@staticmethod
def create(data: model.CollectionUpdate) -> "Collection":
return Collection(
name=data.name,
type=data.type,
version=data.version,
scope=data.scope,
named_args=data.named_args,
path=data.path,
doc=data.doc,
doc_format=data.doc_format,
)

def to_model(self) -> model.Collection:
keywords = [kw.to_nested_model() for kw in self.keywords]
return model.Collection(
id=self.id,
name=self.name,
type=self.type,
version=self.version,
scope=self.scope,
named_args=self.named_args,
path=self.path,
doc=self.doc,
doc_format=self.doc_format,
html_doc=self.html_doc,
synopsis=self.synopsis,
keywords=keywords,
)

def to_nested_model(self) -> model.NestedCollection:
return model.NestedCollection(id=self.id, name=self.name)
34 changes: 34 additions & 0 deletions rfhub2/db/model/keyword.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from rfhub2.db.model.base_class import Base
from rfhub2.db.model.mixins import KeywordMixin
from rfhub2.db.repository.ordering import OrderingItem
from rfhub2 import model


class Keyword(Base, KeywordMixin):
Expand All @@ -24,3 +25,36 @@ def __repr__(self): # pragma: no cover
@classmethod
def default_ordering(cls) -> List[OrderingItem]:
return [OrderingItem("name")]

@staticmethod
def create(data: model.KeywordCreate) -> "Keyword":
return Keyword(
name=data.name,
doc=data.doc,
args=data.args,
collection_id=data.collection_id,
)

def to_model(self) -> model.Keyword:
collection = self.collection
return model.Keyword(
id=self.id,
name=self.name,
doc=self.doc,
args=self.args,
arg_string=self.arg_string,
html_doc=self.html_doc,
synopsis=self.synopsis,
collection=collection.to_nested_model(),
)

def to_nested_model(self) -> model.NestedKeyword:
return model.NestedKeyword(
id=self.id,
name=self.name,
doc=self.doc,
args=self.args,
arg_string=self.arg_string,
html_doc=self.html_doc,
synopsis=self.synopsis,
)
24 changes: 24 additions & 0 deletions rfhub2/db/model/keyword_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from rfhub2.db.model.base_class import Base
from rfhub2.db.repository.ordering import OrderingItem
from rfhub2 import model


class KeywordStatistics(Base):
Expand Down Expand Up @@ -32,3 +33,26 @@ def default_ordering(cls) -> List[OrderingItem]:
OrderingItem("keyword"),
OrderingItem("execution_time", False),
]

@staticmethod
def create(data: model.KeywordStatistics) -> "KeywordStatistics":
return KeywordStatistics(
collection=data.collection,
keyword=data.keyword,
execution_time=data.execution_time,
times_used=data.times_used,
total_elapsed=data.total_elapsed,
min_elapsed=data.min_elapsed,
max_elapsed=data.max_elapsed,
)

def to_model(self) -> model.KeywordStatistics:
return model.KeywordStatistics(
collection=self.collection,
keyword=self.keyword,
execution_time=self.execution_time,
times_used=self.times_used,
total_elapsed=self.total_elapsed,
min_elapsed=self.min_elapsed,
max_elapsed=self.max_elapsed,
)
39 changes: 29 additions & 10 deletions rfhub2/db/repository/collection_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sqlalchemy.sql.elements import BinaryExpression

from rfhub2.db.base import Collection, KeywordStatistics
from rfhub2.model import CollectionWithStats
from rfhub2.model import CollectionWithStats, Collection as ModelCollection
from rfhub2.db.repository.base_repository import IdEntityRepository
from rfhub2.db.repository.ordering import OrderingItem
from rfhub2.db.repository.query_utils import glob_to_sql
Expand Down Expand Up @@ -50,7 +50,23 @@ def filter_criteria(pattern: Optional[str], libtype: Optional[str]):

@staticmethod
def from_stats_row(row: Tuple[Collection, int]) -> CollectionWithStats:
return CollectionWithStats(**row[0].__dict__, **{"times_used": row[1]})
collection = row[0]
keywords = [kw.to_nested_model() for kw in collection.keywords]
return CollectionWithStats(
id=collection.id,
name=collection.name,
type=collection.type,
version=collection.version,
scope=collection.scope,
named_args=collection.named_args,
path=collection.path,
doc=collection.doc,
doc_format=collection.doc_format,
html_doc=collection.html_doc,
synopsis=collection.synopsis,
keywords=keywords,
times_used=row[1],
)

def get_all(
self,
Expand All @@ -60,14 +76,17 @@ def get_all(
skip: int = 0,
limit: int = 100,
ordering: List[OrderingItem] = None,
) -> List[Collection]:
return (
self._items.filter(*self.filter_criteria(pattern, libtype))
.order_by(*Collection.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
) -> List[ModelCollection]:
return [
collection.to_model()
for collection in (
self._items.filter(*self.filter_criteria(pattern, libtype))
.order_by(*Collection.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
]

def get_all_with_stats(
self,
Expand Down
41 changes: 28 additions & 13 deletions rfhub2/db/repository/keyword_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sqlalchemy.sql.elements import BinaryExpression

from rfhub2.db.base import Collection, Keyword, KeywordStatistics
from rfhub2.model import KeywordWithStats
from rfhub2.model import KeywordWithStats, Keyword as ModelKeyword
from rfhub2.db.repository.base_repository import IdEntityRepository
from rfhub2.db.repository.ordering import OrderingItem
from rfhub2.db.repository.query_utils import glob_to_sql
Expand Down Expand Up @@ -74,8 +74,18 @@ def filter_criteria(

@staticmethod
def from_stats_row(row: Tuple[Keyword, int, float]) -> KeywordWithStats:
keyword = row[0]
return KeywordWithStats(
**row[0].__dict__, **{"times_used": row[1], "avg_elapsed": row[2]}
id=keyword.id,
name=keyword.name,
doc=keyword.doc,
args=keyword.args,
arg_string=keyword.arg_string,
html_doc=keyword.html_doc,
synopsis=keyword.synopsis,
collection=keyword.collection.to_nested_model(),
times_used=row[1],
avg_elapsed=row[2],
)

def get_all(
Expand All @@ -88,18 +98,23 @@ def get_all(
skip: int = 0,
limit: int = 100,
ordering: List[OrderingItem] = None,
) -> List[Keyword]:
return (
self.session.query(Keyword)
.join(Keyword.collection)
.filter(
*self.filter_criteria(pattern, collection_name, collection_id, use_doc)
) -> List[ModelKeyword]:
return [
keyword.to_model()
for keyword in (
self.session.query(Keyword)
.join(Keyword.collection)
.filter(
*self.filter_criteria(
pattern, collection_name, collection_id, use_doc
)
)
.order_by(*Keyword.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
.order_by(*Keyword.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
]

def get_all_with_stats(
self,
Expand Down
17 changes: 10 additions & 7 deletions rfhub2/db/repository/keyword_statistics_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,16 @@ def get_many(
limit: int = 100,
ordering: List[OrderingItem] = None,
) -> List[KeywordStatistics]:
return (
self._items.filter(*self.filter_criteria(filter_params))
.order_by(*KeywordStatistics.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
return [
stat.to_model()
for stat in (
self._items.filter(*self.filter_criteria(filter_params))
.order_by(*KeywordStatistics.ordering_criteria(ordering))
.offset(skip)
.limit(limit)
.all()
)
]

def add_many(self, items: List[KeywordStatistics]) -> int:
count: int = len(items)
Expand Down
7 changes: 2 additions & 5 deletions rfhub2/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
from typing import List, Optional


from rfhub2.db.model.mixins import DocMixin, KeywordMixin


class VersionInfo(BaseModel):
title: str
version: str
Expand Down Expand Up @@ -60,15 +57,15 @@ class Collection(NestedCollection, CollectionUpdate):
html_doc: Optional[str]


class CollectionWithStats(Collection, DocMixin):
class CollectionWithStats(Collection):
times_used: Optional[int]


class Keyword(NestedKeyword):
collection: NestedCollection


class KeywordWithStats(Keyword, KeywordMixin):
class KeywordWithStats(Keyword):
times_used: Optional[int]
avg_elapsed: Optional[float]

Expand Down
2 changes: 1 addition & 1 deletion rfhub2/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = "0.14"
version = "0.15"
Loading

0 comments on commit 81a95c2

Please sign in to comment.