espark-core 0.5.3__tar.gz → 0.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of espark-core might be problematic. Click here for more details.
- {espark_core-0.5.3/espark_core.egg-info → espark_core-0.5.4}/PKG-INFO +4 -4
- {espark_core-0.5.3 → espark_core-0.5.4/espark_core.egg-info}/PKG-INFO +4 -4
- {espark_core-0.5.3 → espark_core-0.5.4}/espark_core.egg-info/requires.txt +2 -2
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/base_repository.py +3 -3
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/telemetry_repository.py +1 -1
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/base_router.py +6 -6
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/device_router.py +2 -2
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/telemetry_router.py +2 -2
- {espark_core-0.5.3 → espark_core-0.5.4}/requirements.txt +2 -2
- {espark_core-0.5.3 → espark_core-0.5.4}/setup.py +2 -2
- {espark_core-0.5.3 → espark_core-0.5.4}/LICENSE +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/MANIFEST.in +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/README.md +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/espark_core.egg-info/SOURCES.txt +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/espark_core.egg-info/dependency_links.txt +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/espark_core.egg-info/top_level.txt +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/constants.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/database.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/device.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/notification.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/outbox.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/telemetry.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/trigger.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/models/version.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/device_repository.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/notification_repository.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/outbox_repository.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/trigger_repository.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/version_repository.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/notifications/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/notifications/notifier.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/notifications/slack_notifier.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/notification_router.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/trigger_router.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/routers/version_router.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/schedules/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/schedules/outbox.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/schedules/scheduler.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/services/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/services/mqtt.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/utils/__init__.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/utils/logging.py +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/requirements.dev.txt +0 -0
- {espark_core-0.5.3 → espark_core-0.5.4}/setup.cfg +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: espark-core
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: The core module of the Espark ESP32-based IoT device management framework.
|
|
5
5
|
License: MIT
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: aiomqtt>=2.4.0
|
|
10
10
|
Requires-Dist: apscheduler>=3.11.2
|
|
11
|
-
Requires-Dist: fastapi>=0.
|
|
11
|
+
Requires-Dist: fastapi>=0.128.0
|
|
12
12
|
Requires-Dist: packaging>=25.0
|
|
13
13
|
Requires-Dist: slack-sdk==3.39.0
|
|
14
14
|
Requires-Dist: sqlalchemy>=2.0.45
|
|
15
|
-
Requires-Dist: sqlmodel>=0.0.
|
|
15
|
+
Requires-Dist: sqlmodel>=0.0.31
|
|
16
16
|
Requires-Dist: uvicorn[standard]>=0.40.0
|
|
17
17
|
Provides-Extra: dev
|
|
18
18
|
Requires-Dist: aiosqlite==0.22.1; extra == "dev"
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: espark-core
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: The core module of the Espark ESP32-based IoT device management framework.
|
|
5
5
|
License: MIT
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: aiomqtt>=2.4.0
|
|
10
10
|
Requires-Dist: apscheduler>=3.11.2
|
|
11
|
-
Requires-Dist: fastapi>=0.
|
|
11
|
+
Requires-Dist: fastapi>=0.128.0
|
|
12
12
|
Requires-Dist: packaging>=25.0
|
|
13
13
|
Requires-Dist: slack-sdk==3.39.0
|
|
14
14
|
Requires-Dist: sqlalchemy>=2.0.45
|
|
15
|
-
Requires-Dist: sqlmodel>=0.0.
|
|
15
|
+
Requires-Dist: sqlmodel>=0.0.31
|
|
16
16
|
Requires-Dist: uvicorn[standard]>=0.40.0
|
|
17
17
|
Provides-Extra: dev
|
|
18
18
|
Requires-Dist: aiosqlite==0.22.1; extra == "dev"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Generic, Optional, Sequence, Type, TypeVar
|
|
2
2
|
|
|
3
|
-
from sqlalchemy import func,
|
|
3
|
+
from sqlalchemy import ColumnElement, func, text
|
|
4
4
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
5
5
|
from sqlmodel import select, SQLModel
|
|
6
6
|
|
|
@@ -41,14 +41,14 @@ class AsyncRepository(Generic[T]):
|
|
|
41
41
|
|
|
42
42
|
return (await session.execute(query)).scalars().first()
|
|
43
43
|
|
|
44
|
-
async def list(self, session: AsyncSession, *conditions: ColumnElement[bool], offset: Optional[int] = None, order_by=None, limit: Optional[int] = None) -> Sequence[T]:
|
|
44
|
+
async def list(self, session: AsyncSession, *conditions: ColumnElement[bool], offset: Optional[int] = None, order_by: ColumnElement | str = None, limit: Optional[int] = None) -> Sequence[T]:
|
|
45
45
|
query = select(self.model)
|
|
46
46
|
|
|
47
47
|
if conditions:
|
|
48
48
|
query = query.where(*conditions)
|
|
49
49
|
|
|
50
50
|
if order_by is not None:
|
|
51
|
-
query = query.order_by(order_by)
|
|
51
|
+
query = query.order_by(text(order_by) if isinstance(order_by, str) else order_by)
|
|
52
52
|
|
|
53
53
|
if offset is not None:
|
|
54
54
|
query = query.offset(offset)
|
{espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/telemetry_repository.py
RENAMED
|
@@ -17,7 +17,7 @@ class TelemetryRepository(AsyncRepository[Telemetry]):
|
|
|
17
17
|
results = await self.list(session, and_(Telemetry.device_id == device_id, Telemetry.data_type == data_type), order_by=Telemetry.timestamp.desc(), limit=1)
|
|
18
18
|
return results[0] if results else None
|
|
19
19
|
|
|
20
|
-
async def list(self, session: AsyncSession, *conditions: ColumnElement[bool], offset: Optional[int] = None, order_by=None, limit: Optional[int] = None) -> Sequence[Telemetry]:
|
|
20
|
+
async def list(self, session: AsyncSession, *conditions: ColumnElement[bool], offset: Optional[int] = None, order_by: ColumnElement | str = None, limit: Optional[int] = None) -> Sequence[Telemetry]:
|
|
21
21
|
if order_by is None:
|
|
22
22
|
# pylint: disable=no-member
|
|
23
23
|
order_by = Telemetry.timestamp.desc()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Generic, List, Sequence, Type, TypeVar
|
|
2
2
|
|
|
3
|
-
from fastapi import APIRouter, Body, Depends, HTTPException, Query, status, Response
|
|
3
|
+
from fastapi import APIRouter, Body, Depends, HTTPException, Query, status, Response, Path
|
|
4
4
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
5
5
|
from sqlmodel import SQLModel
|
|
6
6
|
|
|
@@ -57,7 +57,7 @@ class BaseRouter(Generic[T]):
|
|
|
57
57
|
return result
|
|
58
58
|
|
|
59
59
|
@self.router.delete('/{id}', status_code=status.HTTP_204_NO_CONTENT)
|
|
60
|
-
async def delete(id: str, session: AsyncSession = Depends(BaseRouter._get_session)) -> None:
|
|
60
|
+
async def delete(id: str = Path(..., min_length=1), session: AsyncSession = Depends(BaseRouter._get_session)) -> None:
|
|
61
61
|
entity = await self.repo.get(session, self.model.id == id)
|
|
62
62
|
if not entity:
|
|
63
63
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
|
@@ -67,7 +67,7 @@ class BaseRouter(Generic[T]):
|
|
|
67
67
|
await self._after_delete(entity, session)
|
|
68
68
|
|
|
69
69
|
@self.router.get('/{id}', response_model=self.model)
|
|
70
|
-
async def get(id: str, session: AsyncSession = Depends(BaseRouter._get_session)) -> T:
|
|
70
|
+
async def get(id: str = Path(..., min_length=1), session: AsyncSession = Depends(BaseRouter._get_session)) -> T:
|
|
71
71
|
entity = await self.repo.get(session, self.model.id == id)
|
|
72
72
|
if not entity:
|
|
73
73
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
|
@@ -75,13 +75,13 @@ class BaseRouter(Generic[T]):
|
|
|
75
75
|
return entity
|
|
76
76
|
|
|
77
77
|
@self.router.get('/', response_model=List[self.model])
|
|
78
|
-
async def list(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), offset: int = Query(
|
|
78
|
+
async def list(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), order_by: str = Query(None), offset: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=100)) -> Sequence[T]:
|
|
79
79
|
response.headers['X-Total-Count'] = str(await self.repo.count(session))
|
|
80
80
|
|
|
81
|
-
return await self.repo.list(session, offset=offset, limit=limit)
|
|
81
|
+
return await self.repo.list(session, order_by=order_by, offset=offset, limit=limit)
|
|
82
82
|
|
|
83
83
|
@self.router.put('/{id}', response_model=self.model)
|
|
84
|
-
async def update(id: str, data: dict = Body(...), session: AsyncSession = Depends(BaseRouter._get_session)) -> T:
|
|
84
|
+
async def update(id: str = Path(..., min_length=1), data: dict = Body(...), session: AsyncSession = Depends(BaseRouter._get_session)) -> T:
|
|
85
85
|
entity = await self.repo.get(session, self.model.id == id)
|
|
86
86
|
if not entity:
|
|
87
87
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
|
@@ -31,10 +31,10 @@ class DeviceRouter(BaseRouter):
|
|
|
31
31
|
|
|
32
32
|
def _setup_routes(self) -> None:
|
|
33
33
|
@self.router.get('/all')
|
|
34
|
-
async def list_all(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), offset: int = Query(
|
|
34
|
+
async def list_all(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), order_by: str = Query(None), offset: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=100)):
|
|
35
35
|
response.headers['X-Total-Count'] = str(await self.repo.count(session))
|
|
36
36
|
|
|
37
|
-
devices = await self.repo.list(session, offset=offset, limit=limit)
|
|
37
|
+
devices = await self.repo.list(session, order_by=order_by, offset=offset, limit=limit)
|
|
38
38
|
devices_with_telemetry = []
|
|
39
39
|
telemetry_repo = TelemetryRepository()
|
|
40
40
|
|
|
@@ -18,7 +18,7 @@ class TelemetryRouter(BaseRouter):
|
|
|
18
18
|
|
|
19
19
|
def _setup_routes(self) -> None:
|
|
20
20
|
@self.router.get('/history', response_model=Sequence[Telemetry])
|
|
21
|
-
async def list_history(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), device_id:
|
|
21
|
+
async def list_history(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), device_id: str = Query(..., min_length=1), offset: int = Query(0, min=0)) -> Sequence[Telemetry]:
|
|
22
22
|
from_date = datetime.now(timezone.utc) - timedelta(seconds=offset)
|
|
23
23
|
results = await self.repo.list(session, and_(Telemetry.device_id == device_id, Telemetry.timestamp >= from_date))
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ class TelemetryRouter(BaseRouter):
|
|
|
27
27
|
return results
|
|
28
28
|
|
|
29
29
|
@self.router.get('/recent', response_model=Sequence[Telemetry])
|
|
30
|
-
async def list_recent(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), offset: int = Query(
|
|
30
|
+
async def list_recent(response: Response, session: AsyncSession = Depends(BaseRouter._get_session), offset: int = Query(0, min=0)) -> Sequence[Telemetry]:
|
|
31
31
|
from_date = datetime.now(timezone.utc) - timedelta(seconds=offset)
|
|
32
32
|
device_repo = DeviceRepository()
|
|
33
33
|
# pylint: disable=no-member
|
|
@@ -10,7 +10,7 @@ extra_requirements = (root / 'requirements.dev.txt').read_text().splitlines
|
|
|
10
10
|
|
|
11
11
|
setup(
|
|
12
12
|
name='espark-core',
|
|
13
|
-
version='0.5.
|
|
13
|
+
version='0.5.4',
|
|
14
14
|
description='The core module of the Espark ESP32-based IoT device management framework.',
|
|
15
15
|
long_description=(root / 'README.md').read_text(),
|
|
16
16
|
long_description_content_type='text/markdown',
|
|
@@ -18,7 +18,7 @@ setup(
|
|
|
18
18
|
license_files=[
|
|
19
19
|
'LICENSE',
|
|
20
20
|
],
|
|
21
|
-
python_requires='>=3.
|
|
21
|
+
python_requires='>=3.10',
|
|
22
22
|
packages=find_packages(where='.'),
|
|
23
23
|
package_dir={
|
|
24
24
|
'' : '.',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{espark_core-0.5.3 → espark_core-0.5.4}/esparkcore/data/repositories/notification_repository.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|