aiwaf 0.1.7.1__tar.gz → 0.1.7.3__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.

Potentially problematic release.


This version of aiwaf might be problematic. Click here for more details.

Files changed (24) hide show
  1. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/PKG-INFO +5 -1
  2. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/README.md +4 -0
  3. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/middleware.py +13 -13
  4. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf.egg-info/PKG-INFO +5 -1
  5. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf.egg-info/SOURCES.txt +2 -2
  6. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/pyproject.toml +1 -1
  7. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/setup.py +1 -1
  8. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/LICENSE +0 -0
  9. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/__init__.py +0 -0
  10. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/apps.py +0 -0
  11. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/blacklist_manager.py +0 -0
  12. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/management/__init__.py +0 -0
  13. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/management/commands/__init__.py +0 -0
  14. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/management/commands/detect_and_train.py +0 -0
  15. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/models.py +0 -0
  16. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/resources/model.pkl +0 -0
  17. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/storage.py +0 -0
  18. {aiwaf-0.1.7.1/aiwaf/template_tags → aiwaf-0.1.7.3/aiwaf/templatetags}/__init__.py +0 -0
  19. {aiwaf-0.1.7.1/aiwaf/template_tags → aiwaf-0.1.7.3/aiwaf/templatetags}/aiwaf_tags.py +0 -0
  20. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/trainer.py +0 -0
  21. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf/utils.py +0 -0
  22. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf.egg-info/dependency_links.txt +0 -0
  23. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/aiwaf.egg-info/top_level.txt +0 -0
  24. {aiwaf-0.1.7.1 → aiwaf-0.1.7.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.7.1
3
+ Version: 0.1.7.3
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -22,6 +22,10 @@ Dynamic: requires-python
22
22
 
23
23
  ---
24
24
 
25
+ ## System Requirements
26
+
27
+ No GPU needed—AI-WAF runs entirely on CPU with just Python 3.8+, Django 3.2+, a single vCPU and ~512 MB RAM for small sites; for moderate production traffic you can bump to 2–4 vCPUs and 2–4 GB RAM, offload the daily detect-and-train job to a worker, and rotate logs to keep memory use bounded.
28
+
25
29
  ## 📁 Package Structure
26
30
 
27
31
  ```
@@ -6,6 +6,10 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## System Requirements
10
+
11
+ No GPU needed—AI-WAF runs entirely on CPU with just Python 3.8+, Django 3.2+, a single vCPU and ~512 MB RAM for small sites; for moderate production traffic you can bump to 2–4 vCPUs and 2–4 GB RAM, offload the daily detect-and-train job to a worker, and rotate logs to keep memory use bounded.
12
+
9
13
  ## 📁 Package Structure
10
14
 
11
15
  ```
@@ -101,29 +101,29 @@ class IPAndKeywordBlockMiddleware:
101
101
 
102
102
 
103
103
  class RateLimitMiddleware:
104
- WINDOW = 10
105
- MAX = 20
106
- FLOOD = 10
104
+ WINDOW = 10 # seconds
105
+ MAX = 20 # soft limit
106
+ FLOOD = 40 # hard limit
107
107
 
108
108
  def __init__(self, get_response):
109
109
  self.get_response = get_response
110
- self.logs = defaultdict(list)
111
110
 
112
111
  def __call__(self, request):
113
112
  if is_exempt_path(request.path):
114
113
  return self.get_response(request)
115
- ip = get_ip(request)
116
- now = time.time()
117
- recs = [t for t in self.logs[ip] if now - t < self.WINDOW]
118
- recs.append(now)
119
- self.logs[ip] = recs
120
114
 
121
- if len(recs) > self.MAX:
122
- return JsonResponse({"error": "too_many_requests"}, status=429)
123
- if len(recs) > self.FLOOD:
115
+ ip = get_ip(request)
116
+ key = f"ratelimit:{ip}"
117
+ now = time.time()
118
+ timestamps = cache.get(key, [])
119
+ timestamps = [t for t in timestamps if now - t < self.WINDOW]
120
+ timestamps.append(now)
121
+ cache.set(key, timestamps, timeout=self.WINDOW)
122
+ if len(timestamps) > self.FLOOD:
124
123
  BlacklistManager.block(ip, "Flood pattern")
125
124
  return JsonResponse({"error": "blocked"}, status=403)
126
-
125
+ if len(timestamps) > self.MAX:
126
+ return JsonResponse({"error": "too_many_requests"}, status=429)
127
127
  return self.get_response(request)
128
128
 
129
129
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.7.1
3
+ Version: 0.1.7.3
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -22,6 +22,10 @@ Dynamic: requires-python
22
22
 
23
23
  ---
24
24
 
25
+ ## System Requirements
26
+
27
+ No GPU needed—AI-WAF runs entirely on CPU with just Python 3.8+, Django 3.2+, a single vCPU and ~512 MB RAM for small sites; for moderate production traffic you can bump to 2–4 vCPUs and 2–4 GB RAM, offload the daily detect-and-train job to a worker, and rotate logs to keep memory use bounded.
28
+
25
29
  ## 📁 Package Structure
26
30
 
27
31
  ```
@@ -18,5 +18,5 @@ aiwaf/management/__init__.py
18
18
  aiwaf/management/commands/__init__.py
19
19
  aiwaf/management/commands/detect_and_train.py
20
20
  aiwaf/resources/model.pkl
21
- aiwaf/template_tags/__init__.py
22
- aiwaf/template_tags/aiwaf_tags.py
21
+ aiwaf/templatetags/__init__.py
22
+ aiwaf/templatetags/aiwaf_tags.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aiwaf"
3
- version = "0.1.7.1"
3
+ version = "0.1.7.3"
4
4
  description = "AI-powered Web Application Firewall"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.8"
@@ -9,7 +9,7 @@ long_description = (HERE / "README.md").read_text(encoding="utf-8")
9
9
 
10
10
  setup(
11
11
  name="aiwaf",
12
- version="0.1.7.1",
12
+ version="0.1.7.3",
13
13
  description="AI‑driven, self‑learning Web Application Firewall for Django",
14
14
  long_description=long_description,
15
15
  long_description_content_type="text/markdown",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes