added base protocol types that every app in this monorepo import it

This commit is contained in:
2026-08-29 11:04:54 +03:30
parent 5c8310b837
commit fc5267175e
17 changed files with 43 additions and 28 deletions
+1
View File
@@ -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"
+5
View File
@@ -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 -2
View File
@@ -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 -2
View File
@@ -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 -2
View File
@@ -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"
] ]
} }
+3 -3
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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:
+1 -1
View File
@@ -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)
View File
@@ -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
View File
@@ -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.
View File