pykara commited on
Commit
ee93203
·
1 Parent(s): 445e3c8

Update DB to AWS RDS with pymssql

Browse files
Files changed (2) hide show
  1. app.py +230 -62
  2. requirements.txt +2 -0
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  import time
3
  import base64
4
  import uuid
@@ -52,53 +53,124 @@ if not OPENAI_API_KEY:
52
  # ------------------------------------------------------------
53
  # DATABASE CONNECTION (AUTO-DETECTION)
54
  # ------------------------------------------------------------
55
- print("🔍 Checking SQL Server connectivity...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- # Try both ODBC Driver 17 and 18
58
- possible_drivers = ['{ODBC Driver 18 for SQL Server}', '{ODBC Driver 17 for SQL Server}']
59
- driver = None
60
- for d in possible_drivers:
61
- try:
62
- if d.strip('{}') in pyodbc.drivers():
63
- driver = d
64
- break
65
- except Exception:
66
- pass
67
 
68
- if not driver:
69
- driver = '{ODBC Driver 17 for SQL Server}'
70
- print("⚠️ Defaulting to ODBC Driver 17 for SQL Server")
71
 
72
- # Candidate SQL Server instances
73
- test_servers = [
74
- r'localhost\SQLEXPRESS',
75
- r'localhost\MSSQLSERVER',
76
- r'localhost',
77
- r'127.0.0.1'
78
- ]
79
 
80
- database = 'PyDetect'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- def get_db_connection():
83
- """Try multiple connection methods until success."""
84
- for s in test_servers:
85
- try:
86
- conn = pyodbc.connect(
87
- f'DRIVER={driver};SERVER={s};DATABASE={database};Trusted_Connection=yes;',
88
- timeout=3
89
- )
90
- print(f"✅ Connected to SQL Server instance: {s}")
91
- return conn
92
- except pyodbc.OperationalError:
93
- continue
94
- raise ConnectionError("❌ Cannot connect to any SQL Server instance. Please ensure SQL Server is running.")
95
 
96
  def create_user_table():
 
 
 
 
 
97
  try:
98
  conn = get_db_connection()
99
  cursor = conn.cursor()
100
- cursor.execute('''
101
- IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Users' AND xtype='U')
 
 
 
102
  CREATE TABLE Users (
103
  id INT IDENTITY(1,1) PRIMARY KEY,
104
  name NVARCHAR(120) NOT NULL,
@@ -106,7 +178,7 @@ def create_user_table():
106
  email NVARCHAR(120) UNIQUE NOT NULL,
107
  password NVARCHAR(255) NOT NULL
108
  )
109
- ''')
110
  conn.commit()
111
  cursor.close()
112
  conn.close()
@@ -114,8 +186,10 @@ def create_user_table():
114
  except Exception as e:
115
  print(f"❌ Database setup failed: {str(e)}")
116
 
 
117
  create_user_table()
118
 
 
119
  # ------------------------------------------------------------
120
  # LOAD VECTOR INDEX AND CHUNKS
121
  # ------------------------------------------------------------
@@ -642,44 +716,138 @@ def detect_crime_type(brief_description: str):
642
  # ------------------------------------------------------------
643
  # AUTH ROUTES
644
  # ------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  @app.route('/sign-in', methods=['POST'])
646
  def sign_in():
647
- data = request.json
648
  email = data.get('email')
649
  password = data.get('password')
650
- conn = get_db_connection()
651
- cursor = conn.cursor()
652
- cursor.execute('SELECT * FROM Users WHERE email = ?', (email,))
653
- user = cursor.fetchone()
654
- cursor.close()
655
- conn.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  if user and check_password_hash(user[4], password):
657
- return jsonify({"message": "Login successful", "user": {
658
- "id": user[0], "name": user[1], "role": user[2], "email": user[3]
659
- }}), 200
 
 
 
 
 
 
660
  elif user:
661
  return jsonify({"message": "Invalid password"}), 401
662
  else:
663
  return jsonify({"message": "Email not found"}), 404
664
 
 
665
  @app.route('/sign-up', methods=['POST'])
666
  def sign_up():
667
- data = request.json
668
- name, role, email, password = data.get('name'), data.get('role'), data.get('email'), data.get('password')
 
 
 
 
669
  if not email or not password:
670
  return jsonify({"message": "Email and password are required"}), 400
671
- conn = get_db_connection()
672
- cursor = conn.cursor()
673
- cursor.execute('SELECT * FROM Users WHERE email = ?', (email,))
674
- if cursor.fetchone():
675
- return jsonify({"message": "Email already exists"}), 400
676
- hashed_password = generate_password_hash(password)
677
- cursor.execute('INSERT INTO Users (name, role, email, password) VALUES (?, ?, ?, ?)',
678
- (name, role, email, hashed_password))
679
- conn.commit()
680
- cursor.close()
681
- conn.close()
682
- return jsonify({"message": "User created successfully"}), 201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
 
684
  # ------------------------------------------------------------
685
  # CORE LOGIC
 
1
  import os
2
+ import pymssql
3
  import time
4
  import base64
5
  import uuid
 
53
  # ------------------------------------------------------------
54
  # DATABASE CONNECTION (AUTO-DETECTION)
55
  # ------------------------------------------------------------
56
+ # print("🔍 Checking SQL Server connectivity...")
57
+
58
+ # # Try both ODBC Driver 17 and 18
59
+ # possible_drivers = ['{ODBC Driver 18 for SQL Server}', '{ODBC Driver 17 for SQL Server}']
60
+ # driver = None
61
+ # for d in possible_drivers:
62
+ # try:
63
+ # if d.strip('{}') in pyodbc.drivers():
64
+ # driver = d
65
+ # break
66
+ # except Exception:
67
+ # pass
68
+
69
+ # if not driver:
70
+ # driver = '{ODBC Driver 17 for SQL Server}'
71
+ # print("⚠️ Defaulting to ODBC Driver 17 for SQL Server")
72
+
73
+ # # Candidate SQL Server instances
74
+ # test_servers = [
75
+ # r'localhost\SQLEXPRESS',
76
+ # r'localhost\MSSQLSERVER',
77
+ # r'localhost',
78
+ # r'127.0.0.1'
79
+ # ]
80
+
81
+ # database = 'PyDetect'
82
+
83
+ # def get_db_connection():
84
+ # """Try multiple connection methods until success."""
85
+ # for s in test_servers:
86
+ # try:
87
+ # conn = pyodbc.connect(
88
+ # f'DRIVER={driver};SERVER={s};DATABASE={database};Trusted_Connection=yes;',
89
+ # timeout=3
90
+ # )
91
+ # print(f"✅ Connected to SQL Server instance: {s}")
92
+ # return conn
93
+ # except pyodbc.OperationalError:
94
+ # continue
95
+ # raise ConnectionError("❌ Cannot connect to any SQL Server instance. Please ensure SQL Server is running.")
96
+
97
+ # def create_user_table():
98
+ # try:
99
+ # conn = get_db_connection()
100
+ # cursor = conn.cursor()
101
+ # cursor.execute('''
102
+ # IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Users' AND xtype='U')
103
+ # CREATE TABLE Users (
104
+ # id INT IDENTITY(1,1) PRIMARY KEY,
105
+ # name NVARCHAR(120) NOT NULL,
106
+ # role NVARCHAR(50) NOT NULL,
107
+ # email NVARCHAR(120) UNIQUE NOT NULL,
108
+ # password NVARCHAR(255) NOT NULL
109
+ # )
110
+ # ''')
111
+ # conn.commit()
112
+ # cursor.close()
113
+ # conn.close()
114
+ # print("✅ Users table verified/created successfully.")
115
+ # except Exception as e:
116
+ # print(f"❌ Database setup failed: {str(e)}")
117
+
118
+ # create_user_table()
119
+
120
+ USE_DATABASE = os.getenv("USE_DATABASE", "1") == "1"
121
+
122
+ DB_HOST = os.getenv("DB_HOST", r"localhost")
123
+ DB_PORT = int(os.getenv("DB_PORT", "1433"))
124
+ DB_NAME = os.getenv("DB_NAME", "PyDetect")
125
+ DB_USER = os.getenv("DB_USER", "")
126
+ DB_PASSWORD = os.getenv("DB_PASSWORD", "")
127
+
128
+ if USE_DATABASE:
129
+ print(f"🔍 Database mode enabled. Target SQL Server: {DB_HOST}:{DB_PORT}, db={DB_NAME}")
130
+ else:
131
+ print("ℹ️ USE_DATABASE=0 - running without database (demo mode).")
132
 
 
 
 
 
 
 
 
 
 
 
133
 
134
+ def get_db_connection():
135
+ """Return connection to SQL Server using pymssql.
 
136
 
137
+ - On local: you can point DB_HOST to your local SQL Server or to AWS.
138
+ - On Hugging Face: DB_HOST should be your AWS RDS endpoint.
139
+ """
140
+ if not USE_DATABASE:
141
+ return None
 
 
142
 
143
+ try:
144
+ conn = pymssql.connect(
145
+ server=DB_HOST,
146
+ user=DB_USER,
147
+ password=DB_PASSWORD,
148
+ database=DB_NAME,
149
+ port=DB_PORT,
150
+ login_timeout=10,
151
+ timeout=30,
152
+ as_dict=False # we access rows by index
153
+ )
154
+ return conn
155
+ except Exception as e:
156
+ print(f"❌ Could not connect to SQL Server at {DB_HOST}:{DB_PORT} - {e}")
157
+ raise
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
  def create_user_table():
161
+ """Create Users table if it does not exist."""
162
+ if not USE_DATABASE:
163
+ print("ℹ️ Skipping user table creation (demo mode, no DB).")
164
+ return
165
+
166
  try:
167
  conn = get_db_connection()
168
  cursor = conn.cursor()
169
+ cursor.execute("""
170
+ IF NOT EXISTS (
171
+ SELECT * FROM sysobjects
172
+ WHERE name = 'Users' AND xtype = 'U'
173
+ )
174
  CREATE TABLE Users (
175
  id INT IDENTITY(1,1) PRIMARY KEY,
176
  name NVARCHAR(120) NOT NULL,
 
178
  email NVARCHAR(120) UNIQUE NOT NULL,
179
  password NVARCHAR(255) NOT NULL
180
  )
181
+ """)
182
  conn.commit()
183
  cursor.close()
184
  conn.close()
 
186
  except Exception as e:
187
  print(f"❌ Database setup failed: {str(e)}")
188
 
189
+
190
  create_user_table()
191
 
192
+
193
  # ------------------------------------------------------------
194
  # LOAD VECTOR INDEX AND CHUNKS
195
  # ------------------------------------------------------------
 
716
  # ------------------------------------------------------------
717
  # AUTH ROUTES
718
  # ------------------------------------------------------------
719
+ # @app.route('/sign-in', methods=['POST'])
720
+ # def sign_in():
721
+ # data = request.json
722
+ # email = data.get('email')
723
+ # password = data.get('password')
724
+ # conn = get_db_connection()
725
+ # cursor = conn.cursor()
726
+ # cursor.execute('SELECT * FROM Users WHERE email = ?', (email,))
727
+ # user = cursor.fetchone()
728
+ # cursor.close()
729
+ # conn.close()
730
+ # if user and check_password_hash(user[4], password):
731
+ # return jsonify({"message": "Login successful", "user": {
732
+ # "id": user[0], "name": user[1], "role": user[2], "email": user[3]
733
+ # }}), 200
734
+ # elif user:
735
+ # return jsonify({"message": "Invalid password"}), 401
736
+ # else:
737
+ # return jsonify({"message": "Email not found"}), 404
738
+
739
+ # @app.route('/sign-up', methods=['POST'])
740
+ # def sign_up():
741
+ # data = request.json
742
+ # name, role, email, password = data.get('name'), data.get('role'), data.get('email'), data.get('password')
743
+ # if not email or not password:
744
+ # return jsonify({"message": "Email and password are required"}), 400
745
+ # conn = get_db_connection()
746
+ # cursor = conn.cursor()
747
+ # cursor.execute('SELECT * FROM Users WHERE email = ?', (email,))
748
+ # if cursor.fetchone():
749
+ # return jsonify({"message": "Email already exists"}), 400
750
+ # hashed_password = generate_password_hash(password)
751
+ # cursor.execute('INSERT INTO Users (name, role, email, password) VALUES (?, ?, ?, ?)',
752
+ # (name, role, email, hashed_password))
753
+ # conn.commit()
754
+ # cursor.close()
755
+ # conn.close()
756
+ # return jsonify({"message": "User created successfully"}), 201
757
+
758
  @app.route('/sign-in', methods=['POST'])
759
  def sign_in():
760
+ data = request.get_json() or {}
761
  email = data.get('email')
762
  password = data.get('password')
763
+
764
+ if not email or not password:
765
+ return jsonify({"message": "Email and password are required"}), 400
766
+
767
+ # Optional: if you kept USE_DATABASE from earlier
768
+ if USE_DATABASE is False:
769
+ return jsonify({"message": "Database is disabled (USE_DATABASE=0)."}), 503
770
+
771
+ try:
772
+ conn = get_db_connection()
773
+ cursor = conn.cursor()
774
+
775
+ # IMPORTANT: pymssql uses %s, not ?
776
+ cursor.execute(
777
+ "SELECT id, name, role, email, password FROM Users WHERE email = %s",
778
+ (email,)
779
+ )
780
+ user = cursor.fetchone()
781
+
782
+ cursor.close()
783
+ conn.close()
784
+ except Exception as e:
785
+ print(f"❌ Sign-in DB error: {e}")
786
+ return jsonify({"message": "Login service unavailable"}), 503
787
+
788
  if user and check_password_hash(user[4], password):
789
+ return jsonify({
790
+ "message": "Login successful",
791
+ "user": {
792
+ "id": user[0],
793
+ "name": user[1],
794
+ "role": user[2],
795
+ "email": user[3]
796
+ }
797
+ }), 200
798
  elif user:
799
  return jsonify({"message": "Invalid password"}), 401
800
  else:
801
  return jsonify({"message": "Email not found"}), 404
802
 
803
+
804
  @app.route('/sign-up', methods=['POST'])
805
  def sign_up():
806
+ data = request.get_json() or {}
807
+ name = data.get('name')
808
+ role = data.get('role')
809
+ email = data.get('email')
810
+ password = data.get('password')
811
+
812
  if not email or not password:
813
  return jsonify({"message": "Email and password are required"}), 400
814
+
815
+ # Optional: if you kept USE_DATABASE from earlier
816
+ if USE_DATABASE is False:
817
+ return jsonify({"message": "Sign-up is disabled because the database is not enabled (USE_DATABASE=0)."}), 503
818
+
819
+ try:
820
+ conn = get_db_connection()
821
+ cursor = conn.cursor()
822
+
823
+ # Check if email already exists
824
+ cursor.execute(
825
+ "SELECT id FROM Users WHERE email = %s",
826
+ (email,)
827
+ )
828
+ if cursor.fetchone():
829
+ cursor.close()
830
+ conn.close()
831
+ return jsonify({"message": "Email already exists"}), 400
832
+
833
+ hashed_password = generate_password_hash(password)
834
+
835
+ # Insert new user
836
+ cursor.execute(
837
+ "INSERT INTO Users (name, role, email, password) VALUES (%s, %s, %s, %s)",
838
+ (name, role, email, hashed_password)
839
+ )
840
+ conn.commit()
841
+ cursor.close()
842
+ conn.close()
843
+
844
+ return jsonify({"message": "User created successfully"}), 201
845
+
846
+ except Exception as e:
847
+ print(f"❌ Sign-up DB error: {e}")
848
+ return jsonify({"message": "Sign-up service unavailable"}), 503
849
+
850
+
851
 
852
  # ------------------------------------------------------------
853
  # CORE LOGIC
requirements.txt CHANGED
@@ -13,6 +13,8 @@ requests
13
  sentence-transformers
14
  tf-keras
15
  torch
 
 
16
 
17
 
18
  # If using SQL Server ODBC driver, install it separately (not via pip)
 
13
  sentence-transformers
14
  tf-keras
15
  torch
16
+ pymssql
17
+
18
 
19
 
20
  # If using SQL Server ODBC driver, install it separately (not via pip)