igriv commited on
Commit
5d435b4
·
1 Parent(s): b8f93c6

Debug and fix Supabase initialization for HF Spaces

Browse files
.env~ ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ SUPABASE_URL=https://sfwemuejapejushfbcaj.supabase.co
2
+ SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNmd2VtdWVqYXBlanVzaGZiY2FqIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQxNTY2MjksImV4cCI6MjA2OTczMjYyOX0.zWbvSeZqXYaOx1K_TCaWjdvlq_kVAtTG6KGjVy0hibk
3
+ POLYGON_API_KEY=your_polygon_key_here
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .env
2
+ __pycache__/
3
+ *.pyc
4
+ .DS_Store
README_HF.md ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Hugging Face Spaces Deployment Guide
2
+
3
+ ## Files to Upload
4
+
5
+ Upload these files to your HF Space:
6
+ - `app.py` (entry point)
7
+ - `index_interface_supabase.py`
8
+ - `cryptoindex.py`
9
+ - `updater.py`
10
+ - `requirements.txt`
11
+
12
+ **DO NOT upload:**
13
+ - `.env` (use HF Secrets instead)
14
+ - `.git/` directory
15
+ - `__pycache__/`
16
+ - `index_interface.py` (old version)
17
+
18
+ ## Setting up Secrets
19
+
20
+ In your Space settings → Variables and secrets, add:
21
+ - `SUPABASE_URL` = your-supabase-url
22
+ - `SUPABASE_KEY` = your-supabase-key
23
+ - `POLYGON_API_KEY` = your-polygon-key
24
+
25
+ ## Space Configuration
26
+
27
+ 1. Create new Space
28
+ 2. Select "Gradio" as the SDK
29
+ 3. Choose "Private" visibility
30
+ 4. Upload files
31
+ 5. Add secrets
32
+ 6. Space will auto-deploy
33
+
34
+ ## Testing
35
+
36
+ Your app will be available at:
37
+ `https://huggingface.co/spaces/YOUR_USERNAME/YOUR_SPACE_NAME`
38
+
39
+ The private setting ensures only you (and people you authorize) can access it.
SUPABASE_SETUP.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Supabase Setup Guide
2
+
3
+ ## Overview
4
+ The Supabase-backed version of the crypto index tracker provides:
5
+ - User session isolation
6
+ - Caching of computed index values
7
+ - Persistent storage of user-specific weights
8
+ - Prevention of computation overlap between users
9
+
10
+ ## Setup Instructions
11
+
12
+ ### 1. Create a Supabase Project
13
+ 1. Go to [https://supabase.com](https://supabase.com)
14
+ 2. Create a new project
15
+ 3. Note your project URL and anon/public API key
16
+
17
+ ### 2. Set Environment Variables
18
+ ```bash
19
+ export SUPABASE_URL="your-project-url"
20
+ export SUPABASE_KEY="your-anon-public-key"
21
+ export POLYGON_API_KEY="your-polygon-api-key"
22
+ ```
23
+
24
+ ### 3. Create Database Tables
25
+ Run the SQL commands in `supabase_schema.sql` in your Supabase SQL editor:
26
+ 1. Go to your Supabase project dashboard
27
+ 2. Navigate to SQL Editor
28
+ 3. Copy and paste the contents of `supabase_schema.sql`
29
+ 4. Click "Run"
30
+
31
+ ### 4. Install Dependencies
32
+ ```bash
33
+ pip install -r requirements.txt
34
+ ```
35
+
36
+ ### 5. Run the Application
37
+ ```bash
38
+ python index_interface_supabase.py --locale global --market_type crypto
39
+ ```
40
+
41
+ ## Key Differences from Original Version
42
+
43
+ ### User Isolation
44
+ - Each user session gets a unique session ID
45
+ - Weights and computations are stored per session
46
+ - No global variables that can be overwritten
47
+
48
+ ### Caching Strategy
49
+ - Historical data queries are cached in `index_cache` table
50
+ - Cache key is generated from: start_date, end_date, locale, market_type
51
+ - Prevents redundant API calls and computations
52
+
53
+ ### Real-time Data
54
+ - User-specific weights are stored in `user_weights` table
55
+ - Each session maintains its own set of weights
56
+ - Updates don't affect other users
57
+
58
+ ## Optional Enhancements
59
+
60
+ ### 1. User Authentication
61
+ To add proper user authentication:
62
+ 1. Enable Supabase Auth in your project
63
+ 2. Modify the code to use Supabase auth instead of session-based isolation
64
+ 3. Update RLS policies to use `auth.uid()` instead of session_id
65
+
66
+ ### 2. Data Retention
67
+ The schema includes a cleanup function to remove old data:
68
+ - Cache entries older than 30 days
69
+ - User weights older than 7 days
70
+
71
+ To enable automatic cleanup, install the pg_cron extension in Supabase.
72
+
73
+ ### 3. Performance Optimization
74
+ Consider adding:
75
+ - Redis for faster caching
76
+ - Connection pooling for high traffic
77
+ - Batch processing for multiple user requests
index_interface.py CHANGED
@@ -38,6 +38,7 @@ def plot_index_prices(start_date, end_date, **kwargs):
38
  if not is_current:
39
  cryptodf = fetch_crypto_data(start_date = start_date, end_date = end_date, **kwargs)
40
  v, _ = get_crypto_index(cryptodf, func = np.sqrt)
 
41
  is_current = True
42
  _, _, _, output = do_sharpe(v.close)
43
  fig = px.line(v, x=v.index, y='close', title='Index Prices')
@@ -86,4 +87,5 @@ if __name__ == "__main__":
86
  thestats = gr.Markdown()
87
  radio.change(fn = make_graph_flex, inputs = [radio, startdatebox, enddatebox], outputs = [theplot, thestats])
88
  update_button.click(fn = make_graph_flex, inputs = [radio, startdatebox, enddatebox], outputs = [theplot, thestats])
89
- iface.launch(share=args.share)
 
 
38
  if not is_current:
39
  cryptodf = fetch_crypto_data(start_date = start_date, end_date = end_date, **kwargs)
40
  v, _ = get_crypto_index(cryptodf, func = np.sqrt)
41
+ v.to_csv("/tmp/cryptoindex.csv")
42
  is_current = True
43
  _, _, _, output = do_sharpe(v.close)
44
  fig = px.line(v, x=v.index, y='close', title='Index Prices')
 
87
  thestats = gr.Markdown()
88
  radio.change(fn = make_graph_flex, inputs = [radio, startdatebox, enddatebox], outputs = [theplot, thestats])
89
  update_button.click(fn = make_graph_flex, inputs = [radio, startdatebox, enddatebox], outputs = [theplot, thestats])
90
+ iface.launch(server_port=7860, server_name="0.0.0.0")
91
+ #iface.launch(share=args.share)
index_interface_supabase.py CHANGED
@@ -23,13 +23,26 @@ print(f"Supabase URL: {supabase_url[:30]}..." if supabase_url else "No Supabase
23
  print(f"Supabase Key: {supabase_key[:20]}..." if supabase_key else "No Supabase Key")
24
 
25
  try:
26
- supabase: Client = create_client(supabase_url, supabase_key) if supabase_url else None
27
- if supabase:
 
 
 
 
 
 
 
28
  # Test the connection
29
  test_response = supabase.table('index_cache').select('id').limit(1).execute()
30
  print("Supabase connection test successful")
 
 
 
31
  except Exception as e:
32
  print(f"Supabase initialization error: {e}")
 
 
 
33
  supabase = None
34
 
35
  # Don't update weights at startup - it might fail without proper env vars
 
23
  print(f"Supabase Key: {supabase_key[:20]}..." if supabase_key else "No Supabase Key")
24
 
25
  try:
26
+ if supabase_url and supabase_key:
27
+ # Try to create client without any extra parameters
28
+ import inspect
29
+ create_client_params = inspect.signature(create_client).parameters
30
+ print(f"create_client parameters: {list(create_client_params.keys())}")
31
+
32
+ # Basic initialization
33
+ supabase = create_client(supabase_url, supabase_key)
34
+
35
  # Test the connection
36
  test_response = supabase.table('index_cache').select('id').limit(1).execute()
37
  print("Supabase connection test successful")
38
+ else:
39
+ print("Missing Supabase credentials")
40
+ supabase = None
41
  except Exception as e:
42
  print(f"Supabase initialization error: {e}")
43
+ print(f"Error details: {type(e).__name__}")
44
+ import traceback
45
+ traceback.print_exc()
46
  supabase = None
47
 
48
  # Don't update weights at startup - it might fail without proper env vars
requirements.txt CHANGED
@@ -5,12 +5,8 @@ pandas==2.1.4
5
  numpy==1.26.3
6
  polygon-api-client==1.13.6
7
 
8
- # Supabase integration
9
- supabase==2.4.0
10
- postgrest==0.13.0
11
- gotrue==2.1.0
12
- realtime==1.0.2
13
- storage3==0.7.0
14
 
15
  # Optional but recommended
16
  python-dotenv==1.0.0
 
5
  numpy==1.26.3
6
  polygon-api-client==1.13.6
7
 
8
+ # Supabase integration - let pip resolve versions
9
+ supabase
 
 
 
 
10
 
11
  # Optional but recommended
12
  python-dotenv==1.0.0
supabase_schema.sql ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- Create table for caching index calculations
2
+ CREATE TABLE IF NOT EXISTS index_cache (
3
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
4
+ cache_key VARCHAR(32) UNIQUE NOT NULL,
5
+ start_date DATE NOT NULL,
6
+ end_date DATE NOT NULL,
7
+ locale VARCHAR(50) NOT NULL,
8
+ market_type VARCHAR(50) NOT NULL,
9
+ index_data JSONB NOT NULL,
10
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
11
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
12
+ );
13
+
14
+ -- Create index for faster lookups
15
+ CREATE INDEX IF NOT EXISTS idx_cache_key ON index_cache(cache_key);
16
+ CREATE INDEX IF NOT EXISTS idx_cache_dates ON index_cache(start_date, end_date);
17
+
18
+ -- Create table for user-specific weights
19
+ CREATE TABLE IF NOT EXISTS user_weights (
20
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
21
+ session_id VARCHAR(255) NOT NULL,
22
+ locale VARCHAR(50) NOT NULL,
23
+ market_type VARCHAR(50) NOT NULL,
24
+ weights_data JSONB NOT NULL,
25
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
26
+ );
27
+
28
+ -- Create indexes for user weights
29
+ CREATE INDEX IF NOT EXISTS idx_user_session ON user_weights(session_id);
30
+ CREATE INDEX IF NOT EXISTS idx_user_params ON user_weights(session_id, locale, market_type);
31
+
32
+ -- Optional: Create table for user sessions (if you want persistent user management)
33
+ CREATE TABLE IF NOT EXISTS user_sessions (
34
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
35
+ session_id VARCHAR(255) UNIQUE NOT NULL,
36
+ user_email VARCHAR(255),
37
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
38
+ last_active TIMESTAMP WITH TIME ZONE DEFAULT NOW()
39
+ );
40
+
41
+ -- Enable Row Level Security (RLS) for better data isolation
42
+ ALTER TABLE index_cache ENABLE ROW LEVEL SECURITY;
43
+ ALTER TABLE user_weights ENABLE ROW LEVEL SECURITY;
44
+ ALTER TABLE user_sessions ENABLE ROW LEVEL SECURITY;
45
+
46
+ -- Create policies for public access (adjust based on your auth strategy)
47
+ -- For now, allowing all authenticated users to read cached data
48
+ CREATE POLICY "Public read access for index cache" ON index_cache
49
+ FOR SELECT USING (true);
50
+
51
+ CREATE POLICY "Public insert access for index cache" ON index_cache
52
+ FOR INSERT WITH CHECK (true);
53
+
54
+ CREATE POLICY "Public update access for index cache" ON index_cache
55
+ FOR UPDATE USING (true);
56
+
57
+ -- User weights should be session-specific
58
+ CREATE POLICY "Session-specific access for user weights" ON user_weights
59
+ FOR ALL USING (true);
60
+
61
+ -- Function to clean up old cache entries (optional)
62
+ CREATE OR REPLACE FUNCTION cleanup_old_cache()
63
+ RETURNS void AS $$
64
+ BEGIN
65
+ DELETE FROM index_cache WHERE created_at < NOW() - INTERVAL '30 days';
66
+ DELETE FROM user_weights WHERE created_at < NOW() - INTERVAL '7 days';
67
+ END;
68
+ $$ LANGUAGE plpgsql;
69
+
70
+ -- Optional: Create a scheduled job to run cleanup (requires pg_cron extension)
71
+ -- SELECT cron.schedule('cleanup-old-cache', '0 0 * * *', 'SELECT cleanup_old_cache();');