bobbypaton commited on
Commit
de4f5fa
·
1 Parent(s): 2f362b4

add visit counter

Browse files
bde_prediction/bde_flask/__init__.py CHANGED
@@ -8,6 +8,7 @@ from alfabet.prediction import predict_bdes, check_input
8
  from flask import Flask, render_template, request, flash, jsonify, send_from_directory
9
  from werkzeug.middleware.dispatcher import DispatcherMiddleware
10
  from wtforms import Form, StringField, validators
 
11
 
12
  # App config.
13
 
@@ -57,6 +58,7 @@ def send_static(path):
57
 
58
  @app.route("/", methods=['GET', 'POST'])
59
  def index():
 
60
  form = ReusableForm(request.form)
61
  return render_template('index.html', form=form)
62
 
 
8
  from flask import Flask, render_template, request, flash, jsonify, send_from_directory
9
  from werkzeug.middleware.dispatcher import DispatcherMiddleware
10
  from wtforms import Form, StringField, validators
11
+ from visit_counter import log_visit
12
 
13
  # App config.
14
 
 
58
 
59
  @app.route("/", methods=['GET', 'POST'])
60
  def index():
61
+ log_visit()
62
  form = ReusableForm(request.form)
63
  return render_template('index.html', form=form)
64
 
bde_prediction/visit_counter.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ visit_counter.py
3
+ ----------------
4
+ Drop this file into your Space. Call `log_visit()` once per app load.
5
+
6
+ Setup:
7
+ 1. Create a private HF Dataset repo for analytics:
8
+ huggingface-cli repo create analytics --type dataset
9
+
10
+ 2. Add your HF token as a Space secret:
11
+ HF_TOKEN = <your token with write access>
12
+
13
+ 3. Call log_visit() at app startup (see bottom of file for example).
14
+ """
15
+
16
+ import os
17
+ import csv
18
+ import io
19
+ from datetime import datetime, timezone
20
+
21
+ try:
22
+ from huggingface_hub import HfApi, hf_hub_download
23
+ from huggingface_hub.utils import EntryNotFoundError
24
+ except ImportError:
25
+ import subprocess, sys
26
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "huggingface_hub", "-q"])
27
+ from huggingface_hub import HfApi, hf_hub_download
28
+ from huggingface_hub.utils import EntryNotFoundError
29
+
30
+
31
+ # ── Config ────────────────────────────────────────────────────────────────────
32
+ ANALYTICS_REPO = "patonlab/analytics" # your private dataset repo
33
+ ANALYTICS_FILE = "visits.csv" # filename inside that repo
34
+ SPACE_NAME = "patonlab/alfabet_bde" # label stored in each row
35
+ TOKEN = os.environ.get("HF_TOKEN") # set as a Space secret
36
+ # ─────────────────────────────────────────────────────────────────────────────
37
+
38
+
39
+ def log_visit(space: str = SPACE_NAME):
40
+ """Append one row to visits.csv in the analytics dataset repo."""
41
+ if not TOKEN:
42
+ print("[visit_counter] HF_TOKEN not set — skipping visit log.")
43
+ return
44
+
45
+ api = HfApi(token=TOKEN)
46
+ now = datetime.now(timezone.utc).isoformat()
47
+
48
+ # 1. Try to download existing CSV
49
+ existing_rows = []
50
+ try:
51
+ path = hf_hub_download(
52
+ repo_id=ANALYTICS_REPO,
53
+ filename=ANALYTICS_FILE,
54
+ repo_type="dataset",
55
+ token=TOKEN,
56
+ )
57
+ with open(path, newline="") as f:
58
+ existing_rows = list(csv.DictReader(f))
59
+ except EntryNotFoundError:
60
+ pass # first visit ever — file doesn't exist yet
61
+
62
+ # 2. Append new row
63
+ existing_rows.append({"space": space, "timestamp": now})
64
+
65
+ # 3. Write updated CSV to buffer
66
+ buf = io.StringIO()
67
+ writer = csv.DictWriter(buf, fieldnames=["space", "timestamp"])
68
+ writer.writeheader()
69
+ writer.writerows(existing_rows)
70
+
71
+ # 4. Push back to dataset repo
72
+ api.upload_file(
73
+ path_or_fileobj=buf.getvalue().encode(),
74
+ path_in_repo=ANALYTICS_FILE,
75
+ repo_id=ANALYTICS_REPO,
76
+ repo_type="dataset",
77
+ commit_message=f"visit: {space} @ {now}",
78
+ )
79
+ print(f"[visit_counter] Logged visit for {space} at {now}")
80
+
81
+
82
+ def get_visit_counts() -> dict:
83
+ """Return a dict of {space_name: visit_count} from the analytics repo."""
84
+ if not TOKEN:
85
+ return {}
86
+ try:
87
+ path = hf_hub_download(
88
+ repo_id=ANALYTICS_REPO,
89
+ filename=ANALYTICS_FILE,
90
+ repo_type="dataset",
91
+ token=TOKEN,
92
+ )
93
+ counts = {}
94
+ with open(path, newline="") as f:
95
+ for row in csv.DictReader(f):
96
+ counts[row["space"]] = counts.get(row["space"], 0) + 1
97
+ return counts
98
+ except EntryNotFoundError:
99
+ return {}
100
+
101
+
102
+ def print_summary():
103
+ """Print a quick analytics summary to stdout."""
104
+ counts = get_visit_counts()
105
+ if not counts:
106
+ print("No visit data yet.")
107
+ return
108
+ total = sum(counts.values())
109
+ print(f"\n{'='*40}")
110
+ print(f" HF Spaces Visit Summary")
111
+ print(f"{'='*40}")
112
+ for space, n in sorted(counts.items(), key=lambda x: -x[1]):
113
+ print(f" {space:<35} {n:>6} visits")
114
+ print(f" {'TOTAL':<35} {total:>6}")
115
+ print(f"{'='*40}\n")
116
+
117
+
118
+ # ── Example integration ───────────────────────────────────────────────────────
119
+ # In your app's main entry point (e.g. app.py), add:
120
+ #
121
+ # from visit_counter import log_visit
122
+ # log_visit() # <-- one line, runs at startup
123
+ #
124
+ # For Gradio specifically, put it just before gr.launch():
125
+ #
126
+ # import gradio as gr
127
+ # from visit_counter import log_visit
128
+ # log_visit()
129
+ # demo.launch()
130
+ #
131
+ # For a Gradio "on load" event (fires each time UI loads in browser):
132
+ #
133
+ # with gr.Blocks() as demo:
134
+ # demo.load(fn=log_visit)
135
+ # demo.launch()
136
+ # ─────────────────────────────────────────────────────────────────────────────
137
+
138
+ if __name__ == "__main__":
139
+ print_summary()
requirements.txt CHANGED
@@ -10,3 +10,4 @@ joblib
10
  pytest
11
  tensorflow==2.9.1
12
  alfabet==0.2.2
 
 
10
  pytest
11
  tensorflow==2.9.1
12
  alfabet==0.2.2
13
+ huggingface_hub