Simrandhiman commited on
Commit
90d1e9b
·
verified ·
1 Parent(s): 068ced9

Upload 8 files

Browse files
Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, session
2
+ from werkzeug.security import generate_password_hash, check_password_hash
3
+ import os
4
+ from sklearn.datasets import load_iris
5
+ from sklearn.linear_model import LogisticRegression
6
+
7
+ app = Flask(__name__)
8
+ app.secret_key = os.environ.get("SECRET_KEY", "supersecretkey123")
9
+
10
+ # Train ML Model
11
+ iris = load_iris(as_frame=True)
12
+ X, y = iris.data.values, iris.target
13
+ species = iris.target_names
14
+ iris_model = LogisticRegression(max_iter=300)
15
+ iris_model.fit(X, y)
16
+
17
+ # In-memory DB
18
+ users = {}
19
+
20
+ @app.route("/")
21
+ def home():
22
+ if "user" in session:
23
+ return redirect(url_for("dashboard"))
24
+ return redirect(url_for("login"))
25
+
26
+ @app.route("/signup", methods=["GET", "POST"])
27
+ def signup():
28
+ if request.method == "POST":
29
+ username = request.form["username"]
30
+ password = request.form["password"]
31
+ confirm = request.form.get("confirmPassword")
32
+
33
+ if password != confirm:
34
+ return render_template("signup.html", error="Passwords do not match")
35
+ if username in users:
36
+ return render_template("signup.html", error="Username already exists")
37
+
38
+ users[username] = generate_password_hash(password)
39
+ session["user"] = username
40
+ return redirect(url_for("dashboard"))
41
+ return render_template("signup.html")
42
+
43
+ @app.route("/login", methods=["GET", "POST"])
44
+ def login():
45
+ if request.method == "POST":
46
+ username = request.form["username"]
47
+ password = request.form["password"]
48
+
49
+ if username in users and check_password_hash(users[username], password):
50
+ session["user"] = username
51
+ return redirect(url_for("dashboard"))
52
+ return render_template("login.html", error="Invalid username or password")
53
+ return render_template("login.html")
54
+
55
+ @app.route("/dashboard")
56
+ def dashboard():
57
+ if "user" not in session:
58
+ return redirect(url_for("login"))
59
+ return render_template("dashboard.html", username=session["user"])
60
+
61
+ @app.route("/predict", methods=["POST"])
62
+ def predict():
63
+ if "user" not in session:
64
+ return redirect(url_for("login"))
65
+
66
+ try:
67
+ sl = float(request.form["sepal_length"])
68
+ sw = float(request.form["sepal_width"])
69
+ pl = float(request.form["petal_length"])
70
+ pw = float(request.form["petal_width"])
71
+ except Exception:
72
+ return render_template("dashboard.html", username=session["user"], error="Invalid input values", scroll_to="predictor")
73
+
74
+ res_idx = iris_model.predict([[sl, sw, pl, pw]])[0]
75
+ res = species[res_idx]
76
+ return render_template("dashboard.html", username=session["user"], prediction=res, scroll_to="predictor")
77
+
78
+ @app.route("/logout")
79
+ def logout():
80
+ session.pop("user", None)
81
+ return redirect(url_for("login"))
82
+
83
+ if __name__ == "__main__":
84
+ app.run(host="0.0.0.0", port=7860, debug=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ flask
2
+ werkzeug
3
+ scikit-learn
static/style.css ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ background: linear-gradient(135deg,#0b1020,#0a0f1a);
3
+ color: #e6edf3;
4
+ }
5
+ .btn-gradient {
6
+ background: linear-gradient(135deg, #8b5cf6, #22d3ee);
7
+ border: none;
8
+ color: white;
9
+ }
10
+ .btn-gradient:hover { filter: brightness(1.1); }
templates/base.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>{{ title if title else "Flask Portfolio" }}</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
9
+ <link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
10
+ </head>
11
+ <body>
12
+ {% block content %}{% endblock %}
13
+ </body>
14
+ </html>
templates/dashboard.html ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block content %}
3
+ <div class="container py-5">
4
+ <h1 class="mb-4">Welcome, {{ username }}!</h1>
5
+
6
+ {% if error %}<div class="alert alert-danger">{{ error }}</div>{% endif %}
7
+ {% if prediction %}<div class="alert alert-success">The predicted flower species is: <strong>{{ prediction }}</strong></div>{% endif %}
8
+
9
+ <section id="predictor" class="card p-4 mb-4">
10
+ <h2>Iris Flower Predictor</h2>
11
+ <form method="POST" action="{{ url_for('predict') }}">
12
+ <div class="row g-3">
13
+ <div class="col-md-3"><input type="number" step="0.1" name="sepal_length" class="form-control" placeholder="Sepal Length" required></div>
14
+ <div class="col-md-3"><input type="number" step="0.1" name="sepal_width" class="form-control" placeholder="Sepal Width" required></div>
15
+ <div class="col-md-3"><input type="number" step="0.1" name="petal_length" class="form-control" placeholder="Petal Length" required></div>
16
+ <div class="col-md-3"><input type="number" step="0.1" name="petal_width" class="form-control" placeholder="Petal Width" required></div>
17
+ </div>
18
+ <button type="submit" class="btn btn-gradient mt-3">Predict</button>
19
+ </form>
20
+ </section>
21
+
22
+ <a href="{{ url_for('logout') }}" class="btn btn-danger">Logout</a>
23
+ </div>
24
+ {% endblock %}
templates/login.html ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block content %}
3
+ <div class="container py-5">
4
+ <div class="card p-4 mx-auto" style="max-width: 400px;">
5
+ <h2 class="mb-3">Login</h2>
6
+ {% if error %}<div class="alert alert-danger">{{ error }}</div>{% endif %}
7
+ <form method="POST" action="{{ url_for('login') }}">
8
+ <input type="text" name="username" class="form-control mb-3" placeholder="Username" required>
9
+ <input type="password" name="password" class="form-control mb-3" placeholder="Password" required>
10
+ <button type="submit" class="btn btn-gradient w-100">Login</button>
11
+ </form>
12
+ <p class="mt-3">No account? <a href="{{ url_for('signup') }}">Sign up</a></p>
13
+ </div>
14
+ </div>
15
+ {% endblock %}
templates/signup.html ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block content %}
3
+ <div class="container py-5">
4
+ <div class="card p-4 mx-auto" style="max-width: 400px;">
5
+ <h2 class="mb-3">Sign Up</h2>
6
+ {% if error %}<div class="alert alert-danger">{{ error }}</div>{% endif %}
7
+ <form method="POST" action="{{ url_for('signup') }}">
8
+ <input type="text" name="username" class="form-control mb-3" placeholder="Username" required>
9
+ <input type="password" name="password" class="form-control mb-3" placeholder="Password" required>
10
+ <input type="password" name="confirmPassword" class="form-control mb-3" placeholder="Confirm Password" required>
11
+ <button type="submit" class="btn btn-gradient w-100">Sign Up</button>
12
+ </form>
13
+ <p class="mt-3">Already have an account? <a href="{{ url_for('login') }}">Login</a></p>
14
+ </div>
15
+ </div>
16
+ {% endblock %}