returnguard 1.0.0__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.
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.4
2
+ Name: returnguard
3
+ Version: 1.0.0
4
+ Summary: AI-powered returns fraud detection for retail and eCommerce — score return requests, detect wardrobing, serial returners, and policy abuse
5
+ Home-page: https://github.com/returnguard-py/returnguard
6
+ Author:
7
+ Keywords: returns fraud detection,ecommerce fraud,retail fraud,wardrobing detection,return policy abuse,refund fraud,fraud scoring python,return rate analysis,customer fraud detection,shopify fraud detection
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Intended Audience :: Developers
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: pydantic>=2.0
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: home-page
25
+ Dynamic: keywords
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ # returnguard
31
+
32
+ **AI-powered returns fraud detection for retail and eCommerce** — score return requests, detect wardrobing, serial returners, bot patterns, and policy abuse. No $50K enterprise contract required.
33
+
34
+ [![PyPI version](https://badge.fury.io/py/returnguard.svg)](https://pypi.org/project/returnguard/)
35
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/)
36
+
37
+ ## The Problem
38
+
39
+ Returns fraud costs US retailers $101B/year. AI-generated fraud has "exploded overnight." Enterprise solutions (Happy Returns, Narvar) target only large retail — Shopify has **zero** built-in fraud scoring. Mid-market merchants are on their own.
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install returnguard
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```python
50
+ from returnguard import FraudScorer, ReturnRequest, ReturnReason
51
+ from datetime import datetime, timedelta
52
+
53
+ scorer = FraudScorer(
54
+ return_rate_threshold=0.30,
55
+ high_value_threshold=150.0,
56
+ velocity_limit=3,
57
+ )
58
+
59
+ request = ReturnRequest(
60
+ return_id="RET-001",
61
+ order_id="ORD-5521",
62
+ customer_id="CUST-42",
63
+ sku="SKU-JACKET-XL",
64
+ quantity=1,
65
+ reason=ReturnReason.CHANGED_MIND,
66
+ order_date=datetime.utcnow() - timedelta(days=3),
67
+ order_value=220.00,
68
+ channel="shopify",
69
+ )
70
+
71
+ result = scorer.score(request)
72
+ print(result.risk_level) # RiskLevel.HIGH
73
+ print(result.score) # 0.6
74
+ print(result.signals) # [FraudSignal.WARDROBING]
75
+ print(result.recommended_action) # "Require photo evidence + manual review"
76
+ ```
77
+
78
+ ## Fraud Signals Detected
79
+
80
+ | Signal | Description |
81
+ |---|---|
82
+ | `HIGH_RETURN_RATE` | Customer's return rate exceeds threshold |
83
+ | `WARDROBING` | Use-and-return: changed_mind + < 7 days + high-value item |
84
+ | `VELOCITY` | Too many returns in a short window |
85
+ | `SERIAL_RETURNER` | Customer has been flagged multiple times |
86
+ | `POLICY_ABUSE` | Return submitted after policy window |
87
+
88
+ ## Customer Profile Tracking
89
+
90
+ ```python
91
+ from returnguard import CustomerProfile
92
+
93
+ profile = CustomerProfile(
94
+ customer_id="CUST-42",
95
+ total_orders=20,
96
+ total_returns=8,
97
+ flagged_count=2,
98
+ )
99
+
100
+ result = scorer.score(request, profile=profile)
101
+ # Score accounts for historical return behaviour
102
+ ```
103
+
104
+ ## Risk Levels & Actions
105
+
106
+ | Risk Level | Score | Recommended Action |
107
+ |---|---|---|
108
+ | LOW | 0.0–0.30 | Auto-approve |
109
+ | MEDIUM | 0.30–0.55 | Flag for manual review |
110
+ | HIGH | 0.55–0.75 | Require photo evidence |
111
+ | CRITICAL | 0.75–1.0 | Block + escalate to fraud team |
112
+
113
+ ## Batch Scoring
114
+
115
+ ```python
116
+ from returnguard import batch_score, abatch_score
117
+
118
+ # Sync
119
+ scores = batch_score(requests, scorer.score, max_workers=8)
120
+
121
+ # Async
122
+ scores = await abatch_score(requests, scorer.score, max_concurrency=8)
123
+ ```
124
+
125
+ ## Advanced Features
126
+
127
+ ### Pipeline
128
+
129
+ ```python
130
+ from returnguard import FraudPipeline
131
+
132
+ pipeline = (
133
+ FraudPipeline()
134
+ .filter(lambda s: s.score > 0.5, name="high_risk_only")
135
+ .map(lambda scores: sorted(scores, key=lambda s: -s.score), name="sort_by_risk")
136
+ .with_retry(count=2)
137
+ )
138
+
139
+ high_risk = pipeline.run(all_scores)
140
+ print(pipeline.audit_log())
141
+ ```
142
+
143
+ ### Caching
144
+
145
+ ```python
146
+ from returnguard import FraudCache
147
+
148
+ cache = FraudCache(max_size=1000, ttl_seconds=600)
149
+
150
+ @cache.memoize
151
+ def score_with_cache(request):
152
+ return scorer.score(request)
153
+
154
+ print(cache.stats())
155
+ ```
156
+
157
+ ### Validation
158
+
159
+ ```python
160
+ from returnguard import ReturnValidator, ReturnRule
161
+
162
+ validator = ReturnValidator()
163
+ validator.add_rule(ReturnRule("max_days", 60, "Return window expired"))
164
+ validator.add_rule(ReturnRule("max_order_value", 1000, "High-value item requires manual review"))
165
+
166
+ valid, errors = validator.validate(request)
167
+ ```
168
+
169
+ ### Diff & Trend
170
+
171
+ ```python
172
+ from returnguard import diff_scores, RiskTrend
173
+
174
+ diff = diff_scores(previous_scores, current_scores)
175
+ print(diff.summary()) # {'added': 3, 'removed': 1, 'modified': 2}
176
+
177
+ trend = RiskTrend(window=20)
178
+ for score in historical_scores:
179
+ trend.record(score.score)
180
+ print(trend.trend()) # "increasing"
181
+ print(trend.volatility()) # 0.12
182
+ ```
183
+
184
+ ### Streaming & NDJSON
185
+
186
+ ```python
187
+ from returnguard import stream_scores, scores_to_ndjson
188
+
189
+ for score in stream_scores(results):
190
+ process(score)
191
+
192
+ for line in scores_to_ndjson(results):
193
+ file.write(line)
194
+ ```
195
+
196
+ ### Audit Log
197
+
198
+ ```python
199
+ from returnguard import AuditLog
200
+
201
+ log = AuditLog()
202
+ log.record("scored", "RET-001", detail="risk=high")
203
+ log.record("blocked", "RET-001")
204
+ entries = log.export()
205
+ ```
206
+
207
+ ## License
208
+
209
+ MIT
@@ -0,0 +1,180 @@
1
+ # returnguard
2
+
3
+ **AI-powered returns fraud detection for retail and eCommerce** — score return requests, detect wardrobing, serial returners, bot patterns, and policy abuse. No $50K enterprise contract required.
4
+
5
+ [![PyPI version](https://badge.fury.io/py/returnguard.svg)](https://pypi.org/project/returnguard/)
6
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/)
7
+
8
+ ## The Problem
9
+
10
+ Returns fraud costs US retailers $101B/year. AI-generated fraud has "exploded overnight." Enterprise solutions (Happy Returns, Narvar) target only large retail — Shopify has **zero** built-in fraud scoring. Mid-market merchants are on their own.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install returnguard
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```python
21
+ from returnguard import FraudScorer, ReturnRequest, ReturnReason
22
+ from datetime import datetime, timedelta
23
+
24
+ scorer = FraudScorer(
25
+ return_rate_threshold=0.30,
26
+ high_value_threshold=150.0,
27
+ velocity_limit=3,
28
+ )
29
+
30
+ request = ReturnRequest(
31
+ return_id="RET-001",
32
+ order_id="ORD-5521",
33
+ customer_id="CUST-42",
34
+ sku="SKU-JACKET-XL",
35
+ quantity=1,
36
+ reason=ReturnReason.CHANGED_MIND,
37
+ order_date=datetime.utcnow() - timedelta(days=3),
38
+ order_value=220.00,
39
+ channel="shopify",
40
+ )
41
+
42
+ result = scorer.score(request)
43
+ print(result.risk_level) # RiskLevel.HIGH
44
+ print(result.score) # 0.6
45
+ print(result.signals) # [FraudSignal.WARDROBING]
46
+ print(result.recommended_action) # "Require photo evidence + manual review"
47
+ ```
48
+
49
+ ## Fraud Signals Detected
50
+
51
+ | Signal | Description |
52
+ |---|---|
53
+ | `HIGH_RETURN_RATE` | Customer's return rate exceeds threshold |
54
+ | `WARDROBING` | Use-and-return: changed_mind + < 7 days + high-value item |
55
+ | `VELOCITY` | Too many returns in a short window |
56
+ | `SERIAL_RETURNER` | Customer has been flagged multiple times |
57
+ | `POLICY_ABUSE` | Return submitted after policy window |
58
+
59
+ ## Customer Profile Tracking
60
+
61
+ ```python
62
+ from returnguard import CustomerProfile
63
+
64
+ profile = CustomerProfile(
65
+ customer_id="CUST-42",
66
+ total_orders=20,
67
+ total_returns=8,
68
+ flagged_count=2,
69
+ )
70
+
71
+ result = scorer.score(request, profile=profile)
72
+ # Score accounts for historical return behaviour
73
+ ```
74
+
75
+ ## Risk Levels & Actions
76
+
77
+ | Risk Level | Score | Recommended Action |
78
+ |---|---|---|
79
+ | LOW | 0.0–0.30 | Auto-approve |
80
+ | MEDIUM | 0.30–0.55 | Flag for manual review |
81
+ | HIGH | 0.55–0.75 | Require photo evidence |
82
+ | CRITICAL | 0.75–1.0 | Block + escalate to fraud team |
83
+
84
+ ## Batch Scoring
85
+
86
+ ```python
87
+ from returnguard import batch_score, abatch_score
88
+
89
+ # Sync
90
+ scores = batch_score(requests, scorer.score, max_workers=8)
91
+
92
+ # Async
93
+ scores = await abatch_score(requests, scorer.score, max_concurrency=8)
94
+ ```
95
+
96
+ ## Advanced Features
97
+
98
+ ### Pipeline
99
+
100
+ ```python
101
+ from returnguard import FraudPipeline
102
+
103
+ pipeline = (
104
+ FraudPipeline()
105
+ .filter(lambda s: s.score > 0.5, name="high_risk_only")
106
+ .map(lambda scores: sorted(scores, key=lambda s: -s.score), name="sort_by_risk")
107
+ .with_retry(count=2)
108
+ )
109
+
110
+ high_risk = pipeline.run(all_scores)
111
+ print(pipeline.audit_log())
112
+ ```
113
+
114
+ ### Caching
115
+
116
+ ```python
117
+ from returnguard import FraudCache
118
+
119
+ cache = FraudCache(max_size=1000, ttl_seconds=600)
120
+
121
+ @cache.memoize
122
+ def score_with_cache(request):
123
+ return scorer.score(request)
124
+
125
+ print(cache.stats())
126
+ ```
127
+
128
+ ### Validation
129
+
130
+ ```python
131
+ from returnguard import ReturnValidator, ReturnRule
132
+
133
+ validator = ReturnValidator()
134
+ validator.add_rule(ReturnRule("max_days", 60, "Return window expired"))
135
+ validator.add_rule(ReturnRule("max_order_value", 1000, "High-value item requires manual review"))
136
+
137
+ valid, errors = validator.validate(request)
138
+ ```
139
+
140
+ ### Diff & Trend
141
+
142
+ ```python
143
+ from returnguard import diff_scores, RiskTrend
144
+
145
+ diff = diff_scores(previous_scores, current_scores)
146
+ print(diff.summary()) # {'added': 3, 'removed': 1, 'modified': 2}
147
+
148
+ trend = RiskTrend(window=20)
149
+ for score in historical_scores:
150
+ trend.record(score.score)
151
+ print(trend.trend()) # "increasing"
152
+ print(trend.volatility()) # 0.12
153
+ ```
154
+
155
+ ### Streaming & NDJSON
156
+
157
+ ```python
158
+ from returnguard import stream_scores, scores_to_ndjson
159
+
160
+ for score in stream_scores(results):
161
+ process(score)
162
+
163
+ for line in scores_to_ndjson(results):
164
+ file.write(line)
165
+ ```
166
+
167
+ ### Audit Log
168
+
169
+ ```python
170
+ from returnguard import AuditLog
171
+
172
+ log = AuditLog()
173
+ log.record("scored", "RET-001", detail="risk=high")
174
+ log.record("blocked", "RET-001")
175
+ entries = log.export()
176
+ ```
177
+
178
+ ## License
179
+
180
+ MIT
@@ -0,0 +1,68 @@
1
+ """returnguard — AI-powered returns fraud detection for retail and eCommerce."""
2
+ from returnguard.models import (
3
+ CustomerProfile,
4
+ FraudScore,
5
+ FraudSignal,
6
+ ReturnRequest,
7
+ ReturnReason,
8
+ RiskLevel,
9
+ )
10
+ from returnguard.scorer import FraudScorer
11
+ from returnguard.exceptions import (
12
+ ProfileError,
13
+ ReturnGuardError,
14
+ ScoringError,
15
+ ValidationError,
16
+ )
17
+ from returnguard.advanced import (
18
+ AuditLog,
19
+ CancellationToken,
20
+ FraudCache,
21
+ FraudDiff,
22
+ FraudPipeline,
23
+ FraudProfiler,
24
+ PIIScrubber,
25
+ RateLimiter,
26
+ ReturnRule,
27
+ ReturnValidator,
28
+ RiskTrend,
29
+ abatch_score,
30
+ batch_score,
31
+ diff_scores,
32
+ scores_to_ndjson,
33
+ stream_scores,
34
+ )
35
+
36
+ __version__ = "1.0.0"
37
+ __all__ = [
38
+ # Core
39
+ "FraudScorer",
40
+ "FraudScore",
41
+ "FraudSignal",
42
+ "ReturnRequest",
43
+ "ReturnReason",
44
+ "RiskLevel",
45
+ "CustomerProfile",
46
+ # Exceptions
47
+ "ReturnGuardError",
48
+ "ScoringError",
49
+ "ProfileError",
50
+ "ValidationError",
51
+ # Advanced
52
+ "FraudCache",
53
+ "FraudPipeline",
54
+ "ReturnValidator",
55
+ "ReturnRule",
56
+ "RateLimiter",
57
+ "CancellationToken",
58
+ "batch_score",
59
+ "abatch_score",
60
+ "FraudProfiler",
61
+ "RiskTrend",
62
+ "stream_scores",
63
+ "scores_to_ndjson",
64
+ "FraudDiff",
65
+ "diff_scores",
66
+ "AuditLog",
67
+ "PIIScrubber",
68
+ ]