aiwaf 0.1.9.0__tar.gz → 0.1.9.0.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.

Potentially problematic release.


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

Files changed (32) hide show
  1. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/PKG-INFO +2 -1
  2. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/README.md +1 -0
  3. aiwaf-0.1.9.0.2/aiwaf/__init__.py +6 -0
  4. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/aiwaf_diagnose.py +8 -0
  5. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/storage.py +31 -11
  6. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/trainer.py +1 -1
  7. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf.egg-info/PKG-INFO +2 -1
  8. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/pyproject.toml +1 -1
  9. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/setup.py +1 -1
  10. aiwaf-0.1.9.0/aiwaf/__init__.py +0 -19
  11. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/LICENSE +0 -0
  12. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/apps.py +0 -0
  13. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/blacklist_manager.py +0 -0
  14. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/decorators.py +0 -0
  15. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/__init__.py +0 -0
  16. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/__init__.py +0 -0
  17. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/add_ipexemption.py +0 -0
  18. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/aiwaf_logging.py +0 -0
  19. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/aiwaf_reset.py +0 -0
  20. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/management/commands/detect_and_train.py +0 -0
  21. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/middleware.py +0 -0
  22. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/middleware_logger.py +0 -0
  23. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/models.py +0 -0
  24. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/resources/model.pkl +0 -0
  25. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/templatetags/__init__.py +0 -0
  26. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/templatetags/aiwaf_tags.py +0 -0
  27. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf/utils.py +0 -0
  28. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf.egg-info/SOURCES.txt +0 -0
  29. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf.egg-info/dependency_links.txt +0 -0
  30. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf.egg-info/requires.txt +0 -0
  31. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/aiwaf.egg-info/top_level.txt +0 -0
  32. {aiwaf-0.1.9.0 → aiwaf-0.1.9.0.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.9.0
3
+ Version: 0.1.9.0.2
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -370,6 +370,7 @@ MIDDLEWARE = [
370
370
  ```
371
371
 
372
372
  **Common Issues:**
373
+ - **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
373
374
  - Missing Django: `pip install Django`
374
375
  - Old AI-WAF version: `pip install --upgrade aiwaf`
375
376
  - Missing migrations: `python manage.py migrate`
@@ -349,6 +349,7 @@ MIDDLEWARE = [
349
349
  ```
350
350
 
351
351
  **Common Issues:**
352
+ - **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
352
353
  - Missing Django: `pip install Django`
353
354
  - Old AI-WAF version: `pip install --upgrade aiwaf`
354
355
  - Missing migrations: `python manage.py migrate`
@@ -0,0 +1,6 @@
1
+ default_app_config = "aiwaf.apps.AiwafConfig"
2
+
3
+ __version__ = "0.1.9.0.2"
4
+
5
+ # Note: Middleware classes are available from aiwaf.middleware
6
+ # Import them only when needed to avoid circular imports during Django app loading
@@ -14,6 +14,14 @@ class Command(BaseCommand):
14
14
  import aiwaf
15
15
  version = getattr(aiwaf, '__version__', 'Unknown')
16
16
  self.stdout.write(self.style.SUCCESS(f"✅ AI-WAF imported successfully (version: {version})"))
17
+
18
+ # Test critical imports that caused AppRegistryNotReady
19
+ try:
20
+ from aiwaf import storage, utils, trainer
21
+ self.stdout.write(self.style.SUCCESS("✅ Critical modules (storage, utils, trainer) imported successfully"))
22
+ except Exception as e:
23
+ self.stdout.write(self.style.ERROR(f"❌ Critical module import failed: {e}"))
24
+
17
25
  except ImportError as e:
18
26
  self.stdout.write(self.style.ERROR(f"❌ AI-WAF import failed: {e}"))
19
27
  return
@@ -4,17 +4,23 @@ import pandas as pd
4
4
  from django.conf import settings
5
5
  from django.utils import timezone
6
6
 
7
- # Only import models if aiwaf is in INSTALLED_APPS
8
- try:
9
- from django.apps import apps
10
- if apps.is_installed('aiwaf'):
11
- from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
12
- else:
13
- # Create dummy classes to avoid import errors
14
- FeatureSample = BlacklistEntry = IPExemption = DynamicKeyword = None
15
- except (ImportError, RuntimeError):
16
- # Handle cases where Django isn't fully initialized yet
17
- FeatureSample = BlacklistEntry = IPExemption = DynamicKeyword = None
7
+ # Defer model imports to avoid AppRegistryNotReady during Django app loading
8
+ FeatureSample = BlacklistEntry = IPExemption = DynamicKeyword = None
9
+
10
+ def _import_models():
11
+ """Import Django models only when needed and apps are ready."""
12
+ global FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
13
+
14
+ if FeatureSample is not None:
15
+ return # Already imported
16
+
17
+ try:
18
+ from django.apps import apps
19
+ if apps.ready and apps.is_installed('aiwaf'):
20
+ from .models import FeatureSample, BlacklistEntry, IPExemption, DynamicKeyword
21
+ except (ImportError, RuntimeError, Exception):
22
+ # Keep models as None if can't import
23
+ pass
18
24
 
19
25
  # Configuration
20
26
  STORAGE_MODE = getattr(settings, "AIWAF_STORAGE_MODE", "models") # "models" or "csv"
@@ -63,6 +69,7 @@ class CsvFeatureStore:
63
69
  class DbFeatureStore:
64
70
  @staticmethod
65
71
  def persist_rows(rows):
72
+ _import_models()
66
73
  if FeatureSample is not None:
67
74
  objs = []
68
75
  for ip,pl,kw,rt,si,bc,t404,label in rows:
@@ -76,6 +83,7 @@ class DbFeatureStore:
76
83
 
77
84
  @staticmethod
78
85
  def load_matrix():
86
+ _import_models()
79
87
  if FeatureSample is not None:
80
88
  qs = FeatureSample.objects.all().values_list(
81
89
  "path_len","kw_hits","resp_time","status_idx","burst_count","total_404"
@@ -317,23 +325,27 @@ class ModelBlacklistStore:
317
325
 
318
326
  @staticmethod
319
327
  def add_ip(ip_address, reason):
328
+ _import_models()
320
329
  if BlacklistEntry is not None:
321
330
  BlacklistEntry.objects.get_or_create(ip_address=ip_address, defaults={"reason": reason})
322
331
 
323
332
  @staticmethod
324
333
  def is_blocked(ip_address):
334
+ _import_models()
325
335
  if BlacklistEntry is not None:
326
336
  return BlacklistEntry.objects.filter(ip_address=ip_address).exists()
327
337
  return False
328
338
 
329
339
  @staticmethod
330
340
  def get_all():
341
+ _import_models()
331
342
  if BlacklistEntry is not None:
332
343
  return list(BlacklistEntry.objects.values("ip_address", "reason", "created_at"))
333
344
  return []
334
345
 
335
346
  @staticmethod
336
347
  def remove_ip(ip_address):
348
+ _import_models()
337
349
  if BlacklistEntry is not None:
338
350
  BlacklistEntry.objects.filter(ip_address=ip_address).delete()
339
351
 
@@ -343,23 +355,27 @@ class ModelExemptionStore:
343
355
 
344
356
  @staticmethod
345
357
  def add_ip(ip_address, reason=""):
358
+ _import_models()
346
359
  if IPExemption is not None:
347
360
  IPExemption.objects.get_or_create(ip_address=ip_address, defaults={"reason": reason})
348
361
 
349
362
  @staticmethod
350
363
  def is_exempted(ip_address):
364
+ _import_models()
351
365
  if IPExemption is not None:
352
366
  return IPExemption.objects.filter(ip_address=ip_address).exists()
353
367
  return False
354
368
 
355
369
  @staticmethod
356
370
  def get_all():
371
+ _import_models()
357
372
  if IPExemption is not None:
358
373
  return list(IPExemption.objects.values("ip_address", "reason", "created_at"))
359
374
  return []
360
375
 
361
376
  @staticmethod
362
377
  def remove_ip(ip_address):
378
+ _import_models()
363
379
  if IPExemption is not None:
364
380
  IPExemption.objects.filter(ip_address=ip_address).delete()
365
381
 
@@ -369,6 +385,7 @@ class ModelKeywordStore:
369
385
 
370
386
  @staticmethod
371
387
  def add_keyword(keyword, count=1):
388
+ _import_models()
372
389
  if DynamicKeyword is not None:
373
390
  obj, created = DynamicKeyword.objects.get_or_create(keyword=keyword, defaults={"count": count})
374
391
  if not created:
@@ -377,16 +394,19 @@ class ModelKeywordStore:
377
394
 
378
395
  @staticmethod
379
396
  def get_top_keywords(limit=10):
397
+ _import_models()
380
398
  if DynamicKeyword is not None:
381
399
  return list(DynamicKeyword.objects.order_by("-count").values_list("keyword", flat=True)[:limit])
382
400
  return []
383
401
 
384
402
  @staticmethod
385
403
  def remove_keyword(keyword):
404
+ _import_models()
386
405
  if DynamicKeyword is not None:
387
406
  DynamicKeyword.objects.filter(keyword=keyword).delete()
388
407
 
389
408
  @staticmethod
390
409
  def clear_all():
410
+ _import_models()
391
411
  if DynamicKeyword is not None:
392
412
  DynamicKeyword.objects.all().delete()
@@ -17,7 +17,7 @@ from .utils import is_exempt_path
17
17
  from .storage import get_blacklist_store, get_exemption_store, get_keyword_store
18
18
 
19
19
  # ─────────── Configuration ───────────
20
- LOG_PATH = settings.AIWAF_ACCESS_LOG
20
+ LOG_PATH = getattr(settings, 'AIWAF_ACCESS_LOG', None)
21
21
  MODEL_PATH = os.path.join(os.path.dirname(__file__), "resources", "model.pkl")
22
22
 
23
23
  STATIC_KW = [".php", "xmlrpc", "wp-", ".env", ".git", ".bak", "conflg", "shell", "filemanager"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiwaf
3
- Version: 0.1.9.0
3
+ Version: 0.1.9.0.2
4
4
  Summary: AI-powered Web Application Firewall
5
5
  Home-page: https://github.com/aayushgauba/aiwaf
6
6
  Author: Aayush Gauba
@@ -370,6 +370,7 @@ MIDDLEWARE = [
370
370
  ```
371
371
 
372
372
  **Common Issues:**
373
+ - **AppRegistryNotReady Error**: Fixed in v0.1.9.0.1 - update with `pip install --upgrade aiwaf`
373
374
  - Missing Django: `pip install Django`
374
375
  - Old AI-WAF version: `pip install --upgrade aiwaf`
375
376
  - Missing migrations: `python manage.py migrate`
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aiwaf"
3
- version = "0.1.9.0"
3
+ version = "0.1.9.0.2"
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.9.0",
12
+ version="0.1.9.0.2",
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",
@@ -1,19 +0,0 @@
1
- default_app_config = "aiwaf.apps.AiwafConfig"
2
-
3
- __version__ = "0.1.9.0"
4
-
5
- # Import main middleware classes for easier access
6
- try:
7
- from .middleware import (
8
- IPAndKeywordBlockMiddleware,
9
- RateLimitMiddleware,
10
- AIAnomalyMiddleware,
11
- HoneypotTimingMiddleware,
12
- UUIDTamperMiddleware
13
- )
14
- except ImportError as e:
15
- # Handle import errors gracefully during package installation
16
- import sys
17
- if 'runserver' in sys.argv or 'migrate' in sys.argv or 'shell' in sys.argv:
18
- print(f"Warning: Could not import middleware classes: {e}")
19
- print("Tip: Run 'python manage.py aiwaf_diagnose' to troubleshoot")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes