shape: generic asDict and toObject methods

This commit is contained in:
Helmut Merz 2026-11-05 09:32:42 +01:00
parent f7ba9c3881
commit e0a53dce68
5 changed files with 23 additions and 16 deletions

View file

@ -7,7 +7,8 @@ name = "py-scopes"
version = "3.0.1" version = "3.0.1"
description = "Implementation of the unknown 'scopes' paradigm in Python" description = "Implementation of the unknown 'scopes' paradigm in Python"
readme = "README.md" readme = "README.md"
license = {text = "MIT"} license = "MIT"
license-files = ["LICENSE"]
keywords = ["scopes"] keywords = ["scopes"]
authors = [{name = "Helmut Merz", email = "helmutm@cy55.de"}] authors = [{name = "Helmut Merz", email = "helmutm@cy55.de"}]
@ -19,7 +20,7 @@ postgres = [
"transaction", "transaction",
"zope.sqlalchemy", "zope.sqlalchemy",
] ]
app = [ # TODO: rename to zope zope = [
"python-dotenv", "python-dotenv",
"waitress", "waitress",
"zope.authentication", "zope.authentication",
@ -28,8 +29,8 @@ app = [ # TODO: rename to zope
"zope.traversing", "zope.traversing",
] ]
api = ["fastapi[standard]"] api = ["fastapi[standard]"]
auth = ["pyjwt[crypto]", "cryptography", "requests"] auth = ["authlib", "pyjwt[crypto]", "cryptography", "requests"]
test = ["zope.testrunner"] # TODO: rename to zopetest, or merge with apitest zopetest = ["zope.testrunner"]
apitest = ["pytest", "httpx2"] apitest = ["pytest", "httpx2"]
[tool.setuptools] [tool.setuptools]

View file

@ -23,6 +23,6 @@ router = APIRouter()
@router.get('/users', response_model=list[User]) @router.get('/users', response_model=list[User])
async def get_users(storage: deps.Storage): async def get_users(storage: deps.Storage):
users = storage.create(st_user.Users) users = storage.create(st_user.Users)
result = [tr.toModel(User) for tr in users.query()] result = [tr.toObject(User) for tr in users.query()]
return result return result

View file

@ -47,7 +47,11 @@ class Record:
def __repr__(self): def __repr__(self):
return f'<{self.__class__.__name__}: {self.headValues}, {self.data}>' return f'<{self.__class__.__name__}: {self.headValues}, {self.data}>'
def asDict(self): def asDict(self, flatten=False):
if flatten:
return self.head | self.data
return dict(head=self.head, data=self.data) return dict(head=self.head, data=self.data)
def toObject(self, cls):
return cls(**self.asDict(flatten=True))

View file

@ -25,16 +25,12 @@ class Record(shape.Record):
self.trackId = trackId self.trackId = trackId
self.container = container self.container = container
def asDict(self): def asDict(self, flatten=False):
return dict(uid=self.uid, head=self.head, data=self.data, ts = str(self.timeStamp)[:19]
timeStamp=str(self.timeStamp)[:19]) base = dict(uid=self.uid, timeStamp=ts)
if flatten:
def toModel(self, cls): return base | self.head | self.data
data = dict(uid=self.uid) return base | super().asDict()
data.update(self.head)
for k, v in self.data.items():
data[k] = v
return cls(**data)
@property @property
def uid(self): def uid(self):

View file

@ -57,6 +57,12 @@ def test_message():
assert msg.head['class'] is k.person assert msg.head['class'] is k.person
assert msg.addr() == (k.test, k.person, '4711') assert msg.addr() == (k.test, k.person, '4711')
assert msg.categ() == (k.test, k.person) assert msg.categ() == (k.test, k.person)
assert msg.asDict() == {'head': {'domain': k.test, 'action': k.data,
'class': k.person, 'item': '4711'},
'data': {'firstName': 'Bob', 'lastName': 'Miller'}}
assert msg.asDict(flatten=True) == {
'domain': k.test, 'action': k.data, 'class': k.person, 'item': '4711',
'firstName': 'Bob', 'lastName': 'Miller'}
@pytest.fixture @pytest.fixture