aiomisc 17.5.29__tar.gz → 17.5.31__tar.gz

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.
Files changed (70) hide show
  1. {aiomisc-17.5.29 → aiomisc-17.5.31}/PKG-INFO +1 -1
  2. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/records.py +1 -1
  3. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/store.py +20 -1
  4. aiomisc-17.5.31/aiomisc/service/dns/zone.py +67 -0
  5. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/raven.py +2 -2
  6. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/version.py +2 -2
  7. {aiomisc-17.5.29 → aiomisc-17.5.31}/pyproject.toml +1 -1
  8. aiomisc-17.5.29/aiomisc/service/dns/zone.py +0 -44
  9. {aiomisc-17.5.29 → aiomisc-17.5.31}/COPYING +0 -0
  10. {aiomisc-17.5.29 → aiomisc-17.5.31}/README.rst +0 -0
  11. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/__init__.py +0 -0
  12. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/_context_vars.py +0 -0
  13. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/aggregate.py +0 -0
  14. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/backoff.py +0 -0
  15. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/circuit_breaker.py +0 -0
  16. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/compat.py +0 -0
  17. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/context.py +0 -0
  18. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/counters.py +0 -0
  19. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/cron.py +0 -0
  20. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/entrypoint.py +0 -0
  21. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/io.py +0 -0
  22. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/iterator_wrapper.py +0 -0
  23. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/log.py +0 -0
  24. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/periodic.py +0 -0
  25. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/plugins/__init__.py +0 -0
  26. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/plugins/__main__.py +0 -0
  27. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/pool.py +0 -0
  28. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/process_pool.py +0 -0
  29. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/py.typed +0 -0
  30. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/recurring.py +0 -0
  31. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/__init__.py +0 -0
  32. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/aiohttp.py +0 -0
  33. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/asgi.py +0 -0
  34. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/base.py +0 -0
  35. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/carbon.py +0 -0
  36. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/cron.py +0 -0
  37. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/__init__.py +0 -0
  38. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/service.py +0 -0
  39. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/tree.py +0 -0
  40. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/grpc_server.py +0 -0
  41. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/periodic.py +0 -0
  42. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/process.py +0 -0
  43. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/profiler.py +0 -0
  44. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/sdwatchdog.py +0 -0
  45. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tcp.py +0 -0
  46. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tls.py +0 -0
  47. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tracer.py +0 -0
  48. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/udp.py +0 -0
  49. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/uvicorn.py +0 -0
  50. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/signal.py +0 -0
  51. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/thread_pool.py +0 -0
  52. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/timeout.py +0 -0
  53. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/utils.py +0 -0
  54. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/worker_pool.py +0 -0
  55. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/__init__.py +0 -0
  56. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/enum.py +0 -0
  57. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/__init__.py +0 -0
  58. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/color.py +0 -0
  59. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/journald.py +0 -0
  60. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/json.py +0 -0
  61. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/rich.py +0 -0
  62. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/py.typed +0 -0
  63. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/__init__.py +0 -0
  64. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/__main__.py +0 -0
  65. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/forking.py +0 -0
  66. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/process.py +0 -0
  67. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/process_inner.py +0 -0
  68. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/protocol.py +0 -0
  69. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/py.typed +0 -0
  70. {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/worker.py +0 -0
@@ -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
@@ -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
@@ -0,0 +1,67 @@
1
+ from collections import defaultdict
2
+ from typing import DefaultDict, Iterable, Sequence, Set, Tuple
3
+
4
+ from .records import DNSRecord, RecordType
5
+
6
+
7
+ RecordsType = DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
8
+
9
+
10
+ class DNSZone:
11
+ records: RecordsType
12
+ name: str
13
+
14
+ __slots__ = ("name", "records")
15
+
16
+ def __init__(self, name: str, *records: DNSRecord) -> None:
17
+ if not name.endswith("."):
18
+ name += "."
19
+ self.name = name
20
+ self.records = defaultdict(set)
21
+
22
+ for record in records:
23
+ self.add_record(record)
24
+
25
+ def add_record(self, record: DNSRecord) -> None:
26
+ if not self.check_record(record):
27
+ raise ValueError(
28
+ f"Record {record.name} does not belong to zone {self.name}",
29
+ )
30
+ self.records[(record.name, record.type)].add(record)
31
+
32
+ def remove_record(self, record: DNSRecord) -> None:
33
+ key = (record.name, record.type)
34
+ if key in self.records:
35
+ self.records[key].discard(record)
36
+ if self.records[key]:
37
+ return
38
+ del self.records[key]
39
+
40
+ def get_records(
41
+ self, name: str, record_type: RecordType,
42
+ ) -> Sequence[DNSRecord]:
43
+ if not name.endswith("."):
44
+ name += "."
45
+ return tuple(self.records.get((name, record_type), ()))
46
+
47
+ def check_record(self, record: DNSRecord) -> bool:
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
@@ -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:
@@ -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,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "aiomisc"
3
3
  # This is a dummy version which will be rewritten with poem-plugins
4
- version = "17.5.29"
4
+ version = "17.5.31"
5
5
  description = "aiomisc - miscellaneous utils for asyncio"
6
6
  authors = ["Dmitry Orlov <me@mosquito.su>"]
7
7
  readme = "README.rst"
@@ -1,44 +0,0 @@
1
- from collections import defaultdict
2
- from typing import DefaultDict, Sequence, Set, Tuple
3
-
4
- from .records import DNSRecord, RecordType
5
-
6
-
7
- class DNSZone:
8
- records: DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
9
- name: str
10
-
11
- __slots__ = ("name", "records")
12
-
13
- def __init__(self, name: str):
14
- if not name.endswith("."):
15
- name += "."
16
- self.name = name
17
- self.records = defaultdict(set)
18
-
19
- def add_record(self, record: DNSRecord) -> None:
20
- if not self._is_valid_record(record):
21
- raise ValueError(
22
- f"Record {record.name} does not belong to zone {self.name}",
23
- )
24
- key = (record.name, record.type)
25
- self.records[key].add(record)
26
-
27
- def remove_record(self, record: DNSRecord) -> None:
28
- key = (record.name, record.type)
29
- if key in self.records:
30
- self.records[key].discard(record)
31
- if self.records[key]:
32
- return
33
- del self.records[key]
34
-
35
- def get_records(
36
- self, name: str, record_type: RecordType,
37
- ) -> Sequence[DNSRecord]:
38
- if not name.endswith("."):
39
- name += "."
40
- key = (name, record_type)
41
- return tuple(self.records.get(key, ()))
42
-
43
- def _is_valid_record(self, record: DNSRecord) -> bool:
44
- return record.name.endswith(self.name)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes