Spaces:
Running
Running
feat(models): expand SubActionModel with all transactional and promotional subactions per Apple ILMessageFilterSubAction
Browse files- README.md +10 -0
- app.py +3 -43
- models/enums.py +38 -0
- models/models.py +25 -0
README.md
CHANGED
@@ -9,3 +9,13 @@ license: apache-2.0
|
|
9 |
---
|
10 |
|
11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
---
|
10 |
|
11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
12 |
+
|
13 |
+
## Organisation des modèles
|
14 |
+
|
15 |
+
Les modèles Pydantic (`BaseModel`) sont désormais définis dans `models/models.py` et les énumérations (`Enum`) dans `models/enums.py`. Le fichier `app.py` importe ces classes pour la logique de l'API.
|
16 |
+
|
17 |
+
- `models/models.py` : Contient les modèles de données (MessageModel, QueryModel, AppModel, InputModel, OutputModel, ReportModel).
|
18 |
+
- `models/enums.py` : Contient les énumérations (ActionModel, SubActionModel).
|
19 |
+
|
20 |
+
Cela facilite la réutilisation et la maintenance du code.
|
21 |
+
|
app.py
CHANGED
@@ -6,8 +6,6 @@ import re
|
|
6 |
import httpx
|
7 |
from fastapi import FastAPI
|
8 |
from fastapi.responses import JSONResponse, FileResponse
|
9 |
-
from pydantic import BaseModel
|
10 |
-
from enum import Enum
|
11 |
from transformers import pipeline
|
12 |
from phishing_datasets import submit_entry
|
13 |
from url_tools import extract_urls, resolve_short_url, extract_domain_from_url
|
@@ -15,7 +13,8 @@ from urlscan_client import UrlscanClient
|
|
15 |
import requests
|
16 |
from mnemonic_attack import find_confusable_brand
|
17 |
|
18 |
-
|
|
|
19 |
|
20 |
app = FastAPI()
|
21 |
urlscan = UrlscanClient()
|
@@ -25,45 +24,11 @@ for handler in logging.root.handlers[:]:
|
|
25 |
logging.root.removeHandler(handler)
|
26 |
|
27 |
logging.basicConfig(
|
28 |
-
level=logging.
|
29 |
format='%(levelname)s: %(asctime)s %(message)s',
|
30 |
handlers=[logging.StreamHandler(sys.stdout)]
|
31 |
)
|
32 |
|
33 |
-
class MessageModel(BaseModel):
|
34 |
-
text: str
|
35 |
-
|
36 |
-
class QueryModel(BaseModel):
|
37 |
-
sender: str
|
38 |
-
message: MessageModel
|
39 |
-
|
40 |
-
class AppModel(BaseModel):
|
41 |
-
version: str
|
42 |
-
|
43 |
-
class InputModel(BaseModel):
|
44 |
-
_version: int
|
45 |
-
query: QueryModel
|
46 |
-
app: AppModel
|
47 |
-
|
48 |
-
class ActionModel(Enum):
|
49 |
-
# Insufficient information to determine an action to take. In a query response, has the effect of allowing the message to be shown normally.
|
50 |
-
NONE = 0
|
51 |
-
# Allow the message to be shown normally.
|
52 |
-
ALLOW = 1
|
53 |
-
# Prevent the message from being shown normally, filtered as Junk message.
|
54 |
-
JUNK = 2
|
55 |
-
# Prevent the message from being shown normally, filtered as Promotional message.
|
56 |
-
PROMOTION = 3
|
57 |
-
# Prevent the message from being shown normally, filtered as Transactional message.
|
58 |
-
TRANSACTION = 4
|
59 |
-
|
60 |
-
class SubActionModel(Enum):
|
61 |
-
NONE = 0
|
62 |
-
|
63 |
-
class OutputModel(BaseModel):
|
64 |
-
action: ActionModel
|
65 |
-
sub_action: SubActionModel
|
66 |
-
|
67 |
pipe = pipeline(task="text-classification", model="mrm8488/bert-tiny-finetuned-sms-spam-detection")
|
68 |
|
69 |
@app.get("/.well-known/apple-app-site-association", include_in_schema=False)
|
@@ -117,7 +82,6 @@ def predict(model: InputModel) -> OutputModel:
|
|
117 |
case 'promotion':
|
118 |
return OutputModel(action=ActionModel.PROMOTION, sub_action=SubActionModel.NONE)
|
119 |
|
120 |
-
|
121 |
# Brand usurpation detection using confusables
|
122 |
confusable_brand = find_confusable_brand(text)
|
123 |
if confusable_brand:
|
@@ -197,10 +161,6 @@ def predict(model: InputModel) -> OutputModel:
|
|
197 |
logging.info(f"[FINAL ACTION] {action}")
|
198 |
return OutputModel(action=action, sub_action=SubActionModel.NONE)
|
199 |
|
200 |
-
class ReportModel(BaseModel):
|
201 |
-
sender: str
|
202 |
-
message: str
|
203 |
-
|
204 |
@app.post("/report")
|
205 |
def report(model: ReportModel):
|
206 |
submit_entry(model.sender, model.message)
|
|
|
6 |
import httpx
|
7 |
from fastapi import FastAPI
|
8 |
from fastapi.responses import JSONResponse, FileResponse
|
|
|
|
|
9 |
from transformers import pipeline
|
10 |
from phishing_datasets import submit_entry
|
11 |
from url_tools import extract_urls, resolve_short_url, extract_domain_from_url
|
|
|
13 |
import requests
|
14 |
from mnemonic_attack import find_confusable_brand
|
15 |
|
16 |
+
from models.models import MessageModel, QueryModel, AppModel, InputModel, OutputModel, ReportModel
|
17 |
+
from models.enums import ActionModel, SubActionModel
|
18 |
|
19 |
app = FastAPI()
|
20 |
urlscan = UrlscanClient()
|
|
|
24 |
logging.root.removeHandler(handler)
|
25 |
|
26 |
logging.basicConfig(
|
27 |
+
level=logging.INFO,
|
28 |
format='%(levelname)s: %(asctime)s %(message)s',
|
29 |
handlers=[logging.StreamHandler(sys.stdout)]
|
30 |
)
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
pipe = pipeline(task="text-classification", model="mrm8488/bert-tiny-finetuned-sms-spam-detection")
|
33 |
|
34 |
@app.get("/.well-known/apple-app-site-association", include_in_schema=False)
|
|
|
82 |
case 'promotion':
|
83 |
return OutputModel(action=ActionModel.PROMOTION, sub_action=SubActionModel.NONE)
|
84 |
|
|
|
85 |
# Brand usurpation detection using confusables
|
86 |
confusable_brand = find_confusable_brand(text)
|
87 |
if confusable_brand:
|
|
|
161 |
logging.info(f"[FINAL ACTION] {action}")
|
162 |
return OutputModel(action=action, sub_action=SubActionModel.NONE)
|
163 |
|
|
|
|
|
|
|
|
|
164 |
@app.post("/report")
|
165 |
def report(model: ReportModel):
|
166 |
submit_entry(model.sender, model.message)
|
models/enums.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from enum import Enum
|
2 |
+
|
3 |
+
class ActionModel(Enum):
|
4 |
+
"""
|
5 |
+
Enum representing the main actions for message filtering, according to Apple's ILMessageFilterAction:
|
6 |
+
https://developer.apple.com/documentation/identitylookup/ilmessagefilteraction
|
7 |
+
"""
|
8 |
+
NONE = 0 # No action determined, message is handled normally
|
9 |
+
ALLOW = 1 # Allow the message to be shown
|
10 |
+
JUNK = 2 # Filter as junk
|
11 |
+
PROMOTION = 3 # Filter as promotion (extension, not in Apple doc)
|
12 |
+
TRANSACTION = 4 # Filter as transaction (extension, not in Apple doc)
|
13 |
+
# Apple only defines NONE, ALLOW, JUNK; PROMOTION and TRANSACTION are for extension
|
14 |
+
|
15 |
+
class SubActionModel(Enum):
|
16 |
+
"""
|
17 |
+
Enum representing sub-actions for message filtering, including all transactional and promotional subactions as described in Apple's documentation:
|
18 |
+
https://developer.apple.com/documentation/identitylookup/ilmessagefiltersubaction
|
19 |
+
"""
|
20 |
+
# General
|
21 |
+
NONE = 0 # Allows the system to show the message unfiltered due to insufficient information to determine an action.
|
22 |
+
REPORT_JUNK = 1 # Report as junk
|
23 |
+
|
24 |
+
# Transactional Subactions
|
25 |
+
TRANSACTIONAL_OTHERS = 100 # Filtered as an Others message.
|
26 |
+
TRANSACTIONAL_FINANCE = 101 # Filtered as a Finance message.
|
27 |
+
TRANSACTIONAL_ORDERS = 102 # Filtered as an Orders (eCommerce) message.
|
28 |
+
TRANSACTIONAL_REMINDERS = 103 # Filtered as a Reminder message.
|
29 |
+
TRANSACTIONAL_HEALTH = 104 # Filtered as a Health message.
|
30 |
+
TRANSACTIONAL_WEATHER = 105 # Filtered as a Weather message.
|
31 |
+
TRANSACTIONAL_CARRIER = 106 # Filtered as a Carrier message.
|
32 |
+
TRANSACTIONAL_REWARDS = 107 # Filtered as a Rewards message.
|
33 |
+
TRANSACTIONAL_PUBLIC_SERVICES = 108 # Filtered as a Government/Public Services message.
|
34 |
+
|
35 |
+
# Promotional Subactions
|
36 |
+
PROMOTIONAL_OTHERS = 200 # Filtered as an Others message.
|
37 |
+
PROMOTIONAL_OFFERS = 201 # Filtered as an Offers message.
|
38 |
+
PROMOTIONAL_COUPONS = 202 # Filtered as a Coupons message.
|
models/models.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from enum import Enum
|
3 |
+
|
4 |
+
class MessageModel(BaseModel):
|
5 |
+
text: str
|
6 |
+
|
7 |
+
class QueryModel(BaseModel):
|
8 |
+
sender: str
|
9 |
+
message: MessageModel
|
10 |
+
|
11 |
+
class AppModel(BaseModel):
|
12 |
+
version: str
|
13 |
+
|
14 |
+
class InputModel(BaseModel):
|
15 |
+
_version: int
|
16 |
+
query: QueryModel
|
17 |
+
app: AppModel
|
18 |
+
|
19 |
+
class OutputModel(BaseModel):
|
20 |
+
action: 'ActionModel'
|
21 |
+
sub_action: 'SubActionModel'
|
22 |
+
|
23 |
+
class ReportModel(BaseModel):
|
24 |
+
sender: str
|
25 |
+
message: str
|