limits 4.7__tar.gz → 4.7.2__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 (99) hide show
  1. {limits-4.7 → limits-4.7.2}/HISTORY.rst +18 -0
  2. {limits-4.7 → limits-4.7.2}/PKG-INFO +1 -1
  3. limits-4.7.2/doc/source/ext/_static/benchmark-chart.css +61 -0
  4. {limits-4.7 → limits-4.7.2}/doc/source/ext/_static/js/benchmark-chart.js +46 -21
  5. {limits-4.7 → limits-4.7.2}/doc/source/ext/_static/js/benchmark-details.js +22 -6
  6. {limits-4.7 → limits-4.7.2}/doc/source/ext/_static/js/benchmark-loader.js +4 -5
  7. limits-4.7.2/doc/source/ext/_templates/git_info.js +2 -0
  8. {limits-4.7 → limits-4.7.2}/doc/source/ext/bench_chart.py +15 -4
  9. {limits-4.7 → limits-4.7.2}/doc/source/performance.rst +1 -1
  10. {limits-4.7 → limits-4.7.2}/limits/_version.py +3 -3
  11. {limits-4.7 → limits-4.7.2}/limits.egg-info/PKG-INFO +1 -1
  12. limits-4.7/doc/source/ext/_static/benchmark-chart.css +0 -10
  13. limits-4.7/doc/source/ext/_templates/git_info.js +0 -2
  14. {limits-4.7 → limits-4.7.2}/CLASSIFIERS +0 -0
  15. {limits-4.7 → limits-4.7.2}/CONTRIBUTIONS.rst +0 -0
  16. {limits-4.7 → limits-4.7.2}/LICENSE.txt +0 -0
  17. {limits-4.7 → limits-4.7.2}/MANIFEST.in +0 -0
  18. {limits-4.7 → limits-4.7.2}/README.rst +0 -0
  19. {limits-4.7 → limits-4.7.2}/doc/Makefile +0 -0
  20. {limits-4.7 → limits-4.7.2}/doc/source/_static/custom.css +0 -0
  21. {limits-4.7 → limits-4.7.2}/doc/source/api.rst +0 -0
  22. {limits-4.7 → limits-4.7.2}/doc/source/async.rst +0 -0
  23. {limits-4.7 → limits-4.7.2}/doc/source/changelog.rst +0 -0
  24. {limits-4.7 → limits-4.7.2}/doc/source/conf.py +0 -0
  25. {limits-4.7 → limits-4.7.2}/doc/source/custom-storage.rst +0 -0
  26. {limits-4.7 → limits-4.7.2}/doc/source/index.rst +0 -0
  27. {limits-4.7 → limits-4.7.2}/doc/source/installation.rst +0 -0
  28. {limits-4.7 → limits-4.7.2}/doc/source/quickstart.rst +0 -0
  29. {limits-4.7 → limits-4.7.2}/doc/source/storage.rst +0 -0
  30. {limits-4.7 → limits-4.7.2}/doc/source/strategies.rst +0 -0
  31. {limits-4.7 → limits-4.7.2}/doc/source/theme_config.py +0 -0
  32. {limits-4.7 → limits-4.7.2}/limits/__init__.py +0 -0
  33. {limits-4.7 → limits-4.7.2}/limits/aio/__init__.py +0 -0
  34. {limits-4.7 → limits-4.7.2}/limits/aio/storage/__init__.py +0 -0
  35. {limits-4.7 → limits-4.7.2}/limits/aio/storage/base.py +0 -0
  36. {limits-4.7 → limits-4.7.2}/limits/aio/storage/etcd.py +0 -0
  37. {limits-4.7 → limits-4.7.2}/limits/aio/storage/memcached.py +0 -0
  38. {limits-4.7 → limits-4.7.2}/limits/aio/storage/memory.py +0 -0
  39. {limits-4.7 → limits-4.7.2}/limits/aio/storage/mongodb.py +0 -0
  40. {limits-4.7 → limits-4.7.2}/limits/aio/storage/redis/__init__.py +0 -0
  41. {limits-4.7 → limits-4.7.2}/limits/aio/storage/redis/bridge.py +0 -0
  42. {limits-4.7 → limits-4.7.2}/limits/aio/storage/redis/coredis.py +0 -0
  43. {limits-4.7 → limits-4.7.2}/limits/aio/storage/redis/redispy.py +0 -0
  44. {limits-4.7 → limits-4.7.2}/limits/aio/storage/redis/valkey.py +0 -0
  45. {limits-4.7 → limits-4.7.2}/limits/aio/strategies.py +0 -0
  46. {limits-4.7 → limits-4.7.2}/limits/errors.py +0 -0
  47. {limits-4.7 → limits-4.7.2}/limits/limits.py +0 -0
  48. {limits-4.7 → limits-4.7.2}/limits/py.typed +0 -0
  49. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/acquire_moving_window.lua +0 -0
  50. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/acquire_sliding_window.lua +0 -0
  51. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/clear_keys.lua +0 -0
  52. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/incr_expire.lua +0 -0
  53. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/moving_window.lua +0 -0
  54. {limits-4.7 → limits-4.7.2}/limits/resources/redis/lua_scripts/sliding_window.lua +0 -0
  55. {limits-4.7 → limits-4.7.2}/limits/storage/__init__.py +0 -0
  56. {limits-4.7 → limits-4.7.2}/limits/storage/base.py +0 -0
  57. {limits-4.7 → limits-4.7.2}/limits/storage/etcd.py +0 -0
  58. {limits-4.7 → limits-4.7.2}/limits/storage/memcached.py +0 -0
  59. {limits-4.7 → limits-4.7.2}/limits/storage/memory.py +0 -0
  60. {limits-4.7 → limits-4.7.2}/limits/storage/mongodb.py +0 -0
  61. {limits-4.7 → limits-4.7.2}/limits/storage/redis.py +0 -0
  62. {limits-4.7 → limits-4.7.2}/limits/storage/redis_cluster.py +0 -0
  63. {limits-4.7 → limits-4.7.2}/limits/storage/redis_sentinel.py +0 -0
  64. {limits-4.7 → limits-4.7.2}/limits/storage/registry.py +0 -0
  65. {limits-4.7 → limits-4.7.2}/limits/strategies.py +0 -0
  66. {limits-4.7 → limits-4.7.2}/limits/typing.py +0 -0
  67. {limits-4.7 → limits-4.7.2}/limits/util.py +0 -0
  68. {limits-4.7 → limits-4.7.2}/limits/version.py +0 -0
  69. {limits-4.7 → limits-4.7.2}/limits.egg-info/SOURCES.txt +0 -0
  70. {limits-4.7 → limits-4.7.2}/limits.egg-info/dependency_links.txt +0 -0
  71. {limits-4.7 → limits-4.7.2}/limits.egg-info/not-zip-safe +0 -0
  72. {limits-4.7 → limits-4.7.2}/limits.egg-info/requires.txt +0 -0
  73. {limits-4.7 → limits-4.7.2}/limits.egg-info/top_level.txt +0 -0
  74. {limits-4.7 → limits-4.7.2}/pyproject.toml +0 -0
  75. {limits-4.7 → limits-4.7.2}/requirements/ci.txt +0 -0
  76. {limits-4.7 → limits-4.7.2}/requirements/dev.txt +0 -0
  77. {limits-4.7 → limits-4.7.2}/requirements/docs.txt +0 -0
  78. {limits-4.7 → limits-4.7.2}/requirements/main.txt +0 -0
  79. {limits-4.7 → limits-4.7.2}/requirements/storage/async-etcd.txt +0 -0
  80. {limits-4.7 → limits-4.7.2}/requirements/storage/async-memcached.txt +0 -0
  81. {limits-4.7 → limits-4.7.2}/requirements/storage/async-mongodb.txt +0 -0
  82. {limits-4.7 → limits-4.7.2}/requirements/storage/async-redis.txt +0 -0
  83. {limits-4.7 → limits-4.7.2}/requirements/storage/async-valkey.txt +0 -0
  84. {limits-4.7 → limits-4.7.2}/requirements/storage/etcd.txt +0 -0
  85. {limits-4.7 → limits-4.7.2}/requirements/storage/memcached.txt +0 -0
  86. {limits-4.7 → limits-4.7.2}/requirements/storage/mongodb.txt +0 -0
  87. {limits-4.7 → limits-4.7.2}/requirements/storage/redis.txt +0 -0
  88. {limits-4.7 → limits-4.7.2}/requirements/storage/rediscluster.txt +0 -0
  89. {limits-4.7 → limits-4.7.2}/requirements/storage/valkey.txt +0 -0
  90. {limits-4.7 → limits-4.7.2}/requirements/test.txt +0 -0
  91. {limits-4.7 → limits-4.7.2}/setup.cfg +0 -0
  92. {limits-4.7 → limits-4.7.2}/setup.py +0 -0
  93. {limits-4.7 → limits-4.7.2}/tests/test_limit_granularities.py +0 -0
  94. {limits-4.7 → limits-4.7.2}/tests/test_limits.py +0 -0
  95. {limits-4.7 → limits-4.7.2}/tests/test_ratelimit_parser.py +0 -0
  96. {limits-4.7 → limits-4.7.2}/tests/test_storage.py +0 -0
  97. {limits-4.7 → limits-4.7.2}/tests/test_strategy.py +0 -0
  98. {limits-4.7 → limits-4.7.2}/tests/test_utils.py +0 -0
  99. {limits-4.7 → limits-4.7.2}/versioneer.py +0 -0
@@ -3,6 +3,22 @@
3
3
  Changelog
4
4
  =========
5
5
 
6
+ v4.7.2
7
+ ------
8
+ Release Date: 2025-04-09
9
+
10
+ * Documentation
11
+
12
+ * Improve presentation of benchmark docs
13
+
14
+ v4.7.1
15
+ ------
16
+ Release Date: 2025-04-08
17
+
18
+ * Testing
19
+
20
+ * Fix incorrect benchmark for async test method
21
+
6
22
  v4.7
7
23
  ----
8
24
  Release Date: 2025-04-08
@@ -854,6 +870,8 @@ Release Date: 2015-01-08
854
870
 
855
871
 
856
872
 
873
+
874
+
857
875
 
858
876
 
859
877
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: limits
3
- Version: 4.7
3
+ Version: 4.7.2
4
4
  Summary: Rate limiting utilities
5
5
  Home-page: https://limits.readthedocs.org
6
6
  Author: Ali-Akber Saifee
@@ -0,0 +1,61 @@
1
+ .benchmark-chart {
2
+ width: 100%;
3
+ }
4
+ .benchmark-details {
5
+ .benchmark-details-section {
6
+ thead > tr {
7
+ color: var(--color-purple);
8
+ }
9
+ }
10
+ }
11
+ .benchmark-chart-error,
12
+ .benchmark-details-error {
13
+ color: var(--color-red);
14
+ font-size: smaller;
15
+ padding: 2em;
16
+ text-align: center;
17
+ height: 5em;
18
+ }
19
+ .benchmark-chart-loading {
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: center;
23
+ font-size: 1.2rem;
24
+ font-weight: bold;
25
+ color: var(--color-purple);
26
+ letter-spacing: 1px;
27
+ height: 200px;
28
+ animation: benchmark-chart-loading-animation;
29
+ animation-iteration-count: 10;
30
+ animation-duration: 2s;
31
+ }
32
+
33
+ @keyframes benchmark-chart-loading-animation {
34
+ 0% {
35
+ opacity: 0;
36
+ }
37
+ ,
38
+ 25% {
39
+ opacity: 25%;
40
+ }
41
+ ,
42
+ 50% {
43
+ opacity: 50%;
44
+ }
45
+ ,
46
+ 90% {
47
+ opacity: 90%;
48
+ }
49
+ ,
50
+ 100% {
51
+ opacity: 100%;
52
+ }
53
+ }
54
+
55
+ .plot-container {
56
+ filter: invert(100%);
57
+ }
58
+
59
+ body[data-theme="light"] .plot-container {
60
+ filter: invert(0);
61
+ }
@@ -1,3 +1,5 @@
1
+ import { render, html } from "https://unpkg.com/uhtml@3.2.1?module";
2
+ import { fetchBenchmarkData } from "./benchmark-loader.js";
1
3
  const KNOWN_PARAMS = ["storage_type", "limit", "strategy", "async"];
2
4
 
3
5
  function getBenchmarkData(result, query) {
@@ -44,7 +46,7 @@ function formatRateLimit(str) {
44
46
 
45
47
  function nameTransform(benchmark, stripParams, query) {
46
48
  let name = benchmark.name;
47
- params = benchmark.params;
49
+ let params = benchmark.params;
48
50
  name = name
49
51
  .replace(/\[.*?\]/, "")
50
52
  .replace("_async", "")
@@ -97,21 +99,6 @@ function getColorForStorage(storageType) {
97
99
  return storageColorMap[storageType] || "#7f7f7f"; // gray
98
100
  }
99
101
 
100
- function sortBenchmarksByParams(benchmarks, sortKeys) {
101
- return benchmarks.sort((a, b) => {
102
- for (const key of sortKeys) {
103
- let valA = (a.params?.[key] || "").toLowerCase();
104
- let valB = (b.params?.[key] || "").toLowerCase();
105
- if (key == "limit") {
106
- valA = parseInt(valA.split(" ")[0]);
107
- valB = parseInt(valB.split(" ")[0]);
108
- }
109
- return valA < valB ? -1 : valA > valB ? 1 : 0;
110
- }
111
-
112
- return a.name.localeCompare(b.name);
113
- });
114
- }
115
102
  function sortBenchmarksByParams(benchmarks, sortKeys) {
116
103
  return benchmarks.sort(function (a, b) {
117
104
  for (const key of sortKeys) {
@@ -127,6 +114,7 @@ function sortBenchmarksByParams(benchmarks, sortKeys) {
127
114
  return a.name.localeCompare(b.name);
128
115
  });
129
116
  }
117
+
130
118
  let dispatched = new Set();
131
119
 
132
120
  document.addEventListener("DOMContentLoaded", function () {
@@ -138,15 +126,38 @@ document.addEventListener("DOMContentLoaded", function () {
138
126
  let sortBy = JSON.parse(
139
127
  chart.dataset.sortBy || '["storage_type", "limit"]',
140
128
  );
129
+ render(
130
+ chart,
131
+ html`
132
+ <div class="benchmark-chart-loading">
133
+ <span>Loading</span>
134
+ </div>
135
+ `,
136
+ );
141
137
  if (!dispatched.has(source)) {
142
- fetchBenchmarkData(`${source}.json`).then((result) => {
143
- window.Benchmarks[source] = result;
144
- event = new Event(`${source}-loaded`);
145
- window.dispatchEvent(event);
146
- });
138
+ fetchBenchmarkData(`${source}.json`)
139
+ .then((result) => {
140
+ window.Benchmarks[source] = result;
141
+ let event = new Event(`${source}-loaded`);
142
+ window.dispatchEvent(event);
143
+ })
144
+ .catch((error) => {
145
+ let event = new Event(`${source}-failed`);
146
+ window.dispatchEvent(event);
147
+ });
147
148
  }
148
149
  dispatched.add(source);
150
+ window.addEventListener(`${chart.dataset.source}-failed`, function () {
151
+ chart.querySelector(".benchmark-chart-loading")?.remove();
152
+ render(
153
+ chart,
154
+ html`
155
+ <div class="benchmark-chart-error">Benchmark data not available.</div>
156
+ `,
157
+ );
158
+ });
149
159
  window.addEventListener(`${chart.dataset.source}-loaded`, function () {
160
+ chart.querySelector(".benchmark-chart-loading")?.remove();
150
161
  let results = Benchmarks[chart.dataset.source];
151
162
  let unsorted = getBenchmarkData(results, query);
152
163
  let data = sortBenchmarksByParams(
@@ -188,7 +199,21 @@ document.addEventListener("DOMContentLoaded", function () {
188
199
  return item;
189
200
  }),
190
201
  layout,
202
+ { responsive: true, displaylogo: false },
191
203
  );
204
+ let initial = true;
205
+ chart.on("plotly_afterplot", function () {
206
+ const { hash } = window.location;
207
+ if (hash && initial) {
208
+ initial = false;
209
+ const target = document.querySelector(hash);
210
+ if (target) {
211
+ setTimeout(function () {
212
+ target.scrollIntoView({ behavior: "instant" });
213
+ }, 10);
214
+ }
215
+ }
216
+ });
192
217
  });
193
218
  });
194
219
  });
@@ -1,21 +1,37 @@
1
1
  import { render, html } from "https://unpkg.com/uhtml@3.2.1?module";
2
+ import { fetchBenchmarkData } from "./benchmark-loader.js";
2
3
  document.addEventListener("DOMContentLoaded", function () {
3
4
  const details = document.querySelectorAll(".benchmark-details");
5
+ let dispatched = new Set();
4
6
  details.forEach((detail) => {
5
7
  let source = detail.dataset.source;
6
8
  if (!dispatched.has(source)) {
7
- fetchBenchmarkData(`${source}.json`).then((result) => {
8
- window.Benchmarks[source] = result;
9
- event = new Event(`${source}-loaded`);
10
- window.dispatchEvent(event);
11
- });
9
+ fetchBenchmarkData(`${source}.json`)
10
+ .then((result) => {
11
+ window.Benchmarks[source] = result;
12
+ let event = new Event(`${source}-loaded`);
13
+ window.dispatchEvent(event);
14
+ })
15
+ .catch((error) => {
16
+ let event = new Event(`${source}-failed`);
17
+ window.dispatchEvent(event);
18
+ });
12
19
  }
13
20
  dispatched.add(source);
21
+ window.addEventListener(`${detail.dataset.source}-failed`, function () {
22
+ render(
23
+ detail,
24
+ html`
25
+ <div class="benchmark-details-error">
26
+ Benchmark data not available.
27
+ </div>
28
+ `,
29
+ );
30
+ });
14
31
  window.addEventListener(`${detail.dataset.source}-loaded`, function () {
15
32
  const machine_info = window.Benchmarks[source].machine_info;
16
33
  const commit_info = window.Benchmarks[source].commit_info;
17
34
  const cpu = window.Benchmarks[source].machine_info.cpu;
18
- console.log(machine_info);
19
35
  render(
20
36
  detail,
21
37
  html`
@@ -7,16 +7,13 @@ window.Benchmarks = new Map();
7
7
 
8
8
  function fetchBenchmarkData(filename) {
9
9
  let attempts = 0;
10
-
11
10
  function tryFetch() {
12
11
  if (attempts >= BENCHMARK_PATHS.length) {
13
- return Promise.reject("All fetch attempts failed.");
12
+ return Promise.reject(new Error("All fetch attempts failed."));
14
13
  }
15
-
16
14
  const base = BENCHMARK_PATHS[attempts++];
17
15
  const url = base + filename;
18
-
19
- // First send a HEAD request to quietly check existence
16
+ console.log(`Testing ${url}`);
20
17
  return fetch(url, { method: "HEAD" })
21
18
  .then((headRes) => {
22
19
  if (!headRes.ok) throw new Error("HEAD check failed");
@@ -30,3 +27,5 @@ function fetchBenchmarkData(filename) {
30
27
 
31
28
  return tryFetch();
32
29
  }
30
+
31
+ export { fetchBenchmarkData };
@@ -0,0 +1,2 @@
1
+ window.GITBRANCH = "{{branch | replace('.', '-')}}";
2
+ window.GITSHA = "{{sha}}";
@@ -13,11 +13,13 @@ if TYPE_CHECKING:
13
13
 
14
14
  here = os.path.dirname(os.path.abspath(__file__))
15
15
 
16
+
16
17
  def check_bool(value):
17
18
  if value.lower() in ["true", "false"]:
18
19
  return value.lower() == "true"
19
20
  return value
20
21
 
22
+
21
23
  def query(argument):
22
24
  if not argument.strip():
23
25
  return {}
@@ -27,8 +29,9 @@ def query(argument):
27
29
  queries[key] = check_bool(value)
28
30
  return queries
29
31
 
32
+
30
33
  def filters(argument):
31
- filters: dict[str, list|bool] = {}
34
+ filters: dict[str, list | bool] = {}
32
35
  for filter in argument.strip().split(","):
33
36
  if ":" in filter:
34
37
  source, value = filter.split(":")
@@ -37,9 +40,11 @@ def filters(argument):
37
40
  filters[filter] = True
38
41
  return filters
39
42
 
43
+
40
44
  def sortBy(argument):
41
45
  return [k.strip() for k in argument.split(",")] if argument else []
42
46
 
47
+
43
48
  class BenchmarkDetails(SphinxDirective):
44
49
  required_arguments = 0
45
50
  final_argument_whitespace = False
@@ -47,6 +52,7 @@ class BenchmarkDetails(SphinxDirective):
47
52
  "source": str,
48
53
  }
49
54
  has_content = False
55
+
50
56
  def run(self):
51
57
  source = self.options.get("source", "benchmark-summary")
52
58
  html = f"""
@@ -58,6 +64,7 @@ class BenchmarkDetails(SphinxDirective):
58
64
 
59
65
  return [nodes.raw("", html, format="html")]
60
66
 
67
+
61
68
  class BenchmarkChart(SphinxDirective):
62
69
  required_arguments = 0
63
70
  final_argument_whitespace = False
@@ -68,6 +75,7 @@ class BenchmarkChart(SphinxDirective):
68
75
  "sort": sortBy,
69
76
  }
70
77
  has_content = False
78
+
71
79
  def run(self):
72
80
  source = self.options.get("source", "benchmark-summary")
73
81
  filters = self.options.get("filters", ["group"])
@@ -86,6 +94,7 @@ class BenchmarkChart(SphinxDirective):
86
94
 
87
95
  return [nodes.raw("", html, format="html")]
88
96
 
97
+
89
98
  def render_js_template(app) -> None:
90
99
  context = {
91
100
  "branch": app.config.benchmark_git_context.get("branch", ""),
@@ -103,19 +112,22 @@ def render_js_template(app) -> None:
103
112
  f.write(rendered_js)
104
113
  app.add_js_file("js/git_info.js")
105
114
 
115
+
106
116
  def setup(app: Sphinx):
107
117
  app.add_directive("benchmark-chart", BenchmarkChart)
108
118
  app.add_directive("benchmark-details", BenchmarkDetails)
109
119
  app.add_config_value("benchmark_git_context", default={}, rebuild="env")
120
+
110
121
  def add_assets(app, env) -> None:
111
122
  static_path = os.path.join(here, "_static")
112
123
  if static_path not in app.config.html_static_path:
113
124
  app.config.html_static_path.append(static_path)
114
- app.add_js_file("js/benchmark-chart.js")
125
+ app.add_js_file("js/benchmark-chart.js", type="module")
115
126
  app.add_js_file("js/benchmark-details.js", type="module")
116
- app.add_js_file("js/benchmark-loader.js")
127
+ app.add_js_file("js/benchmark-loader.js", type="module")
117
128
  app.add_js_file("https://cdn.plot.ly/plotly-3.0.1.min.js")
118
129
  app.add_css_file("benchmark-chart.css")
130
+
119
131
  app.config.templates_path += [os.path.join(here, "_templates")]
120
132
  app.connect("env-updated", add_assets)
121
133
  app.connect("builder-inited", render_js_template)
@@ -124,5 +136,4 @@ def setup(app: Sphinx):
124
136
  "version": "0.1",
125
137
  "parallel_read_safe": True,
126
138
  "parallel_write_safe": True,
127
-
128
139
  }
@@ -207,7 +207,7 @@ Sliding Window
207
207
  :query: async=false,group=get-window-stats,strategy=sliding-window
208
208
  :sort: storage_type,limit
209
209
 
210
- .. tab:: Get Window (Async)
210
+ .. tab:: Get Window Stats (Async)
211
211
 
212
212
  .. benchmark-chart::
213
213
  :source: benchmark-summary
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-04-08T13:37:22-0700",
11
+ "date": "2025-04-09T14:27:52-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "c20794b223ba2e7984ecf12c4395c092aadcad88",
15
- "version": "4.7"
14
+ "full-revisionid": "451bd270b52aff6324de3ed6576a8fc87fbdaf9a",
15
+ "version": "4.7.2"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: limits
3
- Version: 4.7
3
+ Version: 4.7.2
4
4
  Summary: Rate limiting utilities
5
5
  Home-page: https://limits.readthedocs.org
6
6
  Author: Ali-Akber Saifee
@@ -1,10 +0,0 @@
1
- .benchmark-chart {
2
- width: 100%;
3
- }
4
- .benchmark-details{
5
- .benchmark-details-section {
6
- thead > tr {
7
- color: var(--color-purple);
8
- }
9
- }
10
- }
@@ -1,2 +0,0 @@
1
- window.GITBRANCH = "{{branch}}";
2
- window.GITSHA = "{{sha}}";
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
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
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