Surajkumaar commited on
Commit
850e269
Β·
1 Parent(s): e43ea9d
check_deployed_api.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Check if the deployed Hugging Face Space API has the updated code
4
+ """
5
+
6
+ import requests
7
+ import sys
8
+
9
+ def check_deployed_api(api_url):
10
+ """Check if the deployed API has the health endpoint and shows correct version"""
11
+
12
+ print("=" * 60)
13
+ print("CHECKING DEPLOYED API")
14
+ print("=" * 60)
15
+ print(f"API URL: {api_url}")
16
+ print()
17
+
18
+ try:
19
+ # Check health endpoint
20
+ print("1. Checking /health endpoint...")
21
+ response = requests.get(f"{api_url}/health", timeout=10)
22
+
23
+ if response.status_code == 200:
24
+ data = response.json()
25
+ print(" βœ… API is online!")
26
+ print(f" Status: {data.get('status')}")
27
+ print(f" Storage: {data.get('storage')}")
28
+ print(f" Supabase: {data.get('apis', {}).get('supabase')}")
29
+ print()
30
+ else:
31
+ print(f" ❌ Health check failed: HTTP {response.status_code}")
32
+ return False
33
+
34
+ # Check root endpoint for version info
35
+ print("2. Checking / endpoint for version...")
36
+ response = requests.get(f"{api_url}/", timeout=10)
37
+
38
+ if response.status_code == 200:
39
+ data = response.json()
40
+ print(" βœ… Root endpoint accessible!")
41
+ print(f" Message: {data.get('message')}")
42
+ print(f" Version: {data.get('version')}")
43
+ print(f" Data Storage: {data.get('data_storage')}")
44
+ print()
45
+ else:
46
+ print(f" ❌ Root endpoint failed: HTTP {response.status_code}")
47
+
48
+ # Try a test submission to see error handling
49
+ print("3. Testing error handling (this should fail gracefully)...")
50
+ print(" Sending invalid submission to check error messages...")
51
+
52
+ # This should fail with a proper error message
53
+ test_data = {
54
+ 'species_name': 'TEST_SPECIES',
55
+ 'location': 'INVALID_LOCATION', # This should fail validation
56
+ 'species_type': 'plant'
57
+ }
58
+
59
+ response = requests.post(
60
+ f"{api_url}/submit-new-species",
61
+ data=test_data,
62
+ timeout=10
63
+ )
64
+
65
+ if response.status_code == 400:
66
+ error_data = response.json()
67
+ print(" βœ… Error handling works!")
68
+ print(f" Error message: {error_data.get('detail')}")
69
+
70
+ # Check if it's the NEW error message format
71
+ if "Invalid location" in error_data.get('detail', ''):
72
+ print(" βœ… NEW CODE DETECTED - Error messages are specific!")
73
+ else:
74
+ print(" ⚠️ OLD CODE - Error messages are generic")
75
+ else:
76
+ print(f" Status: {response.status_code}")
77
+ print(f" Response: {response.text[:200]}")
78
+
79
+ print()
80
+ print("=" * 60)
81
+ print("βœ… API CHECK COMPLETE")
82
+ print("=" * 60)
83
+ print()
84
+ print("Next steps:")
85
+ print("1. If API is online but using old code:")
86
+ print(" β†’ Restart the Hugging Face Space")
87
+ print("2. If API is offline:")
88
+ print(" β†’ Check Hugging Face Space logs for errors")
89
+ print("3. Test with a real species submission from the frontend")
90
+ print()
91
+
92
+ return True
93
+
94
+ except requests.exceptions.ConnectionError:
95
+ print(" ❌ Connection Error - Cannot reach the API")
96
+ print(" β†’ Check if the Hugging Face Space is running")
97
+ print(" β†’ Verify the API URL is correct")
98
+ return False
99
+ except requests.exceptions.Timeout:
100
+ print(" ❌ Timeout - API is not responding")
101
+ print(" β†’ The Space might be starting up (wait 2-3 minutes)")
102
+ return False
103
+ except Exception as e:
104
+ print(f" ❌ Error: {e}")
105
+ return False
106
+
107
+ if __name__ == "__main__":
108
+ # Default API URL - update this with your actual Hugging Face Space URL
109
+ api_url = input("Enter your Hugging Face Space API URL (e.g., https://YOUR-USERNAME-YOUR-SPACE.hf.space): ").strip()
110
+
111
+ if not api_url:
112
+ print("No URL provided. Using example...")
113
+ api_url = "http://localhost:7860" # Fallback to local
114
+
115
+ # Remove trailing slash if present
116
+ api_url = api_url.rstrip('/')
117
+
118
+ check_deployed_api(api_url)
fix_logs_rls.sql ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- Fix RLS policy for recognition_logs table
2
+ -- Run this in your Supabase SQL Editor
3
+
4
+ -- 1. Enable RLS (just in case)
5
+ ALTER TABLE public.recognition_logs ENABLE ROW LEVEL SECURITY;
6
+
7
+ -- 2. Drop existing policies to cleanly recreate them
8
+ DROP POLICY IF EXISTS "Anyone can log recognitions" ON public.recognition_logs;
9
+ DROP POLICY IF EXISTS "Enable insert for all users" ON public.recognition_logs;
10
+ DROP POLICY IF EXISTS "Enable read for all users" ON public.recognition_logs;
11
+
12
+ -- 3. Create permissive policies for both INSERT and SELECT
13
+ -- Allow the API (anon/service_role) to insert logs
14
+ CREATE POLICY "Enable insert for all users"
15
+ ON public.recognition_logs FOR INSERT
16
+ WITH CHECK (true);
17
+
18
+ -- Allow reading logs (if needed for dashboard)
19
+ CREATE POLICY "Enable read for all users"
20
+ ON public.recognition_logs FOR SELECT
21
+ USING (true);
22
+
23
+ -- 4. Verify policies
24
+ SELECT tablename, policyname, cmd, diff_key
25
+ FROM pg_policies
26
+ WHERE tablename = 'recognition_logs';
test_live_insert.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script to simulate what happens when the API tries to insert a species
4
+ This will help us see the ACTUAL error from Supabase
5
+ """
6
+
7
+ import os
8
+ from dotenv import load_dotenv
9
+ from supabase import create_client, Client
10
+
11
+ # Load environment variables
12
+ load_dotenv()
13
+
14
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
15
+ SUPABASE_KEY = os.getenv("SUPABASE_KEY", "")
16
+
17
+ def test_insert_with_validation():
18
+ """Test inserting a species with proper response validation"""
19
+
20
+ if not SUPABASE_URL or not SUPABASE_KEY:
21
+ print("❌ ERROR: SUPABASE_URL or SUPABASE_KEY not found in .env file")
22
+ return
23
+
24
+ try:
25
+ # Initialize Supabase client
26
+ supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
27
+
28
+ # Test data - similar to what the API would send
29
+ species_data = {
30
+ "sno": 88888,
31
+ "species_name": "Test Plant Species",
32
+ "species_type": "plant",
33
+ "location": "QSC",
34
+ "latitude": 12.92000,
35
+ "longitude": 80.12100,
36
+ "added_by": "test_user",
37
+ "notes": "Testing insert validation"
38
+ }
39
+
40
+ print("=" * 60)
41
+ print("TESTING SPECIES INSERT WITH VALIDATION")
42
+ print("=" * 60)
43
+ print(f"\n[DEBUG] Attempting to insert species data:")
44
+ print(f" Species: {species_data['species_name']}")
45
+ print(f" Location: {species_data['location']}")
46
+ print(f" Type: {species_data['species_type']}")
47
+ print()
48
+
49
+ # This is what the API does
50
+ response = supabase.table("species").insert(species_data).execute()
51
+
52
+ print(f"[DEBUG] Response received:")
53
+ print(f" response.data: {response.data}")
54
+ print(f" response.count: {response.count}")
55
+ print(f" Type: {type(response.data)}")
56
+ print(f" Length: {len(response.data) if response.data else 'None'}")
57
+ print()
58
+
59
+ # Check if the insert was successful (NEW VALIDATION)
60
+ if not response.data or len(response.data) == 0:
61
+ print("❌ [ERROR] Insert failed - no data returned!")
62
+ print(f" Full response: {response}")
63
+ print()
64
+ print("πŸ” DIAGNOSIS:")
65
+ print(" The insert was called but Supabase returned no data.")
66
+ print(" This usually means:")
67
+ print(" 1. RLS policy blocked the insert (permission denied)")
68
+ print(" 2. A constraint was violated (duplicate key)")
69
+ print(" 3. The insert was rolled back due to an error")
70
+ return False
71
+
72
+ print(f"βœ… [INFO] Successfully saved {species_data['species_name']} to Supabase")
73
+ print(f"[DEBUG] Insert response: {response.data}")
74
+ print()
75
+
76
+ # Verify by reading it back
77
+ inserted_id = response.data[0].get('id')
78
+ print(f"[VERIFY] Reading back inserted record (ID: {inserted_id})...")
79
+ verify = supabase.table("species").select("*").eq("id", inserted_id).execute()
80
+
81
+ if verify.data and len(verify.data) > 0:
82
+ print("βœ… Verification successful - data exists in database!")
83
+ print(f" Data: {verify.data[0]}")
84
+ else:
85
+ print("❌ Verification FAILED - data not found!")
86
+ return False
87
+
88
+ # Clean up
89
+ print()
90
+ print("[CLEANUP] Deleting test record...")
91
+ supabase.table("species").delete().eq("id", inserted_id).execute()
92
+ print("βœ… Test record deleted")
93
+ print()
94
+
95
+ print("=" * 60)
96
+ print("βœ… TEST PASSED - Insert validation is working!")
97
+ print("=" * 60)
98
+ return True
99
+
100
+ except Exception as e:
101
+ print()
102
+ print("=" * 60)
103
+ print("❌ EXCEPTION CAUGHT")
104
+ print("=" * 60)
105
+ print(f"Error type: {type(e).__name__}")
106
+ print(f"Error message: {str(e)}")
107
+ print()
108
+
109
+ error_str = str(e).lower()
110
+
111
+ if "duplicate key" in error_str or "unique constraint" in error_str:
112
+ print("πŸ” DIAGNOSIS: Duplicate Key Violation")
113
+ print(" A species with this name already exists at this location.")
114
+ print(" Solution: The API should return HTTP 409 with a clear message.")
115
+ elif "permission denied" in error_str or "policy" in error_str or "rls" in error_str:
116
+ print("πŸ” DIAGNOSIS: Row Level Security (RLS) Policy Issue")
117
+ print(" The RLS policy is blocking the insert.")
118
+ print(" Solution: Run fix_species_insert.sql in Supabase SQL Editor")
119
+ elif "violates not-null constraint" in error_str:
120
+ print("πŸ” DIAGNOSIS: Missing Required Field")
121
+ print(" A required field is missing from the insert data.")
122
+ else:
123
+ print("πŸ” DIAGNOSIS: Unknown Error")
124
+ print(" Check the error message above for details.")
125
+
126
+ print()
127
+ return False
128
+
129
+ if __name__ == "__main__":
130
+ test_insert_with_validation()
verify_remote_species.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ API_URL = "https://greennai-greenai.hf.space"
5
+
6
+ def check_species_exists(species_name, location):
7
+ print(f"Checking if '{species_name}' exists in '{location}'...")
8
+
9
+ # We can't query the DB directly via API, but we can try to add it again
10
+ # If it exists, it should return 409 Conflict
11
+
12
+ payload = {
13
+ "species_name": species_name,
14
+ "location": location,
15
+ "species_type": "plant",
16
+ "user_id": "test_script"
17
+ }
18
+
19
+ try:
20
+ response = requests.post(f"{API_URL}/submit-new-species", json=payload)
21
+
22
+ print(f"Status Code: {response.status_code}")
23
+ print(f"Response: {response.text}")
24
+
25
+ if response.status_code == 409:
26
+ print("βœ… SUCCESS: The API knows this species exists (Duplicate Error)")
27
+ return True
28
+ elif response.status_code == 200:
29
+ print("❌ FAILURE: The API added it again (It didn't know it existed)")
30
+ return False
31
+ else:
32
+ print(f"⚠️ UNEXPECTED: {response.status_code}")
33
+ return False
34
+
35
+ except Exception as e:
36
+ print(f"Error: {e}")
37
+ return False
38
+
39
+ # Test with the species you mentioned
40
+ check_species_exists("Ocimum gratissimum (African basil)", "QSC")
41
+ check_species_exists("Ocimum gratissimum", "QSC")
42
+ check_species_exists("African basil", "QSC")