Skip to content

Commit f3cd293

Browse files
Generic http datasource (#239)
* Http Datasource * Datasource Factory * Changelog * Cleanup Co-authored-by: Lev Gorodetskiy <[email protected]>
1 parent 7f73c9b commit f3cd293

File tree

6 files changed

+104
-32
lines changed

6 files changed

+104
-32
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ Please use [this](https://docs.gitlab.com/ee/development/changelog.html) documen
4444

4545
## 4.2.4 - 2022-02-14
4646

47+
### Added
48+
49+
* config: Added `http` datasource to making arbitrary http requests.
50+
4751
### Fixed
4852

4953
* context: Fixed crash when calling `fire_hook` method.

src/dipdup/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,22 @@ def __hash__(self):
273273
return hash(self.kind + self.url)
274274

275275

276+
@dataclass
277+
class HttpDatasourceConfig(NameMixin):
278+
kind: Literal['http']
279+
url: str
280+
http: Optional[HTTPConfig] = None
281+
282+
def __hash__(self):
283+
return hash(self.kind + self.url)
284+
285+
276286
DatasourceConfigT = Union[
277287
TzktDatasourceConfig,
278288
CoinbaseDatasourceConfig,
279289
MetadataDatasourceConfig,
280290
IpfsDatasourceConfig,
291+
HttpDatasourceConfig,
281292
]
282293

283294

src/dipdup/context.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from dipdup.config import TzktDatasourceConfig
3939
from dipdup.datasources.coinbase.datasource import CoinbaseDatasource
4040
from dipdup.datasources.datasource import Datasource
41+
from dipdup.datasources.datasource import HttpDatasource
4142
from dipdup.datasources.ipfs.datasource import IpfsDatasource
4243
from dipdup.datasources.metadata.datasource import MetadataDatasource
4344
from dipdup.datasources.tzkt.datasource import TzktDatasource
@@ -298,6 +299,9 @@ def get_metadata_datasource(self, name: str) -> MetadataDatasource:
298299
def get_ipfs_datasource(self, name: str) -> IpfsDatasource:
299300
return self._get_datasource(name, IpfsDatasource)
300301

302+
def get_http_datasource(self, name: str) -> HttpDatasource:
303+
return self._get_datasource(name, HttpDatasource)
304+
301305

302306
class HookContext(DipDupContext):
303307
"""Hook callback context."""

src/dipdup/datasources/datasource.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from typing import Set
77
from typing import Tuple
88

9+
from aiohttp.hdrs import METH_GET
10+
911
from dipdup.config import HTTPConfig
1012
from dipdup.datasources.subscription import HeadSubscription
1113
from dipdup.datasources.subscription import Subscription
@@ -38,6 +40,26 @@ def set_logger(self, name: str) -> None:
3840
self._logger = FormattedLogger(self._logger.name, name + ': {}')
3941

4042

43+
class HttpDatasource(Datasource):
44+
_default_http_config = HTTPConfig(
45+
cache=True,
46+
retry_count=5,
47+
retry_sleep=1,
48+
ratelimit_rate=0,
49+
ratelimit_period=0,
50+
)
51+
52+
def __init__(self, url: str, http_config: Optional[HTTPConfig] = None) -> None:
53+
super().__init__(url, self._default_http_config.merge(http_config))
54+
self._logger = _logger
55+
56+
async def get(self, url: str, cache: bool = False, weight: int = 1, **kwargs):
57+
return await self.request(METH_GET, url, cache, weight, **kwargs)
58+
59+
async def run(self) -> None:
60+
pass
61+
62+
4163
# TODO: Generic interface
4264
class GraphQLDatasource(Datasource):
4365
...

src/dipdup/datasources/factory.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from dipdup.config import CoinbaseDatasourceConfig
2+
from dipdup.config import DipDupConfig
3+
from dipdup.config import HttpDatasourceConfig
4+
from dipdup.config import IpfsDatasourceConfig
5+
from dipdup.config import MetadataDatasourceConfig
6+
from dipdup.config import TzktDatasourceConfig
7+
from dipdup.datasources.coinbase.datasource import CoinbaseDatasource
8+
from dipdup.datasources.datasource import Datasource
9+
from dipdup.datasources.datasource import HttpDatasource
10+
from dipdup.datasources.ipfs.datasource import IpfsDatasource
11+
from dipdup.datasources.metadata.datasource import MetadataDatasource
12+
from dipdup.datasources.tzkt.datasource import TzktDatasource
13+
14+
15+
class DatasourceFactory:
16+
"""Decouple Context logic and knowledge about Datasources implementation and creation"""
17+
18+
@classmethod
19+
def build(cls, name: str, config: DipDupConfig) -> Datasource:
20+
datasource = cls._build_datasource(name, config)
21+
datasource.set_logger(name)
22+
datasource.set_user_agent(config.package)
23+
24+
return datasource
25+
26+
@classmethod
27+
def _build_datasource(cls, name: str, config: DipDupConfig) -> Datasource:
28+
datasource_config = config.get_datasource(name)
29+
30+
if isinstance(datasource_config, TzktDatasourceConfig):
31+
return TzktDatasource(
32+
url=datasource_config.url,
33+
http_config=datasource_config.http,
34+
merge_subscriptions=config.advanced.merge_subscriptions,
35+
)
36+
37+
if isinstance(datasource_config, CoinbaseDatasourceConfig):
38+
return CoinbaseDatasource(
39+
http_config=datasource_config.http,
40+
)
41+
42+
if isinstance(datasource_config, MetadataDatasourceConfig):
43+
return MetadataDatasource(
44+
url=datasource_config.url,
45+
network=datasource_config.network,
46+
http_config=datasource_config.http,
47+
)
48+
49+
if isinstance(datasource_config, IpfsDatasourceConfig):
50+
return IpfsDatasource(
51+
url=datasource_config.url,
52+
http_config=datasource_config.http,
53+
)
54+
55+
if isinstance(datasource_config, HttpDatasourceConfig):
56+
return HttpDatasource(
57+
url=datasource_config.url,
58+
http_config=datasource_config.http,
59+
)
60+
61+
raise NotImplementedError

src/dipdup/dipdup.py

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,20 @@
2323
from tortoise.transactions import get_connection
2424

2525
from dipdup.codegen import DipDupCodeGenerator
26-
from dipdup.config import CoinbaseDatasourceConfig
2726
from dipdup.config import ContractConfig
2827
from dipdup.config import DatasourceConfigT
2928
from dipdup.config import DipDupConfig
3029
from dipdup.config import IndexTemplateConfig
31-
from dipdup.config import IpfsDatasourceConfig
32-
from dipdup.config import MetadataDatasourceConfig
3330
from dipdup.config import OperationIndexConfig
3431
from dipdup.config import PostgresDatabaseConfig
35-
from dipdup.config import TzktDatasourceConfig
3632
from dipdup.config import default_hooks
3733
from dipdup.context import CallbackManager
3834
from dipdup.context import DipDupContext
3935
from dipdup.context import MetadataCursor
4036
from dipdup.context import pending_indexes
41-
from dipdup.datasources.coinbase.datasource import CoinbaseDatasource
4237
from dipdup.datasources.datasource import Datasource
4338
from dipdup.datasources.datasource import IndexDatasource
44-
from dipdup.datasources.ipfs.datasource import IpfsDatasource
45-
from dipdup.datasources.metadata.datasource import MetadataDatasource
39+
from dipdup.datasources.factory import DatasourceFactory
4640
from dipdup.datasources.tzkt.datasource import TzktDatasource
4741
from dipdup.enums import ReindexingReason
4842
from dipdup.exceptions import ConfigInitializationException
@@ -376,32 +370,8 @@ async def _create_datasources(self) -> None:
376370
if name in self._datasources:
377371
continue
378372

379-
if isinstance(datasource_config, TzktDatasourceConfig):
380-
datasource = TzktDatasource(
381-
url=datasource_config.url,
382-
http_config=datasource_config.http,
383-
merge_subscriptions=self._config.advanced.merge_subscriptions,
384-
)
385-
elif isinstance(datasource_config, CoinbaseDatasourceConfig):
386-
datasource = CoinbaseDatasource(
387-
http_config=datasource_config.http,
388-
)
389-
elif isinstance(datasource_config, MetadataDatasourceConfig):
390-
datasource = MetadataDatasource(
391-
url=datasource_config.url,
392-
network=datasource_config.network,
393-
http_config=datasource_config.http,
394-
)
395-
elif isinstance(datasource_config, IpfsDatasourceConfig):
396-
datasource = IpfsDatasource(
397-
url=datasource_config.url,
398-
http_config=datasource_config.http,
399-
)
400-
else:
401-
raise NotImplementedError
373+
datasource = DatasourceFactory.build(name, self._config)
402374

403-
datasource.set_logger(datasource_config.name)
404-
datasource.set_user_agent(self._config.package)
405375
self._datasources[name] = datasource
406376
self._datasources_by_config[datasource_config] = datasource
407377

0 commit comments

Comments
 (0)