Prak2005 commited on
Commit
4bb159b
Β·
verified Β·
1 Parent(s): f9c0c76

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +352 -310
app.py CHANGED
@@ -7,10 +7,6 @@ from datetime import datetime, timedelta
7
  from typing import Dict, Any, List, Optional
8
  from pydantic import BaseModel, Field
9
  import gradio as gr
10
- from crewai import Agent, Crew, Process, Task, LLM
11
- from crewai.agent import agent
12
- from crewai.task import task
13
- from crewai.crew import crew, CrewBase
14
 
15
  # Setup logging
16
  logging.basicConfig(
@@ -19,12 +15,6 @@ logging.basicConfig(
19
  )
20
  logger = logging.getLogger(__name__)
21
 
22
- # Initialize LLM (will use environment variable)
23
- llm = LLM(
24
- model="gemini/gemini-2.0-flash-exp", # or any other model
25
- api_key=os.getenv("GEMINI_API_KEY", "dummy-key-for-testing"),
26
- )
27
-
28
  # ========== DATA MODELS ==========
29
  class UserVerification(BaseModel):
30
  user_id: str = Field(..., description="User ID")
@@ -87,181 +77,174 @@ class MockDatabase:
87
  # Initialize mock database
88
  mock_db = MockDatabase()
89
 
90
- # ========== CREW CLASS ==========
91
- class AntiScalpingCrew(CrewBase):
92
- """Anti-Scalping Ticketing System Crew"""
93
-
94
- @agent
95
- def user_verification_agent(self) -> Agent:
96
- return Agent(
97
- role="User Verification Specialist",
98
- goal="Verify user identity and assess verification level for ticket purchases",
99
- backstory="""You are an expert in Know Your Customer (KYC) processes and identity
100
- verification. You assess user documentation, verify identities, and assign risk scores
101
- based on user history and verification completeness. You ensure only legitimate users
102
- can purchase tickets while maintaining a smooth user experience.""",
103
- llm=llm,
104
- verbose=True
105
- )
106
-
107
- @agent
108
- def scalping_detection_agent(self) -> Agent:
109
- return Agent(
110
- role="Scalping Detection Analyst",
111
- goal="Detect and prevent ticket scalping through behavioral analysis",
112
- backstory="""You are a specialized analyst focused on identifying scalping patterns.
113
- You analyze purchase velocity, IP addresses, buying patterns, and other behavioral
114
- indicators to detect potential scalpers. Your expertise helps maintain fair ticket
115
- distribution and prevents automated bot purchases.""",
116
- llm=llm,
117
- verbose=True
118
- )
119
-
120
- @agent
121
- def dynamic_pricing_agent(self) -> Agent:
122
- return Agent(
123
- role="Dynamic Pricing Strategist",
124
- goal="Calculate fair resale prices based on demand while preventing price gouging",
125
- backstory="""You are an expert in market dynamics and pricing strategies. You analyze
126
- demand levels, market conditions, and event popularity to recommend fair resale prices.
127
- You balance market forces with consumer protection, ensuring prices reflect true demand
128
- without enabling exploitative pricing.""",
129
- llm=llm,
130
- verbose=True
131
- )
132
-
133
- @agent
134
- def resale_monitor_agent(self) -> Agent:
135
- return Agent(
136
- role="Resale Compliance Officer",
137
- goal="Monitor and enforce resale policies to ensure fair ticket distribution",
138
- backstory="""You are responsible for ensuring all ticket resales comply with platform
139
- policies and local regulations. You monitor resale prices, frequency, and patterns to
140
- prevent policy violations. Your work ensures the secondary ticket market remains fair
141
- and accessible to genuine fans.""",
142
- llm=llm,
143
- verbose=True
144
- )
145
-
146
- @task
147
- def verify_user_task(self) -> Task:
148
- return Task(
149
- description="""Verify the user with the following details:
150
- - Name: {name}
151
- - Email: {email}
152
- - User ID: {user_id}
153
-
154
- Perform KYC verification checks:
155
- 1. Validate email format and domain
156
- 2. Check if name appears legitimate
157
- 3. Assign verification level (basic/standard/premium)
158
- 4. Calculate risk score (0-1) based on user patterns
159
- 5. Determine if user is verified for ticket purchase
160
-
161
- Consider factors like email domain reputation, name consistency, and any red flags.""",
162
- agent=self.user_verification_agent(),
163
- expected_output="UserVerification model with complete verification details"
164
- )
165
-
166
- @task
167
- def detect_scalping_task(self) -> Task:
168
- return Task(
169
- description="""Analyze user behavior for scalping indicators:
170
- - User ID: {user_id}
171
- - Current purchase attempt for event: {event_name}
172
- - Ticket quantity requested: {ticket_quantity}
173
-
174
- Check for scalping patterns:
175
- 1. Purchase velocity (multiple purchases in short time)
176
- 2. IP address duplication (multiple accounts from same IP)
177
- 3. Unusual buying patterns
178
- 4. Bot-like behavior indicators
179
- 5. Historical resale frequency
180
-
181
- Use the user's purchase history and behavioral data to determine scalping likelihood.""",
182
- agent=self.scalping_detection_agent(),
183
- expected_output="ScalpingDetection model with detection results and confidence score"
184
  )
185
-
186
- @task
187
- def calculate_pricing_task(self) -> Task:
188
- return Task(
189
- description="""Calculate recommended resale price for:
190
- - Event: {event_name}
191
- - Original ticket price: ${original_price}
192
- - Current demand level: {demand_level}
193
- - Ticket type: {ticket_type}
194
-
195
- Pricing guidelines:
196
- - Low demand: Allow 10-20% below original price (acknowledge loss)
197
- - Medium demand: Allow up to 25% markup
198
- - High demand: Allow up to 50% markup (with profit margin note)
199
-
200
- Consider market factors and ensure pricing remains fair while reflecting demand.""",
201
- agent=self.dynamic_pricing_agent(),
202
- expected_output="PricingRecommendation model with price calculations and justification"
 
 
 
 
 
 
 
 
 
203
  )
204
-
205
- @task
206
- def monitor_compliance_task(self) -> Task:
207
- return Task(
208
- description="""Evaluate resale compliance for:
209
- - User ID: {user_id}
210
- - Proposed resale price: ${proposed_resale_price}
211
- - Original price: ${original_price}
212
- - User's resale history from scalping detection
213
-
214
- Check against policies:
215
- 1. Maximum 2x original price cap
216
- 2. No more than 4 resales per month
217
- 3. No bulk resales (>4 tickets at once)
218
- 4. Cooling period between purchases and resales
219
-
220
- Determine if resale should be allowed and provide recommendations.""",
221
- agent=self.resale_monitor_agent(),
222
- context=[self.detect_scalping_task(), self.calculate_pricing_task()],
223
- expected_output="ResaleCompliance model with compliance decision and violations"
224
  )
225
-
226
- @task
227
- def final_report_task(self) -> Task:
228
- return Task(
229
- description="""Create comprehensive system report combining all findings:
230
- 1. User verification results
231
- 2. Scalping detection analysis
232
- 3. Pricing recommendations
233
- 4. Compliance evaluation
234
-
235
- Provide final decision on whether to:
236
- - Allow ticket purchase
237
- - Allow ticket resale
238
- - Apply any restrictions
239
- - Recommend specific actions
240
-
241
- Ensure report is clear and actionable.""",
242
- agent=self.resale_monitor_agent(),
243
- context=[
244
- self.verify_user_task(),
245
- self.detect_scalping_task(),
246
- self.calculate_pricing_task(),
247
- self.monitor_compliance_task()
248
- ],
249
- expected_output="Complete TicketingSystemReport with all components and final decision"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  )
251
-
252
- @crew
253
- def crew(self) -> Crew:
254
- return Crew(
255
- agents=self.agents,
256
- tasks=self.tasks,
257
- process=Process.sequential,
258
- verbose=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  )
260
 
261
  # ========== MAIN APPLICATION ==========
262
  class AntiScalpingSystem:
263
  def __init__(self):
264
- self.crew_instance = AntiScalpingCrew()
 
 
 
265
 
266
  def process_ticket_transaction(
267
  self,
@@ -277,76 +260,67 @@ class AntiScalpingSystem:
277
  ) -> Dict[str, Any]:
278
  """Process a ticket transaction through the anti-scalping system"""
279
 
280
- # Simulate some purchase history for the user
281
- purchase_count = mock_db.get_user_purchases(user_id)
282
- mock_db.user_purchase_history[user_id] = purchase_count + 1
283
-
284
- inputs = {
285
- "name": name,
286
- "email": email,
287
- "user_id": user_id,
288
- "event_name": event_name,
289
- "ticket_type": ticket_type,
290
- "ticket_quantity": ticket_quantity,
291
- "original_price": original_price,
292
- "demand_level": demand_level,
293
- "proposed_resale_price": proposed_resale_price
294
- }
295
-
296
  try:
297
- result = self.crew_instance.crew().kickoff(inputs=inputs)
 
 
 
 
 
 
 
 
 
 
 
298
 
299
- # Parse the result and create a structured response
300
- if hasattr(result, 'dict'):
301
- return result.dict()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  else:
303
- # Create a mock response for demo purposes
304
- return self._create_mock_response(inputs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  except Exception as e:
306
  logger.error(f"Error processing transaction: {e}")
307
- return self._create_mock_response(inputs)
308
 
309
- def _create_mock_response(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
310
- """Create a mock response for demo purposes"""
311
- is_scalper = random.random() > 0.7
312
- price_ratio = inputs["proposed_resale_price"] / inputs["original_price"]
313
-
314
  return {
315
- "verification": {
316
- "user_id": inputs["user_id"],
317
- "name": inputs["name"],
318
- "email": inputs["email"],
319
- "is_verified": not is_scalper,
320
- "verification_level": "standard" if not is_scalper else "basic",
321
- "risk_score": 0.3 if not is_scalper else 0.8
322
- },
323
- "scalping_detection": {
324
- "is_scalper": is_scalper,
325
- "confidence": 0.85 if is_scalper else 0.15,
326
- "flags": ["rapid_purchases", "multiple_ips"] if is_scalper else [],
327
- "purchase_velocity": random.randint(1, 10),
328
- "ip_duplicates": random.randint(1, 5)
329
- },
330
- "pricing": {
331
- "original_price": inputs["original_price"],
332
- "recommended_resale_price": inputs["proposed_resale_price"],
333
- "demand_level": inputs["demand_level"],
334
- "price_adjustment_reason": f"Based on {inputs['demand_level']} demand",
335
- "profit_margin": (price_ratio - 1) * 100 if price_ratio > 1 else None,
336
- "loss_percentage": (1 - price_ratio) * 100 if price_ratio < 1 else None
337
- },
338
- "compliance": {
339
- "is_compliant": price_ratio <= 2 and not is_scalper,
340
- "violations": ["price_exceeds_2x"] if price_ratio > 2 else [],
341
- "resale_allowed": price_ratio <= 2 and not is_scalper,
342
- "max_allowed_price": inputs["original_price"] * 2,
343
- "recommendation": "Proceed with resale" if price_ratio <= 2 and not is_scalper else "Block transaction"
344
- },
345
- "final_decision": "APPROVED" if price_ratio <= 2 and not is_scalper else "DENIED",
346
- "action_items": [
347
- "Process ticket resale" if price_ratio <= 2 and not is_scalper else "Block transaction",
348
- "Monitor future activity" if is_scalper else "No additional action required"
349
- ]
350
  }
351
 
352
  # ========== GRADIO INTERFACE ==========
@@ -361,14 +335,18 @@ def create_interface():
361
 
362
  # Validate inputs
363
  if not all([name, email, user_id, event_name]):
364
- return "Please fill in all required fields"
365
 
366
  try:
367
- original_price = float(original_price)
368
- proposed_resale_price = float(proposed_resale_price)
369
- ticket_quantity = int(ticket_quantity)
370
- except ValueError:
371
- return "Please enter valid numbers for prices and quantity"
 
 
 
 
372
 
373
  # Process through the system
374
  result = system.process_ticket_transaction(
@@ -383,95 +361,159 @@ def create_interface():
383
  proposed_resale_price=proposed_resale_price
384
  )
385
 
 
 
 
 
386
  # Format the output
 
 
387
  output = f"""
388
- # 🎫 Anti-Scalping System Report
 
 
 
 
389
 
390
  ## πŸ‘€ User Verification
391
- - **User ID**: {result['verification']['user_id']}
 
 
392
  - **Verified**: {'βœ… Yes' if result['verification']['is_verified'] else '❌ No'}
393
- - **Risk Score**: {result['verification']['risk_score']:.2f}
394
- - **Verification Level**: {result['verification']['verification_level']}
395
 
396
- ## πŸ” Scalping Detection
397
- - **Scalper Detected**: {'🚨 Yes' if result['scalping_detection']['is_scalper'] else 'βœ… No'}
398
- - **Confidence**: {result['scalping_detection']['confidence']:.2%}
399
  - **Purchase Velocity**: {result['scalping_detection']['purchase_velocity']} purchases/hour
400
- - **IP Duplicates**: {result['scalping_detection']['ip_duplicates']}
401
- - **Flags**: {', '.join(result['scalping_detection']['flags']) if result['scalping_detection']['flags'] else 'None'}
402
 
403
- ## πŸ’° Pricing Analysis
404
  - **Original Price**: ${result['pricing']['original_price']:.2f}
405
- - **Proposed Resale**: ${result['pricing']['recommended_resale_price']:.2f}
406
- - **Demand Level**: {result['pricing']['demand_level']}
 
407
  - **Price Ratio**: {result['pricing']['recommended_resale_price']/result['pricing']['original_price']:.2f}x
408
  """
409
 
410
  if result['pricing'].get('profit_margin'):
411
- output += f"- **Profit Margin**: {result['pricing']['profit_margin']:.1f}%\n"
412
  elif result['pricing'].get('loss_percentage'):
413
- output += f"- **Loss**: {result['pricing']['loss_percentage']:.1f}%\n"
414
-
415
- output += f"""
416
- ## βœ… Compliance Check
417
- - **Compliant**: {'βœ… Yes' if result['compliance']['is_compliant'] else '❌ No'}
418
- - **Resale Allowed**: {'βœ… Yes' if result['compliance']['resale_allowed'] else '❌ No'}
419
- - **Max Allowed Price**: ${result['compliance']['max_allowed_price']:.2f}
420
- - **Violations**: {', '.join(result['compliance']['violations']) if result['compliance']['violations'] else 'None'}
421
 
422
- ## πŸ“‹ Final Decision: **{result['final_decision']}**
 
 
 
 
 
423
 
424
- ### Action Items:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  """
426
- for action in result['action_items']:
427
- output += f"- {action}\n"
428
 
429
  return output
430
 
431
- # Create Gradio interface
432
- interface = gr.Interface(
433
- fn=process_transaction,
434
- inputs=[
435
- gr.Textbox(label="Full Name", placeholder="John Doe"),
436
- gr.Textbox(label="Email", placeholder="john@example.com"),
437
- gr.Textbox(label="User ID", placeholder="USER123"),
438
- gr.Textbox(label="Event Name", placeholder="Taylor Swift - Eras Tour"),
439
- gr.Dropdown(
440
- label="Ticket Type",
441
- choices=["General Admission", "VIP", "Premium", "Standard"],
442
- value="Standard"
443
- ),
444
- gr.Number(label="Ticket Quantity", value=1, minimum=1, maximum=10),
445
- gr.Number(label="Original Ticket Price ($)", value=100),
446
- gr.Radio(
447
- label="Current Demand Level",
448
- choices=["low", "medium", "high"],
449
- value="medium"
450
- ),
451
- gr.Number(label="Proposed Resale Price ($)", value=150)
452
- ],
453
- outputs=gr.Markdown(),
454
  title="🎫 Anti-Scalping Ticketing System",
455
- description="""
456
- This AI-powered system helps prevent ticket scalping by:
457
- - Verifying user identity and history
458
- - Detecting scalping patterns and behaviors
459
- - Recommending fair resale prices based on demand
460
- - Ensuring compliance with anti-scalping policies
461
-
462
- Enter the ticket transaction details below to see if it should be approved.
463
- """,
464
- examples=[
465
- ["John Smith", "john@gmail.com", "USER001", "Taylor Swift - Eras Tour", "VIP", 2, 500, "high", 750],
466
- ["Jane Doe", "jane@company.com", "USER002", "NBA Finals Game 7", "Premium", 4, 300, "high", 1200],
467
- ["Bob Wilson", "bob@email.com", "USER003", "Local Concert", "General Admission", 1, 50, "low", 40],
468
- ],
469
- theme=gr.themes.Soft()
470
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
 
472
  return interface
473
 
474
  # Main execution
475
  if __name__ == "__main__":
476
  interface = create_interface()
477
- interface.launch(share=True)
 
 
 
 
 
 
7
  from typing import Dict, Any, List, Optional
8
  from pydantic import BaseModel, Field
9
  import gradio as gr
 
 
 
 
10
 
11
  # Setup logging
12
  logging.basicConfig(
 
15
  )
16
  logger = logging.getLogger(__name__)
17
 
 
 
 
 
 
 
18
  # ========== DATA MODELS ==========
19
  class UserVerification(BaseModel):
20
  user_id: str = Field(..., description="User ID")
 
77
  # Initialize mock database
78
  mock_db = MockDatabase()
79
 
80
+ # ========== VERIFICATION LOGIC ==========
81
+ class UserVerificationEngine:
82
+ @staticmethod
83
+ def verify_user(name: str, email: str, user_id: str) -> UserVerification:
84
+ """Verify user based on provided information"""
85
+
86
+ # Email validation
87
+ email_valid = "@" in email and "." in email.split("@")[-1]
88
+
89
+ # Name validation (basic check)
90
+ name_valid = len(name.strip()) >= 2 and not any(char.isdigit() for char in name)
91
+
92
+ # Risk assessment
93
+ risk_factors = []
94
+ if not email_valid:
95
+ risk_factors.append("invalid_email")
96
+ if not name_valid:
97
+ risk_factors.append("suspicious_name")
98
+ if email.endswith(('.temp', '.fake', '.test')):
99
+ risk_factors.append("temporary_email")
100
+
101
+ risk_score = min(0.9, len(risk_factors) * 0.3 + random.uniform(0.1, 0.3))
102
+ is_verified = risk_score < 0.5 and email_valid and name_valid
103
+
104
+ verification_level = "premium" if risk_score < 0.2 else "standard" if risk_score < 0.5 else "basic"
105
+
106
+ return UserVerification(
107
+ user_id=user_id,
108
+ name=name,
109
+ email=email,
110
+ is_verified=is_verified,
111
+ verification_level=verification_level,
112
+ risk_score=risk_score
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  )
114
+
115
+ class ScalpingDetectionEngine:
116
+ @staticmethod
117
+ def detect_scalping(user_id: str, ticket_quantity: int, event_name: str) -> ScalpingDetection:
118
+ """Detect potential scalping behavior"""
119
+
120
+ flags = []
121
+ purchase_velocity = mock_db.get_user_purchases(user_id)
122
+ ip_duplicates = mock_db.get_ip_accounts(user_id)
123
+ resale_frequency = mock_db.get_resale_frequency(user_id)
124
+
125
+ # Check for scalping indicators
126
+ if purchase_velocity > 3:
127
+ flags.append("rapid_purchases")
128
+ if ip_duplicates > 2:
129
+ flags.append("multiple_ips")
130
+ if ticket_quantity > 4:
131
+ flags.append("bulk_purchase")
132
+ if resale_frequency > 5:
133
+ flags.append("frequent_reseller")
134
+
135
+ # Calculate scalping probability
136
+ scalping_score = (
137
+ (purchase_velocity / 10) * 0.3 +
138
+ (ip_duplicates / 5) * 0.3 +
139
+ (ticket_quantity / 10) * 0.2 +
140
+ (resale_frequency / 20) * 0.2
141
  )
142
+
143
+ is_scalper = scalping_score > 0.5
144
+ confidence = min(0.95, scalping_score + random.uniform(0.1, 0.2))
145
+
146
+ return ScalpingDetection(
147
+ is_scalper=is_scalper,
148
+ confidence=confidence,
149
+ flags=flags,
150
+ purchase_velocity=purchase_velocity,
151
+ ip_duplicates=ip_duplicates
 
 
 
 
 
 
 
 
 
 
152
  )
153
+
154
+ class DynamicPricingEngine:
155
+ @staticmethod
156
+ def calculate_pricing(original_price: float, demand_level: str, proposed_price: float) -> PricingRecommendation:
157
+ """Calculate recommended pricing based on demand"""
158
+
159
+ demand_multipliers = {
160
+ "low": (0.8, 1.1), # Allow 20% below to 10% above
161
+ "medium": (0.9, 1.25), # Allow 10% below to 25% above
162
+ "high": (1.0, 1.5) # Allow original price to 50% above
163
+ }
164
+
165
+ min_mult, max_mult = demand_multipliers.get(demand_level, (0.9, 1.25))
166
+
167
+ min_price = original_price * min_mult
168
+ max_price = original_price * max_mult
169
+
170
+ # Recommend price within acceptable range
171
+ recommended_price = max(min_price, min(proposed_price, max_price))
172
+
173
+ price_ratio = recommended_price / original_price
174
+
175
+ profit_margin = None
176
+ loss_percentage = None
177
+
178
+ if price_ratio > 1.0:
179
+ profit_margin = (price_ratio - 1) * 100
180
+ elif price_ratio < 1.0:
181
+ loss_percentage = (1 - price_ratio) * 100
182
+
183
+ reason = f"Adjusted for {demand_level} demand market conditions"
184
+ if recommended_price != proposed_price:
185
+ reason += f" (modified from ${proposed_price:.2f})"
186
+
187
+ return PricingRecommendation(
188
+ original_price=original_price,
189
+ recommended_resale_price=recommended_price,
190
+ demand_level=demand_level,
191
+ price_adjustment_reason=reason,
192
+ profit_margin=profit_margin,
193
+ loss_percentage=loss_percentage
194
  )
195
+
196
+ class ComplianceEngine:
197
+ @staticmethod
198
+ def check_compliance(
199
+ user_id: str,
200
+ proposed_price: float,
201
+ original_price: float,
202
+ scalping_detection: ScalpingDetection
203
+ ) -> ResaleCompliance:
204
+ """Check resale compliance against policies"""
205
+
206
+ violations = []
207
+ price_ratio = proposed_price / original_price
208
+
209
+ # Policy checks
210
+ if price_ratio > 2.0:
211
+ violations.append("price_exceeds_2x")
212
+
213
+ if scalping_detection.is_scalper:
214
+ violations.append("suspected_scalper")
215
+
216
+ if scalping_detection.purchase_velocity > 5:
217
+ violations.append("excessive_purchase_velocity")
218
+
219
+ resale_frequency = mock_db.get_resale_frequency(user_id)
220
+ if resale_frequency > 4:
221
+ violations.append("monthly_resale_limit_exceeded")
222
+
223
+ is_compliant = len(violations) == 0
224
+ resale_allowed = is_compliant and not scalping_detection.is_scalper
225
+
226
+ max_allowed_price = original_price * 2.0
227
+
228
+ if resale_allowed:
229
+ recommendation = "Transaction approved - complies with all policies"
230
+ else:
231
+ recommendation = f"Transaction blocked due to: {', '.join(violations)}"
232
+
233
+ return ResaleCompliance(
234
+ is_compliant=is_compliant,
235
+ violations=violations,
236
+ resale_allowed=resale_allowed,
237
+ max_allowed_price=max_allowed_price,
238
+ recommendation=recommendation
239
  )
240
 
241
  # ========== MAIN APPLICATION ==========
242
  class AntiScalpingSystem:
243
  def __init__(self):
244
+ self.verification_engine = UserVerificationEngine()
245
+ self.scalping_engine = ScalpingDetectionEngine()
246
+ self.pricing_engine = DynamicPricingEngine()
247
+ self.compliance_engine = ComplianceEngine()
248
 
249
  def process_ticket_transaction(
250
  self,
 
260
  ) -> Dict[str, Any]:
261
  """Process a ticket transaction through the anti-scalping system"""
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  try:
264
+ # Step 1: User Verification
265
+ verification = self.verification_engine.verify_user(name, email, user_id)
266
+
267
+ # Step 2: Scalping Detection
268
+ scalping_detection = self.scalping_engine.detect_scalping(
269
+ user_id, ticket_quantity, event_name
270
+ )
271
+
272
+ # Step 3: Dynamic Pricing
273
+ pricing = self.pricing_engine.calculate_pricing(
274
+ original_price, demand_level, proposed_resale_price
275
+ )
276
 
277
+ # Step 4: Compliance Check
278
+ compliance = self.compliance_engine.check_compliance(
279
+ user_id, proposed_resale_price, original_price, scalping_detection
280
+ )
281
+
282
+ # Step 5: Final Decision
283
+ final_decision = "APPROVED" if (
284
+ verification.is_verified and
285
+ compliance.resale_allowed and
286
+ not scalping_detection.is_scalper
287
+ ) else "DENIED"
288
+
289
+ # Action items
290
+ action_items = []
291
+ if final_decision == "APPROVED":
292
+ action_items.append("βœ… Process ticket resale")
293
+ action_items.append("πŸ“Š Monitor user activity")
294
  else:
295
+ action_items.append("❌ Block transaction")
296
+ if scalping_detection.is_scalper:
297
+ action_items.append("🚨 Flag user account for review")
298
+ if not verification.is_verified:
299
+ action_items.append("πŸ“‹ Require additional verification")
300
+
301
+ # Create report
302
+ report = TicketingSystemReport(
303
+ verification=verification,
304
+ scalping_detection=scalping_detection,
305
+ pricing=pricing,
306
+ compliance=compliance,
307
+ final_decision=final_decision,
308
+ action_items=action_items
309
+ )
310
+
311
+ return report.dict()
312
+
313
  except Exception as e:
314
  logger.error(f"Error processing transaction: {e}")
315
+ return self._create_error_response(str(e))
316
 
317
+ def _create_error_response(self, error_msg: str) -> Dict[str, Any]:
318
+ """Create error response"""
 
 
 
319
  return {
320
+ "error": True,
321
+ "message": f"System error: {error_msg}",
322
+ "final_decision": "ERROR",
323
+ "action_items": ["πŸ”§ Contact system administrator"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  }
325
 
326
  # ========== GRADIO INTERFACE ==========
 
335
 
336
  # Validate inputs
337
  if not all([name, email, user_id, event_name]):
338
+ return "❌ **Error**: Please fill in all required fields"
339
 
340
  try:
341
+ original_price = float(original_price) if original_price else 0
342
+ proposed_resale_price = float(proposed_resale_price) if proposed_resale_price else 0
343
+ ticket_quantity = int(ticket_quantity) if ticket_quantity else 1
344
+
345
+ if original_price <= 0 or proposed_resale_price <= 0:
346
+ return "❌ **Error**: Prices must be greater than 0"
347
+
348
+ except (ValueError, TypeError):
349
+ return "❌ **Error**: Please enter valid numbers for prices and quantity"
350
 
351
  # Process through the system
352
  result = system.process_ticket_transaction(
 
361
  proposed_resale_price=proposed_resale_price
362
  )
363
 
364
+ # Handle errors
365
+ if result.get("error"):
366
+ return f"❌ **System Error**: {result.get('message', 'Unknown error occurred')}"
367
+
368
  # Format the output
369
+ decision_emoji = "βœ…" if result['final_decision'] == "APPROVED" else "❌"
370
+
371
  output = f"""
372
+ # 🎫 Anti-Scalping System Analysis Report
373
+
374
+ ## {decision_emoji} Final Decision: **{result['final_decision']}**
375
+
376
+ ---
377
 
378
  ## πŸ‘€ User Verification
379
+ - **User ID**: `{result['verification']['user_id']}`
380
+ - **Name**: {result['verification']['name']}
381
+ - **Email**: {result['verification']['email']}
382
  - **Verified**: {'βœ… Yes' if result['verification']['is_verified'] else '❌ No'}
383
+ - **Risk Score**: {result['verification']['risk_score']:.1%} {'🟒' if result['verification']['risk_score'] < 0.3 else '🟑' if result['verification']['risk_score'] < 0.6 else 'πŸ”΄'}
384
+ - **Verification Level**: {result['verification']['verification_level'].title()}
385
 
386
+ ## πŸ” Scalping Detection Analysis
387
+ - **Scalper Detected**: {'🚨 YES' if result['scalping_detection']['is_scalper'] else 'βœ… NO'}
388
+ - **Detection Confidence**: {result['scalping_detection']['confidence']:.1%}
389
  - **Purchase Velocity**: {result['scalping_detection']['purchase_velocity']} purchases/hour
390
+ - **IP Address Duplicates**: {result['scalping_detection']['ip_duplicates']} accounts
391
+ - **Red Flags**: {', '.join(result['scalping_detection']['flags']) if result['scalping_detection']['flags'] else 'βœ… None detected'}
392
 
393
+ ## πŸ’° Dynamic Pricing Analysis
394
  - **Original Price**: ${result['pricing']['original_price']:.2f}
395
+ - **Proposed Resale**: ${proposed_resale_price:.2f}
396
+ - **Recommended Price**: ${result['pricing']['recommended_resale_price']:.2f}
397
+ - **Demand Level**: {result['pricing']['demand_level'].title()} πŸ“ˆ
398
  - **Price Ratio**: {result['pricing']['recommended_resale_price']/result['pricing']['original_price']:.2f}x
399
  """
400
 
401
  if result['pricing'].get('profit_margin'):
402
+ output += f"- **Profit Margin**: {result['pricing']['profit_margin']:.1f}% πŸ“ˆ\n"
403
  elif result['pricing'].get('loss_percentage'):
404
+ output += f"- **Loss**: -{result['pricing']['loss_percentage']:.1f}% πŸ“‰\n"
405
+
406
+ output += f"""- **Reason**: {result['pricing']['price_adjustment_reason']}
 
 
 
 
 
407
 
408
+ ## βœ… Compliance Evaluation
409
+ - **Policy Compliant**: {'βœ… Yes' if result['compliance']['is_compliant'] else '❌ No'}
410
+ - **Resale Permitted**: {'βœ… Yes' if result['compliance']['resale_allowed'] else '❌ No'}
411
+ - **Maximum Allowed**: ${result['compliance']['max_allowed_price']:.2f}
412
+ - **Policy Violations**: {', '.join(result['compliance']['violations']) if result['compliance']['violations'] else 'βœ… None'}
413
+ - **Recommendation**: {result['compliance']['recommendation']}
414
 
415
+ ---
416
+
417
+ ## πŸ“‹ Required Actions
418
+ """
419
+ for i, action in enumerate(result['action_items'], 1):
420
+ output += f"{i}. {action}\n"
421
+
422
+ # Add summary box
423
+ if result['final_decision'] == "APPROVED":
424
+ output += """
425
+ > βœ… **TRANSACTION APPROVED** - All checks passed. Resale can proceed as recommended.
426
+ """
427
+ else:
428
+ output += """
429
+ > ❌ **TRANSACTION BLOCKED** - Policy violations detected. Review required before proceeding.
430
  """
 
 
431
 
432
  return output
433
 
434
+ # Create Gradio interface with better styling
435
+ with gr.Blocks(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  title="🎫 Anti-Scalping Ticketing System",
437
+ theme=gr.themes.Soft(
438
+ primary_hue="blue",
439
+ secondary_hue="slate",
440
+ )
441
+ ) as interface:
442
+
443
+ gr.Markdown("""
444
+ # 🎫 AI-Powered Anti-Scalping Ticketing System
445
+
446
+ This intelligent system prevents ticket scalping by analyzing user behavior, verifying identities,
447
+ and ensuring fair pricing compliance. Enter transaction details below for real-time analysis.
448
+
449
+ ---
450
+ """)
451
+
452
+ with gr.Row():
453
+ with gr.Column(scale=1):
454
+ gr.Markdown("### πŸ‘€ User Information")
455
+ name = gr.Textbox(label="Full Name", placeholder="John Doe", value="")
456
+ email = gr.Textbox(label="Email Address", placeholder="john@example.com", value="")
457
+ user_id = gr.Textbox(label="User ID", placeholder="USER123", value="")
458
+
459
+ gr.Markdown("### 🎟️ Event Details")
460
+ event_name = gr.Textbox(label="Event Name", placeholder="Taylor Swift - Eras Tour", value="")
461
+ ticket_type = gr.Dropdown(
462
+ label="Ticket Type",
463
+ choices=["General Admission", "VIP", "Premium", "Standard", "Balcony", "Floor"],
464
+ value="Standard"
465
+ )
466
+ ticket_quantity = gr.Number(label="Number of Tickets", value=1, minimum=1, maximum=10, precision=0)
467
+
468
+ gr.Markdown("### πŸ’² Pricing Information")
469
+ original_price = gr.Number(label="Original Ticket Price ($)", value=100, minimum=1)
470
+ demand_level = gr.Radio(
471
+ label="Current Market Demand",
472
+ choices=["low", "medium", "high"],
473
+ value="medium"
474
+ )
475
+ proposed_resale_price = gr.Number(label="Proposed Resale Price ($)", value=150, minimum=1)
476
+
477
+ submit_btn = gr.Button("πŸ” Analyze Transaction", variant="primary", size="lg")
478
+
479
+ with gr.Column(scale=2):
480
+ output = gr.Markdown(value="πŸ‘† Fill in the form and click 'Analyze Transaction' to get started!")
481
+
482
+ # Event handlers
483
+ submit_btn.click(
484
+ fn=process_transaction,
485
+ inputs=[
486
+ name, email, user_id, event_name, ticket_type,
487
+ ticket_quantity, original_price, demand_level, proposed_resale_price
488
+ ],
489
+ outputs=output
490
+ )
491
+
492
+ # Examples section
493
+ gr.Markdown("---")
494
+ gr.Markdown("### πŸ“‹ Example Scenarios")
495
+
496
+ examples = gr.Examples(
497
+ examples=[
498
+ ["John Smith", "john@gmail.com", "USER001", "Taylor Swift - Eras Tour", "VIP", 2, 500, "high", 750],
499
+ ["Jane Doe", "jane@company.com", "USER002", "NBA Finals Game 7", "Premium", 4, 300, "high", 1200],
500
+ ["Bob Wilson", "bob@email.com", "USER003", "Local Concert", "General Admission", 1, 50, "low", 40],
501
+ ["Scalper Bot", "temp@fake.com", "BOT999", "Popular Event", "Standard", 8, 100, "high", 300],
502
+ ],
503
+ inputs=[
504
+ name, email, user_id, event_name, ticket_type,
505
+ ticket_quantity, original_price, demand_level, proposed_resale_price
506
+ ]
507
+ )
508
 
509
  return interface
510
 
511
  # Main execution
512
  if __name__ == "__main__":
513
  interface = create_interface()
514
+ interface.launch(
515
+ share=True,
516
+ server_name="0.0.0.0",
517
+ server_port=7860,
518
+ show_error=True
519
+ )