abstract-block-dumper 0.0.6__tar.gz → 0.0.7__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 (82) hide show
  1. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/CHANGELOG.md +5 -0
  2. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/PKG-INFO +1 -1
  3. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/tasks.py +1 -1
  4. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/uv.lock +1 -1
  5. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/services/scheduler.py +73 -6
  6. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/services/utils.py +1 -5
  7. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_version.py +2 -2
  8. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.cruft.json +0 -0
  9. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.github/dependabot.yml +0 -0
  10. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.github/workflows/ci.yml +0 -0
  11. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.github/workflows/publish.yml +0 -0
  12. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.gitignore +0 -0
  13. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.pre-commit-config.yaml +0 -0
  14. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/.shellcheckrc +0 -0
  15. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/README.md +0 -0
  16. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/SECURITY.md +0 -0
  17. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/docs/3rd_party/cookiecutter-rt-pkg/CHANGELOG.md +0 -0
  18. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/.dockerignore +0 -0
  19. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/.gitignore +0 -0
  20. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/Dockerfile +0 -0
  21. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/README.md +0 -0
  22. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/__init__.py +0 -0
  23. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/admin.py +0 -0
  24. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/apps.py +0 -0
  25. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/management/__init__.py +0 -0
  26. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/management/commands/__init__.py +0 -0
  27. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/management/commands/create_admin.py +0 -0
  28. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/migrations/__init__.py +0 -0
  29. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/models.py +0 -0
  30. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/tests.py +0 -0
  31. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/block_explorer/views.py +0 -0
  32. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/docker-compose.yml +0 -0
  33. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/__init__.py +0 -0
  34. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/asgi.py +0 -0
  35. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/celery.py +0 -0
  36. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/settings.py +0 -0
  37. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/urls.py +0 -0
  38. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/example_project/wsgi.py +0 -0
  39. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/main.py +0 -0
  40. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/manage.py +0 -0
  41. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/pyproject.toml +0 -0
  42. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/example_project/pytest.ini +0 -0
  43. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/noxfile.py +0 -0
  44. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/pyproject.toml +0 -0
  45. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/__init__.py +0 -0
  46. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/__init__.py +0 -0
  47. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/dal/__init__.py +0 -0
  48. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/dal/django_dal.py +0 -0
  49. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/dal/memory_registry.py +0 -0
  50. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/discovery.py +0 -0
  51. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/exceptions.py +0 -0
  52. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/services/__init__.py +0 -0
  53. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/services/block_processor.py +0 -0
  54. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/_internal/services/executor.py +0 -0
  55. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/admin.py +0 -0
  56. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/apps.py +0 -0
  57. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/management/__init__.py +0 -0
  58. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/management/commands/__init__.py +0 -0
  59. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/management/commands/block_tasks_v1.py +0 -0
  60. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/migrations/0001_initial.py +0 -0
  61. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/migrations/__init__.py +0 -0
  62. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/models.py +0 -0
  63. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/py.typed +0 -0
  64. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/v1/__init__.py +0 -0
  65. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/v1/celery.py +0 -0
  66. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/v1/decorators.py +0 -0
  67. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/src/abstract_block_dumper/v1/tasks.py +0 -0
  68. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/__init__.py +0 -0
  69. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/conftest.py +0 -0
  70. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/django_fixtures.py +0 -0
  71. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/fatories.py +0 -0
  72. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/__init__.py +0 -0
  73. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_block_processor.py +0 -0
  74. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_concurrent_processing.py +0 -0
  75. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_multi_arguments_tasks.py +0 -0
  76. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_registered_celery_tasks.py +0 -0
  77. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_scheduler.py +0 -0
  78. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/integration/test_task_registration.py +0 -0
  79. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/settings.py +0 -0
  80. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/unit/test_celery_integration.py +0 -0
  81. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/tests/unit/test_decorator.py +0 -0
  82. {abstract_block_dumper-0.0.6 → abstract_block_dumper-0.0.7}/uv.lock +0 -0
@@ -9,6 +9,11 @@ upcoming release can be found in [changelog.d](changelog.d).
9
9
 
10
10
  <!-- towncrier release notes start -->
11
11
 
12
+ ## [0.0.7](https://github.com/bactensor/abstract-block-dumper/releases/tag/v0.0.7) - 2025-12-01
13
+
14
+ No significant changes.
15
+
16
+
12
17
  ## [0.0.6](https://github.com/bactensor/abstract-block-dumper/releases/tag/v0.0.6) - 2025-11-26
13
18
 
14
19
  No significant changes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstract-block-dumper
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Project-URL: Source, https://github.com/bactensor/abstract-block-dumper
5
5
  Project-URL: Issue Tracker, https://github.com/bactensor/abstract-block-dumper/issues
6
6
  Author-email: Reef Technologies <opensource@reef.pl>
@@ -41,6 +41,6 @@ def backfill_previous_100_blocks(block_number: int, netuid: int | None = None) -
41
41
  backfilling_lookback=1000,
42
42
  celery_kwargs={"retry": True},
43
43
  )
44
- def subnet_analysis(block_number, netuid):
44
+ def subnet_analysis(block_number, netuid) -> str:
45
45
  # Analyze subnet data
46
46
  return f"Processed block {block_number} for NetUID {netuid}"
@@ -15,7 +15,7 @@ dependencies = [
15
15
  [package.metadata]
16
16
  requires-dist = [
17
17
  { name = "bittensor", specifier = ">=9.10.1" },
18
- { name = "celery", specifier = ">=5.5.3" },
18
+ { name = "celery", specifier = ">=5.3" },
19
19
  { name = "django", specifier = ">=3.2,<6.0" },
20
20
  { name = "structlog", specifier = ">=25.4.0" },
21
21
  ]
@@ -10,19 +10,77 @@ from abstract_block_dumper._internal.services.block_processor import BlockProces
10
10
 
11
11
  logger = structlog.get_logger(__name__)
12
12
 
13
+ # Blocks older than this threshold from current head require archive network
14
+ ARCHIVE_BLOCK_THRESHOLD = 300
15
+
13
16
 
14
17
  class TaskScheduler:
15
18
  def __init__(
16
19
  self,
17
20
  block_processor: BlockProcessor,
18
- subtensor: bt.Subtensor,
21
+ network: str,
19
22
  poll_interval: int,
20
23
  ) -> None:
21
24
  self.block_processor = block_processor
22
- self.subtensor = subtensor
25
+ self.network = network
23
26
  self.poll_interval = poll_interval
24
27
  self.last_processed_block = -1
25
28
  self.is_running = False
29
+ self._subtensor: bt.Subtensor | None = None
30
+ self._archive_subtensor: bt.Subtensor | None = None
31
+ self._current_block_cache: int | None = None
32
+
33
+ @property
34
+ def subtensor(self) -> bt.Subtensor:
35
+ """Get the regular subtensor connection, creating it if needed."""
36
+ if self._subtensor is None:
37
+ self._subtensor = abd_utils.get_bittensor_client(self.network)
38
+ return self._subtensor
39
+
40
+ @subtensor.setter
41
+ def subtensor(self, value: bt.Subtensor | None) -> None:
42
+ """Set or reset the subtensor connection."""
43
+ self._subtensor = value
44
+
45
+ @property
46
+ def archive_subtensor(self) -> bt.Subtensor:
47
+ """Get the archive subtensor connection, creating it if needed."""
48
+ if self._archive_subtensor is None:
49
+ self._archive_subtensor = abd_utils.get_bittensor_client("archive")
50
+ return self._archive_subtensor
51
+
52
+ @archive_subtensor.setter
53
+ def archive_subtensor(self, value: bt.Subtensor | None) -> None:
54
+ """Set or reset the archive subtensor connection."""
55
+ self._archive_subtensor = value
56
+
57
+ def get_subtensor_for_block(self, block_number: int) -> bt.Subtensor:
58
+ """
59
+ Get the appropriate subtensor for the given block number.
60
+
61
+ Uses archive network for blocks older than ARCHIVE_BLOCK_THRESHOLD
62
+ from the current head.
63
+ """
64
+ if self._current_block_cache is None:
65
+ self._current_block_cache = self.subtensor.get_current_block()
66
+
67
+ blocks_behind = self._current_block_cache - block_number
68
+
69
+ if blocks_behind > ARCHIVE_BLOCK_THRESHOLD:
70
+ logger.debug(
71
+ "Using archive network for old block",
72
+ block_number=block_number,
73
+ blocks_behind=blocks_behind,
74
+ )
75
+ return self.archive_subtensor
76
+ return self.subtensor
77
+
78
+ def refresh_connections(self) -> None:
79
+ """Reset all subtensor connections to force re-establishment."""
80
+ self._subtensor = None
81
+ self._archive_subtensor = None
82
+ self._current_block_cache = None
83
+ logger.info("Subtensor connections reset")
26
84
 
27
85
  def start(self) -> None:
28
86
  self.is_running = True
@@ -40,13 +98,15 @@ class TaskScheduler:
40
98
  # Process lost retries first
41
99
  self.block_processor.recover_failed_retries()
42
100
 
43
- current_block = self.subtensor.get_current_block()
101
+ # Update current block cache for archive network decision
102
+ self._current_block_cache = self.subtensor.get_current_block()
103
+ current_block = self._current_block_cache
44
104
 
45
105
  for block_number in range(self.last_processed_block + 1, current_block + 1):
46
106
  self.block_processor.process_block(block_number)
107
+ time.sleep(self.poll_interval)
47
108
  self.last_processed_block = block_number
48
109
 
49
- time.sleep(self.poll_interval)
50
110
  except KeyboardInterrupt:
51
111
  logger.info("TaskScheduler stopping due to KeyboardInterrupt.")
52
112
  self.stop()
@@ -86,9 +146,16 @@ class TaskScheduler:
86
146
  )
87
147
 
88
148
 
89
- def task_scheduler_factory() -> TaskScheduler:
149
+ def task_scheduler_factory(network: str = "finney") -> TaskScheduler:
150
+ """
151
+ Factory for TaskScheduler.
152
+
153
+ Args:
154
+ network (str): Bittensor network name. Defaults to "finney"
155
+
156
+ """
90
157
  return TaskScheduler(
91
158
  block_processor=block_processor_factory(),
92
- subtensor=abd_utils.get_bittensor_client(),
159
+ network=network,
93
160
  poll_interval=getattr(settings, "BLOCK_DUMPER_POLL_INTERVAL", 1),
94
161
  )
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  from collections.abc import Callable
3
- from functools import cache
4
3
 
5
4
  import bittensor as bt
6
5
  import structlog
@@ -10,16 +9,13 @@ from django.conf import settings
10
9
  logger = structlog.get_logger(__name__)
11
10
 
12
11
 
13
- @cache
14
- def get_bittensor_client() -> bt.Subtensor:
12
+ def get_bittensor_client(network: str = "finney") -> bt.Subtensor:
15
13
  """
16
14
  Get a cached bittensor client.
17
15
 
18
16
  The client is cached indefinitely since network configuration
19
17
  doesn't change during runtime.
20
18
  """
21
- DEFAULT_BITTENSOR_NETWORK = "finney"
22
- network = getattr(settings, "BITTENSOR_NETWORK", DEFAULT_BITTENSOR_NETWORK)
23
19
  logger.info("Creating new bittensor client for network", network=network)
24
20
  return bt.subtensor(network=network)
25
21
 
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.6'
32
- __version_tuple__ = version_tuple = (0, 0, 6)
31
+ __version__ = version = '0.0.7'
32
+ __version_tuple__ = version_tuple = (0, 0, 7)
33
33
 
34
34
  __commit_id__ = commit_id = None