added base protocol types that every app in this monorepo import it
This commit is contained in:
@@ -47,6 +47,7 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args: [--config-file, pyproject.toml]
|
args: [--config-file, pyproject.toml]
|
||||||
|
exclude: ^src/protocol/
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- "pydantic>=2.13.4"
|
- "pydantic>=2.13.4"
|
||||||
- "pydantic-settings>=2.15.0"
|
- "pydantic-settings>=2.15.0"
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ strict = true
|
|||||||
# Pydantic plugin for correct model field inference
|
# Pydantic plugin for correct model field inference
|
||||||
plugins = ["pydantic.mypy"]
|
plugins = ["pydantic.mypy"]
|
||||||
|
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = "protocol.*"
|
||||||
|
ignore_errors = true
|
||||||
|
|
||||||
[tool.pydantic-mypy]
|
[tool.pydantic-mypy]
|
||||||
init_forbid_extra = true
|
init_forbid_extra = true
|
||||||
warn_required_dynamic_aliases = true
|
warn_required_dynamic_aliases = true
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "https://sadtech.ir/schemas/operation.schema.json",
|
"$id": "https://sadtech.ir/schemas/operation.schema.json",
|
||||||
"title": "Operation",
|
"title": "Operation",
|
||||||
"description": "An operation is a single action that can be performed on the database by sync protocol.",
|
"description": "An operation is a single action performed on the database.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -40,4 +40,4 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "https://sadtech.ir/schemas/snapshot.schema.json",
|
"$id": "https://sadtech.ir/schemas/snapshot.schema.json",
|
||||||
"title": "Snapshot",
|
"title": "Snapshot",
|
||||||
"description": "A snapshot is a complete copy of the database on the server. It is sent to the device when the device's local database is out of sync with the server's database.",
|
"description": "A snapshot is a complete copy of the database on the server.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
"format": "int64"
|
"format": "int64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "https://sadtech.ir/schemas/sync-request.schema.json",
|
"$id": "https://sadtech.ir/schemas/sync-request.schema.json",
|
||||||
"title": "SyncRequest",
|
"title": "SyncRequest",
|
||||||
"description": "A sync request is a request sent by a device to the server to synchronize its local database with the server's database.",
|
"description": "A sync request is a request sent by a device to the server.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"device_id": {
|
"device_id": {
|
||||||
@@ -26,4 +26,4 @@
|
|||||||
"cursor",
|
"cursor",
|
||||||
"operations"
|
"operations"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "https://sadtech.ir/schemas/sync-response.schema.json",
|
"$id": "https://sadtech.ir/schemas/sync-response.schema.json",
|
||||||
"title": "SyncResponse",
|
"title": "SyncResponse",
|
||||||
"description": "A sync response is a response sent by the server to a device to synchronize its local database with the server's database.",
|
"description": "A sync response is a response sent by the server.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"cursor": {
|
"cursor": {
|
||||||
"description": "The cursor is a string that represents the last known state of the database on the device. It is used to determine which operations need to be sent to the device.",
|
"description": "The cursor is an integer that represents the last known state of the database.",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"operations": {
|
"operations": {
|
||||||
@@ -25,4 +25,4 @@
|
|||||||
"cursor",
|
"cursor",
|
||||||
"operations"
|
"operations"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from server.types.sync_request import SyncRequest
|
from protocol.sync_request import SyncRequest
|
||||||
from server.types.sync_response import SyncResponse
|
from protocol.sync_response import SyncResponse
|
||||||
|
|
||||||
|
|
||||||
async def run_client() -> None:
|
async def run_client() -> None:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from engine.adapter import InMemoryAdapter, StorageAdapter
|
from engine.adapter import InMemoryAdapter, StorageAdapter
|
||||||
from engine.types.operation import Operation
|
from protocol.operation import Operation
|
||||||
|
|
||||||
|
|
||||||
class SyncEngine:
|
class SyncEngine:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import threading
|
import threading
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
|
|
||||||
from engine.types.operation import Operation
|
from protocol.operation import Operation
|
||||||
|
|
||||||
|
|
||||||
class StorageAdapter(Protocol):
|
class StorageAdapter(Protocol):
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
|
|
||||||
class {{ model.name }}(BaseModel):
|
class {{ model.name }}(BaseModel):
|
||||||
"""{{ model.description }}"""
|
"""
|
||||||
|
{{ model.description }}
|
||||||
|
"""
|
||||||
|
|
||||||
{% for field in model.fields %}
|
{% for field in model.fields %}
|
||||||
{{ field.name }}: {{ field.type }}
|
{{ field.name }}: {{ field.type }}
|
||||||
@@ -16,5 +18,5 @@ class {{ model.name }}(BaseModel):
|
|||||||
return self.model_dump_json().encode("utf-8")
|
return self.model_dump_json().encode("utf-8")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def decode(cls, data: bytes):
|
def decode(cls, data: bytes) -> "{{ model.name }}":
|
||||||
return cls.model_validate_json(data)
|
return cls.model_validate_json(data)
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
|
|
||||||
class Operation(BaseModel):
|
class Operation(BaseModel):
|
||||||
"""A single action that can be performed on the database by sync protocol."""
|
"""
|
||||||
|
An operation is a single action performed on the database.
|
||||||
|
"""
|
||||||
|
|
||||||
id: str | None = None
|
id: str | None = None
|
||||||
type: str | None = None
|
type: str | None = None
|
||||||
device_id: str | None = None
|
device_id: str | None = None
|
||||||
timestamp: str | None = None
|
timestamp: str | None = None
|
||||||
payload: dict[str, object] | None = None
|
payload: dict | None = None
|
||||||
entity_type: str | None = None
|
entity_type: str | None = None
|
||||||
entity_id: str | None = None
|
entity_id: str | None = None
|
||||||
|
|
||||||
@@ -2,11 +2,13 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
|
|
||||||
class Snapshot(BaseModel):
|
class Snapshot(BaseModel):
|
||||||
"""A complete copy of the server's database, sent when a device is out of sync."""
|
"""
|
||||||
|
A snapshot is a complete copy of the database on the server.
|
||||||
|
"""
|
||||||
|
|
||||||
id: str | None = None
|
id: str | None = None
|
||||||
cursor: int | None = None
|
cursor: int | None = None
|
||||||
data: dict[str, object] | None = None
|
data: dict | None = None
|
||||||
timestamp: int | None = None
|
timestamp: int | None = None
|
||||||
|
|
||||||
def encode(self) -> bytes:
|
def encode(self) -> bytes:
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from engine.types.operation import Operation
|
from .operation import Operation
|
||||||
|
|
||||||
|
|
||||||
class SyncRequest(BaseModel):
|
class SyncRequest(BaseModel):
|
||||||
"""A sync request sent by a device to synchronize with the server's database."""
|
"""
|
||||||
|
A sync request is a request sent by a device to the server.
|
||||||
|
"""
|
||||||
|
|
||||||
device_id: str
|
device_id: str
|
||||||
cursor: int
|
cursor: int
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from engine.types.operation import Operation
|
from .operation import Operation
|
||||||
from engine.types.snapshot import Snapshot
|
from .snapshot import Snapshot
|
||||||
|
|
||||||
|
|
||||||
class SyncResponse(BaseModel):
|
class SyncResponse(BaseModel):
|
||||||
"""A sync response sent by the server to synchronize a device's local database."""
|
"""
|
||||||
|
A sync response is a response sent by the server.
|
||||||
|
"""
|
||||||
|
|
||||||
cursor: int
|
cursor: int
|
||||||
operations: list[Operation]
|
operations: list[Operation]
|
||||||
+2
-3
@@ -2,9 +2,8 @@ import asyncio
|
|||||||
|
|
||||||
from engine import SyncEngine
|
from engine import SyncEngine
|
||||||
from engine.adapter import InMemoryAdapter
|
from engine.adapter import InMemoryAdapter
|
||||||
|
from protocol.sync_request import SyncRequest
|
||||||
from .types.sync_request import SyncRequest
|
from protocol.sync_response import SyncResponse
|
||||||
from .types.sync_response import SyncResponse
|
|
||||||
|
|
||||||
# One shared engine (and its in-memory log) for the lifetime of the server.
|
# One shared engine (and its in-memory log) for the lifetime of the server.
|
||||||
# Swap InMemoryAdapter for any StorageAdapter implementation to persist ops.
|
# Swap InMemoryAdapter for any StorageAdapter implementation to persist ops.
|
||||||
|
|||||||
Reference in New Issue
Block a user