Files
daena/pyproject.toml
T
ahp 4da9accabf feat: replace REST API with gRPC service
Complete migration from FastAPI/HTTP to gRPC:

Proto definition (proto/daena/v1/daena.proto):
- Daena service with 9 RPCs: GetStatus, GetHealth, GetConfig,
  ListPlugins, GetQueueState, ListPendingRecords, ListDeadRecords,
  ListSinks, ReloadConfig
- Messages for all request/response types with proper field types

gRPC server (src/daena/api/grpc_server.py):
- Async gRPC aio server with DaenaServicer implementation
- DaenaGRPCServer with start/stop/serve_forever lifecycle
- All endpoints delegate to DaenaRuntime

gRPC client (src/daena/cli/main.py):
- CLI now uses grpc.insecure_channel + DaenaStub
- Same commands: status, health, queue, sinks, plugins, config, version

Config changes:
- Remove FastAPI/uvicorn/http config, replace with grpc config
- GRPCConfig with host/port/max_workers

Dependency changes:
- Remove fastapi, uvicorn, starlette, anyio
- Add grpcio, grpcio-tools, protobuf
- Keep httpx for HTTP sink forwarding (separate from management API)

Tests:
- 8 new gRPC integration tests (test_grpc.py)
- All 31 tests passing, ruff clean
2026-07-15 10:48:18 +03:30

93 lines
2.1 KiB
TOML

[project]
name = "daena"
version = "0.1.0"
description = "Collect, buffer, and forward logs and events from Linux to central observability backends"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.13"
authors = [
{ name = "Amir Husayn Panahifar", email = "ahp@panahifar.ir" },
]
keywords = ["logging", "observability", "linux", "daemon", "events"]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Intended Audience :: System Administrators",
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3.13",
"Topic :: System :: Logging",
"Topic :: System :: Monitoring",
]
dependencies = [
"grpcio>=1.70",
"grpcio-tools>=1.70",
"protobuf>=5.28",
"pydantic>=2.0",
"pydantic-settings>=2.0",
"PyYAML>=6.0",
"structlog>=24.0",
"typer>=0.12",
"httpx>=0.28",
"lmdb>=1.5",
"tenacity>=8.0",
"rich>=13.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.24",
"pytest-cov>=5.0",
"mypy>=1.10",
"ruff>=0.5",
]
[project.scripts]
daena = "daena.cli.main:app"
daena-serve = "daena.app:serve"
[project.entry-points."daena.sources"]
dummy = "daena.pipeline.sources.dummy:DummySource"
[project.entry-points."daena.sinks"]
dummy = "daena.pipeline.sinks.dummy:DummySink"
http = "daena.pipeline.sinks.http:HTTPSink"
[project.entry-points."daena.processors"]
passthrough = "daena.pipeline.processors.passthrough:PassthroughProcessor"
[tool.pyproject-fmt]
max_blank_lines = 1
[tool.ruff]
target-version = "py313"
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "B", "SIM", "ARG"]
[tool.ruff.format]
quote-style = "double"
[tool.mypy]
python_version = "3.13"
strict = true
warn_unused_ignores = true
exclude = [
"tests/",
".venv/",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
filterwarnings = [
"ignore::DeprecationWarning",
]
[build-system]
requires = ["hatchling>=1.25"]
build-backend = "hatchling.build"