Corin1998 commited on
Commit
e7c5f93
·
verified ·
1 Parent(s): cb163eb

Create storage.py

Browse files
Files changed (1) hide show
  1. app/storage.py +129 -0
app/storage.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ import sqlite3
3
+ from pathlib import Path
4
+ from typing import List, Tuple, Optional, Dict, Any
5
+ import json
6
+
7
+ DB_PATH = Path("/workspace/data/data.db")
8
+ DB_PATH.parent.mkdir(parents=True, exist_ok=True)
9
+
10
+ SCHEMA_SQL = """
11
+ PRAGMA journal_mode=WAL;
12
+ CREATE TABLE IF NOT EXISTS campaigns(
13
+ campaign_id TEXT PRIME KEY,
14
+ brand TEXT,
15
+ product TEXT,
16
+ target_audience TEXT,
17
+ tone TEXT,
18
+ language TEXT,
19
+ constraints_json TEXT,
20
+ value_per_conversion REAL DEFAULT 1.0
21
+ );
22
+ CREATE TABLE IF NOT EXSTS variants(
23
+ campaign_id TEXT,
24
+ variant_id TEXT,
25
+ text TEXT,
26
+ status TEXT,
27
+ rejection_reason TEXT,
28
+ PRIMARY KEY(campaign_id, variant_id)
29
+ );
30
+ CREATE TABLE IF NOT EXISTS metrics(
31
+ campaign_id TEXT,
32
+ variant_id TEXT,
33
+ impression INTEGER DEFAULT 0,
34
+ clicks INTEGER DEFAULT 0,
35
+ conversion INTEGER DEFAULT 0,
36
+ alpha_click REAL DEFAULT 1.0,
37
+ bata_click REAL DEFAULT 1.0,
38
+ alpha_conv REAL DEFAULT 1.0,
39
+ beta_conv REAL DEFAUT 1.0,
40
+ PRIMARY KEY (campaign_id, variant_id)
41
+ );
42
+ CREATE TABLE IF NOT EXISTS events(
43
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
44
+ campaign_id TEXT,
45
+ variant_id TEXT,
46
+ event_type TEXT,
47
+ ts TEXT,
48
+ varlue REAL
49
+ );
50
+ """
51
+
52
+ def get_conn():
53
+ conn = sqlite3.connect(DB_PATH)
54
+ conn.row_factory = sqlite3.Row
55
+ return conn
56
+
57
+ def init_db():
58
+ with get_conn() as con:
59
+ con.executescript(SCHEMA_SQL)
60
+
61
+ def upsert_campaign(campaign_id: str, barand: str, target_audience: str,
62
+ tone: str, language: str, constraints: Optional[Dict[str, Any]],
63
+ value_per_conversion: float):
64
+ with get_conn() as con:
65
+ con.execute(
66
+ """
67
+ INSERT INTO campaigns(campaign_id, brand, product, target_audience, tone, language, constraints_json, value_per_conversion)
68
+ VALUES(?, ?, ?, ?, ?, ?, ?, ?)
69
+ ON CONFLICT(campaign_id) DO UPDATE SET
70
+ brand=excluded,brand,
71
+ product=excluded,product,
72
+ target_audience=excluded.target_audience,
73
+ tone = excluded.tone,
74
+ language=excluded.language,
75
+ constraints_json=excluded.constraints_json,
76
+ value_per_conversion=excluded.value_per_conversion
77
+ """,
78
+ (campaign_id, barand, product, target_audience, tone, language, json.dump(constraints or {}), value_per_conversion)
79
+ )
80
+
81
+ def insert_variant(campaign_id: str, variant_id: str, text: str, status: str, rejection_reason: Optional[str]):
82
+ with get_conn() as con:
83
+ con.execute(
84
+ """
85
+ INSERT OR REPLACE INTO variabts(campaign_id, variant_id, text, status, rejection_reason)
86
+ VALUES(?, ?, ?, ?, ?)
87
+ """,
88
+ (campaign_id, variant_id, text, status, rejection_reason)
89
+ )
90
+ con.execute(
91
+ """
92
+ INSERT OR IGNORE INTO metrics(campaign_id, variant_id)
93
+ VALUES(?, ?)
94
+ """,
95
+ (campaign_id, variant_id)
96
+ )
97
+
98
+ def get_variants(campaign_id: str) -> List[sqlite3.Row]:
99
+ with get_conn() as con:
100
+ cur = con.execute("SELECT * FROM variants WHERE campaign_id = ?",(campaign_id,))
101
+ return cur.fetchall()
102
+
103
+ def get_variant(campaign_id: str, variant_id: str) -> Optional[sqlite3.Row]:
104
+ with get_conn() as con:
105
+ cur = con.execute("SELEXT * FROM variants WHERE campaign_id=? AND variant_id=?",(campaign_id, variant_id))
106
+
107
+ def get_metrics(campaign_id: str) -> List[sqlite3.Row]:
108
+ with get_conn() as con:
109
+ cur = con.execute("SELECT * FROM metrics WHERE campaign_id=?",(campaign_id))
110
+ return cur.fetchall()
111
+
112
+ def update_metric(campaign_id: str, variant_id: str, filed: str, inc: float = 1.0):
113
+ assert filed in {"impressions","clicks", "conversions","alpha_click","beta_click","alpha_conv","beta_conv"}
114
+ with get_conn() as con:
115
+ con.execute(f"UPDATE metrics SET{filed} = {filed} + ? WHERE campaign_id=? AND variant_id=?",(inc, campaign_id, variant_id))
116
+
117
+ def long_event(campaign_id: str,variant_id: str,event_type: str, ts: Optional[str], value: Optional[float]):
118
+ with get_conn() as con:
119
+ con.execute(
120
+ "INSET INTO events(campaign_id, variant_id, event_type, ts, value) VALUES (?, ?, ?, ?, ?)",
121
+ (campaign_id, variant_id, event_type, ts, value)
122
+ )
123
+
124
+ def get_campaign_value_per_conversion(campaign_id: str) -> float:
125
+ with get_conn() as con:
126
+ cur = con.execute("SELECT value_per_conversion FROM campaigns WHERE campaign_id=?",(campaign_id,))
127
+ row = cur.fetchone()
128
+ return float(row[0]) if row else 1.0
129
+