Skip to content

Commit 5743530

Browse files
committed
feat: add main
1 parent ce2f039 commit 5743530

File tree

19 files changed

+211
-32
lines changed

19 files changed

+211
-32
lines changed

deploy/dev/docker-compose.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ services:
1212
volumes:
1313
- ../..:/app
1414
- tgdb-data:/run/app
15-
environments:
15+
environment:
1616
CONF_PATH: /app/deploy/dev/tgdb/conf.yaml
17-
command: bash
17+
ports:
18+
- 8000:8000
19+
command: tgdb-dev
1820

1921
volumes:
2022
tgdb-data: null

deploy/dev/tgdb/conf.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
conf:
2+
uvicorn:
3+
host: "0.0.0.0"
4+
port: 8000
5+
26
api:
37
id: 23598539
48
hash: "6d9d7305ffc6f148dab120d24541b127"
59

610
clients:
7-
bots: "/app/deploy/dev/tgdb/bots/bots.txt"
8-
userbots: "/app/deploy/dev/tgdb/bots/userbots.txt"
11+
bots: "/app/deploy/dev/tgdb/clients/bots.txt"
12+
userbots: "/app/deploy/dev/tgdb/clients/userbots.txt"
913

1014
horizon:
1115
max_len: 10_000

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Repository = "https://github.com/emptybutton/tgdb"
2525
[project.optional-dependencies]
2626
dev = [
2727
"mypy[faster-cache]==1.15.0",
28+
"types-pyyaml==6.0.12.20250516",
2829
"ruff==0.9.7",
2930
"pytest==8.3.4",
3031
"pytest-cov==6.0.0",
@@ -43,6 +44,10 @@ build-backend = "hatchling.build"
4344
[tool.hatch.build.targets.wheel]
4445
packages = ["src/tgdb"]
4546

47+
[project.scripts]
48+
tgdb = "tgdb.main.prod_server.__main__:main"
49+
tgdb-dev = "tgdb.main.dev_server.__main__:main"
50+
4651
[tool.mypy]
4752
mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/tests"
4853
strict = true

src/tgdb/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from importlib.metadata import version
2+
3+
4+
__version__ = version("tgdb")

src/tgdb/infrastructure/pyyaml/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
from dataclasses import dataclass
21
from pathlib import Path
32

43
import yaml
54
from pydantic import BaseModel, Field
65

76

7+
class UvicornConf(BaseModel):
8+
host: str
9+
port: int
10+
11+
812
class APIConf(BaseModel):
913
id: int
1014
hash: str
@@ -60,6 +64,7 @@ class BufferConf(BaseModel):
6064

6165

6266
class Conf(BaseModel):
67+
uvicorn: UvicornConf
6368
api: APIConf
6469
clients: ClientsConf
6570
horizon: HorizonConf

src/tgdb/infrastructure/telethon/client_pool.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
from typing import Self, cast
99

1010
from telethon import TelegramClient
11-
from telethon.sessions.string import StringSession
1211
from telethon.types import InputPeerUser
1312

13+
from tgdb.infrastructure.telethon.string_session_without_entites import (
14+
StringSessionWithoutEntites,
15+
)
16+
1417

1518
@dataclass(frozen=True, unsafe_hash=False)
1619
class TelegramClientPool(AbstractAsyncContextManager["TelegramClientPool"]):
@@ -21,6 +24,11 @@ class TelegramClientPool(AbstractAsyncContextManager["TelegramClientPool"]):
2124
)
2225

2326
async def __aenter__(self) -> Self:
27+
await gather(*(
28+
client.__aenter__() # type: ignore[no-untyped-call]
29+
for client in self._clients
30+
))
31+
2432
for client in self._clients:
2533
client_info = (
2634
cast(InputPeerUser, await client.get_me(input_peer=True))
@@ -29,11 +37,6 @@ async def __aenter__(self) -> Self:
2937

3038
self._client_by_id[client_id] = client
3139

32-
await gather(*(
33-
client.__aenter__() # type: ignore[no-untyped-call]
34-
for client in self._clients
35-
))
36-
3740
return self
3841

3942
async def __aexit__(
@@ -71,12 +74,19 @@ def loaded_client_pool_from_farm_file(
7174
) -> TelegramClientPool:
7275
with farm_file_path.open() as farm_file:
7376
return TelegramClientPool(deque(
74-
TelegramClient(
75-
StringSession(session_token),
76-
app_api_id,
77-
app_api_hash,
78-
entity_cache=None,
79-
)
77+
pool_client(session_token, app_api_id, app_api_hash)
8078
for session_token in farm_file
8179
if session_token
8280
))
81+
82+
83+
def pool_client(
84+
session_token: str, app_api_id: int, app_api_hash: str
85+
) -> TelegramClient:
86+
print(session_token)
87+
return TelegramClient(
88+
StringSessionWithoutEntites(session_token),
89+
app_api_id,
90+
app_api_hash,
91+
entity_cache_limit=0,
92+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from typing import Any
2+
3+
from telethon.sessions.string import StringSession
4+
5+
6+
class StringSessionWithoutEntites(StringSession):
7+
def process_entities(self, tlo: Any) -> None: # noqa: ANN401
8+
...

src/tgdb/main/common/di.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from tgdb.application.view_tuples import ViewTuples
2525
from tgdb.entities.horizon.horizon import Horizon, horizon
2626
from tgdb.entities.horizon.transaction import PreparedCommit
27+
from tgdb.entities.relation.relation import Relation
2728
from tgdb.infrastructure.adapters.buffer import (
2829
InMemoryBuffer,
2930
InTelegramReplicablePreparedCommitBuffer,
@@ -35,6 +36,7 @@
3536
from tgdb.infrastructure.adapters.shared_horizon import InMemorySharedHorizon
3637
from tgdb.infrastructure.adapters.tuples import InTelegramHeapTuples
3738
from tgdb.infrastructure.adapters.uuids import UUIDs4
39+
from tgdb.infrastructure.async_map import AsyncMap
3840
from tgdb.infrastructure.async_queque import AsyncQueque
3941
from tgdb.infrastructure.pyyaml.conf import Conf, VacuumConf
4042
from tgdb.infrastructure.telethon.client_pool import (
@@ -54,6 +56,8 @@
5456
BotPool = NewType("BotPool", TelegramClientPool)
5557
UserBotPool = NewType("UserBotPool", TelegramClientPool)
5658

59+
RelationCache = NewType("RelationCache", InMemoryDb[Relation])
60+
5761

5862
def conf_vacuum(
5963
conf: VacuumConf, bot_pool: BotPool, user_bot_pool: UserBotPool
@@ -73,12 +77,12 @@ class CommonProvider(Provider):
7377
provide_clock = provide(PerfCounterClock, provides=Clock, scope=Scope.APP)
7478
provide_uuids = provide(UUIDs4, provides=UUIDs, scope=Scope.APP)
7579
provide_queque = provide(
76-
lambda: InMemoryQueque(AsyncQueque()),
80+
staticmethod(lambda: InMemoryQueque(AsyncQueque())),
7781
provides=Queque[Sequence[PreparedCommit]],
7882
scope=Scope.APP
7983
)
8084
provide_channel = provide(
81-
AsyncMapChannel,
85+
staticmethod(lambda: AsyncMapChannel(AsyncMap())),
8286
provides=Channel,
8387
scope=Scope.APP,
8488
)
@@ -174,20 +178,24 @@ def provide_buffer(
174178

175179
return InTelegramReplicablePreparedCommitBuffer(buffer, in_tg_bytes)
176180

181+
@provide(scope=Scope.APP)
182+
def provide_relation_cache(self) -> RelationCache:
183+
return RelationCache(InMemoryDb())
184+
177185
@provide(scope=Scope.APP)
178186
def provide_relations(
179187
self,
180188
conf: Conf,
181189
bot_pool: BotPool,
182190
user_bot_pool: UserBotPool,
191+
relation_cache: RelationCache,
183192
) -> Relations:
184193
autovacuum = conf_vacuum(conf.relations.vacuum, bot_pool, user_bot_pool)
185194
in_tg_bytes = InTelegramBytes(
186195
bot_pool, user_bot_pool, conf.relations.chat, autovacuum
187196
)
188-
cached_relations = InMemoryDb()
189197

190-
return InTelegramReplicableRelations(in_tg_bytes, cached_relations)
198+
return InTelegramReplicableRelations(in_tg_bytes, relation_cache)
191199

192200
provide_commit_transaction = provide(CommitTransaction, scope=Scope.APP)
193201
provide_output_commits = provide(OutputCommits, scope=Scope.APP)

src/tgdb/main/dev_server/__init__.py

Whitespace-only changes.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import asyncio
2+
3+
import uvicorn
4+
5+
from tgdb.infrastructure.pyyaml.conf import Conf
6+
from tgdb.main.server.di import server_container
7+
from tgdb.presentation.fastapi.common.app import app_from
8+
9+
10+
async def amain() -> None:
11+
app = await app_from(server_container)
12+
conf = await server_container.get(Conf)
13+
14+
config = uvicorn.Config(
15+
app,
16+
host=conf.uvicorn.host,
17+
port=conf.uvicorn.port,
18+
reload=True,
19+
reload_dirs=["/app"],
20+
)
21+
server = uvicorn.Server(config)
22+
23+
await server.serve()
24+
25+
26+
def main() -> None:
27+
asyncio.run(amain())
28+
29+
30+
if __name__ == "__main__":
31+
main()

0 commit comments

Comments
 (0)