aiomisc 17.5.29__py3-none-any.whl → 17.5.31__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,7 +88,7 @@ class DNSRecord:
88
88
  type: RecordType
89
89
  data: RD
90
90
  cls: DNSClass = field(default=DNSClass.IN)
91
- ttl: int = field(default=3600)
91
+ ttl: int = field(default=3600, compare=False)
92
92
 
93
93
  def rr(self, query_type: int) -> dnslib.RR:
94
94
  return dnslib.RR(
@@ -1,4 +1,4 @@
1
- from typing import Optional, Sequence, Tuple
1
+ from typing import Iterable, Mapping, Optional, Sequence, Tuple
2
2
 
3
3
  from .records import DNSRecord, RecordType
4
4
  from .tree import RadixTree
@@ -49,3 +49,22 @@ class DNSStore:
49
49
  @staticmethod
50
50
  def get_reverse_tuple(zone_name: str) -> Tuple[str, ...]:
51
51
  return tuple(zone_name.strip(".").split("."))[::-1]
52
+
53
+ def replace(
54
+ self, zones_data: Mapping[str, Iterable[DNSRecord]],
55
+ ) -> None:
56
+ """
57
+ Atomically replace all zones with new ones this method is safe
58
+ because it replaces all zones at once. zone_data is a mapping
59
+ zone name and a sequence of DNSRecord objects.
60
+
61
+ If any of the zones or records is invalid, nothing will be replaced.
62
+
63
+ This method is useful for reload configuration from disk
64
+ or database or etc.
65
+ """
66
+ new_zones: RadixTree[DNSZone] = RadixTree()
67
+ for zone_name, records in zones_data.items():
68
+ zone = DNSZone(zone_name, *records)
69
+ new_zones.insert(self.get_reverse_tuple(zone.name), zone)
70
+ self.zones = new_zones
@@ -1,28 +1,33 @@
1
1
  from collections import defaultdict
2
- from typing import DefaultDict, Sequence, Set, Tuple
2
+ from typing import DefaultDict, Iterable, Sequence, Set, Tuple
3
3
 
4
4
  from .records import DNSRecord, RecordType
5
5
 
6
6
 
7
+ RecordsType = DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
8
+
9
+
7
10
  class DNSZone:
8
- records: DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
11
+ records: RecordsType
9
12
  name: str
10
13
 
11
14
  __slots__ = ("name", "records")
12
15
 
13
- def __init__(self, name: str):
16
+ def __init__(self, name: str, *records: DNSRecord) -> None:
14
17
  if not name.endswith("."):
15
18
  name += "."
16
19
  self.name = name
17
20
  self.records = defaultdict(set)
18
21
 
22
+ for record in records:
23
+ self.add_record(record)
24
+
19
25
  def add_record(self, record: DNSRecord) -> None:
20
- if not self._is_valid_record(record):
26
+ if not self.check_record(record):
21
27
  raise ValueError(
22
28
  f"Record {record.name} does not belong to zone {self.name}",
23
29
  )
24
- key = (record.name, record.type)
25
- self.records[key].add(record)
30
+ self.records[(record.name, record.type)].add(record)
26
31
 
27
32
  def remove_record(self, record: DNSRecord) -> None:
28
33
  key = (record.name, record.type)
@@ -37,8 +42,26 @@ class DNSZone:
37
42
  ) -> Sequence[DNSRecord]:
38
43
  if not name.endswith("."):
39
44
  name += "."
40
- key = (name, record_type)
41
- return tuple(self.records.get(key, ()))
45
+ return tuple(self.records.get((name, record_type), ()))
42
46
 
43
- def _is_valid_record(self, record: DNSRecord) -> bool:
47
+ def check_record(self, record: DNSRecord) -> bool:
44
48
  return record.name.endswith(self.name)
49
+
50
+ def replace(self, records: Iterable[DNSRecord]) -> None:
51
+ """
52
+ Atomically replace all records in specified zone with new ones.
53
+ This method is safe because it replaces all records at once.
54
+
55
+ If any of the records does not belong to the zone, ValueError
56
+ will be raised and no records will be replaced.
57
+ """
58
+ new_records: RecordsType = defaultdict(set)
59
+
60
+ for record in records:
61
+ if not self.check_record(record):
62
+ raise ValueError(
63
+ f"Record {record.name} does not "
64
+ f"belong to zone {self.name}",
65
+ )
66
+ new_records[(record.name, record.type)].add(record)
67
+ self.records = new_records
aiomisc/service/raven.py CHANGED
@@ -70,7 +70,7 @@ class AioHttpTransportBase(
70
70
  def __init__(
71
71
  self, parsed_url: Optional[str] = None, *, verify_ssl: bool = True,
72
72
  timeout: TimeoutType = defaults.TIMEOUT, keepalive: bool = True,
73
- family: int = socket.AF_INET,
73
+ family: socket.AddressFamily = socket.AddressFamily.AF_INET,
74
74
  ):
75
75
  self._keepalive = keepalive
76
76
  self._family = family
@@ -92,7 +92,7 @@ class AioHttpTransportBase(
92
92
  return self._keepalive
93
93
 
94
94
  @property
95
- def family(self) -> int:
95
+ def family(self) -> socket.AddressFamily:
96
96
  return self._family
97
97
 
98
98
  def _client_session_factory(self) -> aiohttp.ClientSession:
aiomisc/version.py CHANGED
@@ -2,5 +2,5 @@
2
2
  # BY: poem-plugins "git" plugin
3
3
  # NEVER EDIT THIS FILE MANUALLY
4
4
 
5
- version_info = (17, 5, 29)
6
- __version__ = "17.5.29"
5
+ version_info = (17, 5, 31)
6
+ __version__ = "17.5.31"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aiomisc
3
- Version: 17.5.29
3
+ Version: 17.5.31
4
4
  Summary: aiomisc - miscellaneous utils for asyncio
5
5
  Home-page: https://github.com/aiokitchen/aiomisc
6
6
  License: MIT
@@ -25,16 +25,16 @@ aiomisc/service/base.py,sha256=6xvD27Sh2jy-4JWer6n31FuSq798DZhLI730YYGQbYc,4322
25
25
  aiomisc/service/carbon.py,sha256=o7x2LYUOfCcWYDAP9EFdCTtsduXhqkyMAuIqVio9YsM,1743
26
26
  aiomisc/service/cron.py,sha256=VM-FjdAhy_zFkU-YTdpBSxF79upvrsCo-3kdI9cZTOo,1975
27
27
  aiomisc/service/dns/__init__.py,sha256=RT8_0H8LrQe8sz2xvA2BvLi6CiJVZeVFltNRAx9MN7o,254
28
- aiomisc/service/dns/records.py,sha256=dN_yS3KKmRCF4fNk-fxRB2m-NCQaho42thG5OLFpyZU,8756
28
+ aiomisc/service/dns/records.py,sha256=VE65kDSJ3Fg3-V60-AQQY2OxR89_ggaAc38k7vKUatM,8771
29
29
  aiomisc/service/dns/service.py,sha256=F8KSmFry6WpA4tWNrKcXVhS6GWb_Cyl3uanGu4lbOPw,3616
30
- aiomisc/service/dns/store.py,sha256=FchfLSoWAI2x4n5RyIcnx_i7RQjHmBbco4L4rSAanGU,1749
30
+ aiomisc/service/dns/store.py,sha256=PCYp-H1UoFzUVaYfSnK78_TG3fw1CeIzg-ndMgu_cE4,2509
31
31
  aiomisc/service/dns/tree.py,sha256=q9VRcVxggrClUHyGZZqqSByMaHdU4nYPC1NdT17cVWM,1575
32
- aiomisc/service/dns/zone.py,sha256=Dc3bL7L3rz38J0_R790d_uJlisfJ78vwfdsxmtVfg_w,1343
32
+ aiomisc/service/dns/zone.py,sha256=6Xmrl_leLalSiRQWWNuwGtZVw31Y93i9K2j0JU1vt-4,2174
33
33
  aiomisc/service/grpc_server.py,sha256=G1iRGX3jAfv3fpzNnw_n6UuhORmIZK4cz6aAi7t7qcU,4553
34
34
  aiomisc/service/periodic.py,sha256=BEKGWxWDOX11sfo7MFYp-hiB5iZ4-c2BRsjS56k5B-0,1241
35
35
  aiomisc/service/process.py,sha256=mZf8muZJNWQo95pUmzchMk08MJMhLifFK8m4CnNX49k,4477
36
36
  aiomisc/service/profiler.py,sha256=6KiJsU7tD5eO4YKZXYujV2E8P-G8GUqLAGIl0AuPNG4,1503
37
- aiomisc/service/raven.py,sha256=76GTQ2tOZ4exvWnqnI84hDQc1iBVO1Psrxal0zG7-ow,12166
37
+ aiomisc/service/raven.py,sha256=VHqnXWx-_r71_pjFniIB_E4CgT2reuRD1EB4yEC0hzE,12214
38
38
  aiomisc/service/sdwatchdog.py,sha256=6AMI0MP5deZKEmxguE3w68dapW4xFLRYgx9rgBk5mRw,4473
39
39
  aiomisc/service/tcp.py,sha256=gIdm4wXT191TMpL3Yzm_I7y--1kVxBLioN5lBP8mlhs,5507
40
40
  aiomisc/service/tls.py,sha256=oFTYVe2zf1Ow_Gniem9WyNj_SkD3q95bcsz8LWAYqdI,7325
@@ -45,7 +45,7 @@ aiomisc/signal.py,sha256=_iiC2jukXg7-LLirIl1YATlKIIsKLbmTNFr1Ezheu7g,1728
45
45
  aiomisc/thread_pool.py,sha256=591u5HV1aBmBRcaVm4kAtMLPZOb6veqhT9wkts_knqE,14017
46
46
  aiomisc/timeout.py,sha256=OhXCvQGbPZA9IQ7cRT7ZlZnsbmDgH5ioErQyjeqIEzY,919
47
47
  aiomisc/utils.py,sha256=6yTfTpeRCVzfZp-MJCmB1oayOHUBVwQwzC3U5PBAjn8,11919
48
- aiomisc/version.py,sha256=nd6HyJwsO6HlGHmAhBOBqPIXx-CkhF0dqF_CekE6tJ0,156
48
+ aiomisc/version.py,sha256=inQlcadD8kWvAqeup4DUVRxcUEOCEEwskUqD2Cu1nXM,156
49
49
  aiomisc/worker_pool.py,sha256=GA91KdOrBlqHthbVSTxu_d6BsBIbl-uKqW2NxqSafG0,11107
50
50
  aiomisc_log/__init__.py,sha256=ZD-Q-YTWoZdxJpMqMNMIraA_gaN0QawgnVpXz6mxd2o,4855
51
51
  aiomisc_log/enum.py,sha256=_zfCZPYCGyI9KL6TqHiYVlOfA5U5MCbsuCuDKxDHdxg,1549
@@ -63,8 +63,8 @@ aiomisc_worker/process_inner.py,sha256=8ZtjCSLrgySW57OIbuGrpEWxfysRLYKx1or1YaAqx
63
63
  aiomisc_worker/protocol.py,sha256=1smmlBbdreSmnrxuhHaUMUC10FO9xMIEcedhweQJX_A,2705
64
64
  aiomisc_worker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  aiomisc_worker/worker.py,sha256=f8nCFhlKh84UUBUaEgCllwMRvVZiD8_UUXaeit6g3T8,3236
66
- aiomisc-17.5.29.dist-info/COPYING,sha256=Ky_8CQMaIixfyOreUBsl0hKN6A5fLnPF8KPQ9molMYA,1125
67
- aiomisc-17.5.29.dist-info/METADATA,sha256=KoNJ-qBG7Wo5jedEjR_YqSNsDMDPDEpOVUwb3RHjwmM,15724
68
- aiomisc-17.5.29.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
69
- aiomisc-17.5.29.dist-info/entry_points.txt,sha256=KRsSPCwKJyGTWrvzpwbS0yIDwzsgDA2X6f0CBWYmNao,55
70
- aiomisc-17.5.29.dist-info/RECORD,,
66
+ aiomisc-17.5.31.dist-info/COPYING,sha256=Ky_8CQMaIixfyOreUBsl0hKN6A5fLnPF8KPQ9molMYA,1125
67
+ aiomisc-17.5.31.dist-info/METADATA,sha256=4Mvo60Wnj7oJLOqGnrPrbiIGcSEiKY1HHCTj5dVHqa0,15724
68
+ aiomisc-17.5.31.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
69
+ aiomisc-17.5.31.dist-info/entry_points.txt,sha256=KRsSPCwKJyGTWrvzpwbS0yIDwzsgDA2X6f0CBWYmNao,55
70
+ aiomisc-17.5.31.dist-info/RECORD,,