-
Notifications
You must be signed in to change notification settings - Fork 686
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Frank Campise
committed
Apr 22, 2024
1 parent
c77c712
commit 4c54b84
Showing
22 changed files
with
1,002 additions
and
0 deletions.
There are no files selected for viewing
452 changes: 452 additions & 0 deletions
452
...Additional To-Do Details/User Story 1 - Add additional details to to-do item.md
Large diffs are not rendered by default.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Sprint 6: Advanced Task Details | ||
⏲️ _Est. time to complete: 60 min._ ⏲️ | ||
|
||
This sprint is designed to help students add additional details to the To-Do application. The sprint will walk students through adding details about the task such as Due Date, Priority, Additional Notes, and whether or not the Task has been completed. | ||
|
||
**📕Feature: Add additional about to-do item** | ||
1. [**📖 Add Due Date, Priority, Notes and Completion Status to To-Do item**](/Track_2_ToDo_App/Sprint-06%20-%20Advanced%20To-Do%20Details/Feature%201%20-%20Add%20Additional%20To-Do%20Details/User%20Story%201%20-%20Add%20additional%20details%20to%20to-do%20item.md) | ||
|
||
|
||
<br/> | ||
|
||
[🔼 Hackathon Home Page ](/Track_2_ToDo_App/README.md) | [◀ Previous Sprint](/Track_2_ToDo_App/Sprint-05%20-%20Advanced%20AI%20recommendations/README.md) | [Next sprint ▶](/Track_2_ToDo_App/Sprint-07%20-%20Advanced%20Styling%20Your%20Web%20App/README.md) |
Binary file added
BIN
+335 KB
...pp/Sprint-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-DETAILS-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+264 KB
..._App/Sprint-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-DETAILS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+302 KB
...o_App/Sprint-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-EDIT-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+300 KB
...oDo_App/Sprint-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-EDIT.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+313 KB
...Do_App/Sprint-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-INDEX.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+332 KB
...int-06 - Advanced To-Do Details/images/outcome-S06-F01-US01-RECOMMENDATIONS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions
9
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/.env-example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
DEBUG_APP="True" | ||
USE_AZURE_OPENAI="True" | ||
OPENAI_API_KEY="<get the key from https://platform.openai.com/api-keys>" | ||
OPENAI_ORG_ID="<get the ord-id from https://platform.openai.com/account/organization>" | ||
OPEN_AI_DEPLOYMENT_NAME="gpt-3.5-turbo" | ||
AZURE_OPENAI_DEPLOYMENT_NAME="gpt-35-turbo" | ||
AZURE_OPENAI_ENDPOINT="" | ||
AZURE_OPENAI_API_KEY="" | ||
AZURE_OPENAI_VERSION="2023-05-15" |
156 changes: 156 additions & 0 deletions
156
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/app.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
############################################################################### | ||
## Sprint 6: Advanced To-DO Details | ||
## Feature 1: Add Additional Details to To-Do Items | ||
## User Story 1: Add Due Date, Priority, Notes and Completion Status to To-Do item | ||
############################################################################ | ||
import os | ||
import json | ||
from flask import Flask, render_template, request, redirect, url_for, g | ||
from database import db, Todo | ||
from recommendation_engine import RecommendationEngine | ||
from tab import Tab | ||
|
||
app = Flask(__name__) | ||
basedir = os.path.abspath(os.path.dirname(__file__)) # Get the directory of the this file | ||
todo_file = os.path.join(basedir, 'todo_list.txt') # Create the path to the to-do list file using the directory | ||
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///' + os.path.join(basedir, 'todos.db') | ||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||
|
||
db.init_app(app) | ||
|
||
with app.app_context(): | ||
db.create_all() | ||
|
||
@app.before_request | ||
def load_data_to_g(): | ||
todos = Todo.query.all() | ||
g.todos = todos | ||
g.todo = None | ||
g.TabEnum = Tab | ||
g.selectedTab = Tab.NONE | ||
|
||
|
||
@app.route("/") | ||
def index(): | ||
return render_template("index.html") | ||
|
||
@app.route("/add", methods=["POST"]) | ||
def add_todo(): | ||
|
||
# Get the data from the form | ||
todo = Todo( | ||
name=request.form["todo"] | ||
) | ||
|
||
# Add the new ToDo to the list | ||
db.session.add(todo) | ||
db.session.commit() | ||
|
||
# Add the new ToDo to the list | ||
return redirect(url_for('index')) | ||
|
||
# Details of ToDo Item | ||
@app.route('/details/<int:id>', methods=['GET']) | ||
def details(id): | ||
g.selectedTab = Tab.DETAILS | ||
g.todos = Todo.query.all() | ||
g.todo = Todo.query.filter_by(id=id).first() | ||
|
||
return render_template('index.html') | ||
|
||
# Edit a new ToDo | ||
@app.route('/edit/<int:id>', methods=['GET']) | ||
def edit(id): | ||
g.selectedTab = Tab.EDIT | ||
g.todos = Todo.query.all() | ||
g.todo = Todo.query.filter_by(id=id).first() | ||
|
||
return render_template('index.html') | ||
|
||
# Save existing To Do Item | ||
@app.route('/update/<int:id>', methods=['POST']) | ||
def update_todo(id): | ||
g.selectedTab = Tab.DETAILS | ||
|
||
if request.form.get('cancel') != None: | ||
return redirect(url_for('index')) | ||
|
||
# Get the data from the form | ||
name = request.form['name'] | ||
due_date = request.form.get('duedate') | ||
notes=request.form.get('notes') | ||
priority=request.form.get('priority') | ||
completed=request.form.get('completed') | ||
|
||
todo = db.session.query(Todo).filter_by(id=id).first() | ||
if todo != None: | ||
todo.name = name | ||
|
||
if due_date != "None": | ||
todo.due_date = due_date | ||
|
||
if notes != None: | ||
todo.notes = notes | ||
|
||
if priority != None: | ||
todo.priority = int(priority) | ||
|
||
if completed == None: | ||
todo.completed = False | ||
elif completed == "on": | ||
todo.completed = True | ||
# | ||
db.session.add(todo) | ||
db.session.commit() | ||
# | ||
return redirect(url_for('index')) | ||
|
||
|
||
# Delete a ToDo | ||
@app.route('/remove/<int:id>', methods=["POST"]) | ||
def remove_todo(id): | ||
db.session.delete(Todo.query.filter_by(id=id).first()) | ||
db.session.commit() | ||
return redirect(url_for('index')) | ||
|
||
# Show AI recommendations | ||
@app.route('/recommend/<int:id>', methods=['GET']) | ||
@app.route('/recommend/<int:id>/<refresh>', methods=['GET']) | ||
async def recommend(id, refresh=False): | ||
g.selectedTab = Tab.RECOMMENDATIONS | ||
recommendation_engine = RecommendationEngine() | ||
g.todo = db.session.query(Todo).filter_by(id=id).first() | ||
|
||
if g.todo and not refresh: | ||
try: | ||
#attempt to load any saved recommendation from the DB | ||
if g.todo.recommendations_json is not None: | ||
g.todo.recommendations = json.loads(g.todo.recommendations_json) | ||
return render_template('index.html') | ||
except ValueError as e: | ||
print("Error:", e) | ||
|
||
previous_links_str = None | ||
if refresh: | ||
g.todo.recommendations = json.loads(g.todo.recommendations_json) | ||
# Extract links | ||
links = [item["link"] for item in g.todo.recommendations] | ||
# Convert list of links to a single string | ||
previous_links_str = ", ".join(links) | ||
|
||
g.todo.recommendations = await recommendation_engine.get_recommendations(g.todo.name, previous_links_str) | ||
|
||
# Save the recommendations to the database | ||
try: | ||
g.todo.recommendations_json = json.dumps(g.todo.recommendations) | ||
db.session.add(g.todo) | ||
db.session.commit() | ||
except Exception as e: | ||
print(f"Error adding and committing todo: {e}") | ||
return | ||
|
||
return render_template('index.html') | ||
|
||
|
||
if __name__ == "__main__": | ||
app.run(debug=True) |
49 changes: 49 additions & 0 deletions
49
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/database.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from flask_sqlalchemy import SQLAlchemy | ||
from sqlalchemy import Integer, String, Boolean, JSON, func | ||
from sqlalchemy.orm import DeclarativeBase | ||
|
||
class Base(DeclarativeBase): | ||
pass | ||
|
||
db = SQLAlchemy(model_class=Base) | ||
|
||
class Todo(db.Model): | ||
id = db.Column(Integer, primary_key=True) | ||
name = db.Column(String(100), nullable=False) | ||
notes = db.Column(String(100)) | ||
priority = db.Column(Integer, default=0) | ||
completed = db.Column(Boolean, default=False) | ||
recommendations_json = db.Column(db.JSON) #json serialized version of recommendations for storing in DB | ||
due_date = db.Column(String(50)) | ||
|
||
#transient variables (i.e., not stored in db) | ||
recommendations = [] #recommendations as a collection | ||
|
||
def __str__(self): | ||
return self.name | ||
|
||
def priority_str(self): | ||
""" | ||
Returns the priority as a string. | ||
""" | ||
str = "Not Set" | ||
if self.priority == 1: | ||
str = "High" | ||
elif self.priority == 2: | ||
str = "Medium" | ||
elif self.priority == 3: | ||
str = "Low" | ||
|
||
return str | ||
|
||
def completed_str(self): | ||
""" | ||
Returns the completed status as a string. | ||
""" | ||
if self.completed: | ||
return "Yes" | ||
else: | ||
return "No" | ||
|
||
|
||
|
7 changes: 7 additions & 0 deletions
7
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/priority.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from enum import Enum | ||
|
||
class Priority(Enum): | ||
NONE = 0, | ||
HIGH = 1, | ||
MEDIUM = 2, | ||
LOW = 3 |
77 changes: 77 additions & 0 deletions
77
...ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/recommendation_engine.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import json | ||
import asyncio | ||
import semantic_kernel as sk | ||
from services import Service | ||
from openai import AzureOpenAI | ||
from dotenv import dotenv_values | ||
|
||
config = dotenv_values(".env") | ||
|
||
#uses the USE_AZURE_OPENAI variable from the .env file to determine which AI service to use | ||
#False means use OpenAI, True means use Azure OpenAI | ||
selectedService = Service.AzureOpenAI if config.get("USE_AZURE_OPENAI") == "True" else Service.OpenAI | ||
deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env() | ||
|
||
class RecommendationEngine: | ||
def __init__(self): | ||
deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env() | ||
|
||
self.client = AzureOpenAI(azure_endpoint = endpoint, | ||
api_key=api_key, | ||
api_version="2024-02-15-preview" | ||
) | ||
|
||
|
||
async def get_recommendations(self, keyword, previous_links_str=None): | ||
prompt = f"""Please return 5 recommendations based on the input string: '{keyword}' using correct JSON syntax that contains a title and a hyperlink back to the supporting website. RETURN ONLY JSON AND NOTHING ELSE""" | ||
system_prompt = """You are an administrative assistant bot who is good at giving | ||
recommendations for tasks that need to be done by referencing website links that can provide | ||
assistance to helping complete the task. | ||
If there are not any recommendations simply return an empty collection. | ||
EXPECTED OUTPUT: | ||
Provide your response as a JSON object with the following schema: | ||
[{"title": "...", "link": "..."}, | ||
{"title": "...", "link": "..."}, | ||
{"title": "...", "link": "..."}] | ||
""" | ||
|
||
if previous_links_str is not None: | ||
prompt = prompt + f". EXCLUDE the following links from your recommendations: {previous_links_str}" | ||
|
||
message_text = [{"role":"system","content":system_prompt}, | ||
{"role":"user","content":prompt},] | ||
|
||
response = self.client.chat.completions.create( | ||
model=deployment, | ||
messages = message_text, | ||
temperature=0.14, | ||
max_tokens=800, | ||
top_p=0.17, | ||
frequency_penalty=0, | ||
presence_penalty=0, | ||
stop=None | ||
) | ||
|
||
result = response.choices[0].message.content | ||
print(result) | ||
|
||
try: | ||
recommendation = json.loads(result) | ||
except Exception as e: | ||
print(f"Error loading recommendations: {e}") | ||
recommendation = [{"title": "Sorry, unable to recommendation at this time", "link": ""}] | ||
|
||
return recommendation | ||
|
||
async def test_recommendation_engine(): | ||
engine = RecommendationEngine() | ||
recommendations = await engine.get_recommendations("Buy a birthday gift for mom") | ||
count = 1 | ||
for recommendation in recommendations: | ||
print(f"{count} - {recommendation['title']}: {recommendation['link']}") | ||
count += 1 | ||
|
||
if __name__ == "__main__": | ||
asyncio.run(test_recommendation_engine()) |
18 changes: 18 additions & 0 deletions
18
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/services.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
""" | ||
This module defines an enumeration representing different services. | ||
""" | ||
|
||
from enum import Enum | ||
|
||
|
||
class Service(Enum): | ||
""" | ||
Attributes: | ||
OpenAI (str): Represents the OpenAI service. | ||
AzureOpenAI (str): Represents the Azure OpenAI service. | ||
HuggingFace (str): Represents the HuggingFace service. | ||
""" | ||
|
||
OpenAI = "openai" | ||
AzureOpenAI = "azureopenai" | ||
HuggingFace = "huggingface" |
20 changes: 20 additions & 0 deletions
20
...k_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/static/css/style.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
body { | ||
background-color: f0f0f0; /* light grey */ | ||
color: darkslategray; /* default font color */ | ||
font-family: Arial, sans-serif; | ||
background-image: url("../images/Designer02.jpeg"); | ||
background-repeat: no-repeat; | ||
background-position: center; | ||
background-size:cover; | ||
} | ||
|
||
h1 { | ||
color: darkgray; /* font for the h1 header*/ | ||
} | ||
|
||
.list-group-item { | ||
color: #333; /* dark grey */ | ||
} | ||
|
||
|
||
|
Binary file added
BIN
+175 KB
...-06 - Advanced To-Do Details/src/app-s06-f01-us01/static/images/Designer01.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+150 KB
...-06 - Advanced To-Do Details/src/app-s06-f01-us01/static/images/Designer02.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+318 Bytes
...oDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/static/images/favicon.ico
Binary file not shown.
33 changes: 33 additions & 0 deletions
33
Track_2_ToDo_App/Sprint-06 - Advanced To-Do Details/src/app-s06-f01-us01/static/js/app.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
document.addEventListener("DOMContentLoaded", function() { | ||
const nameInput = document.getElementById("todo"); | ||
|
||
//add javascript to support speech recognition for the todo input field | ||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; | ||
const recognition = new SpeechRecognition(); | ||
recognition.continuous = false; | ||
recognition.lang = "en-US"; | ||
recognition.interimResults = false; | ||
|
||
window.captureVoice = function() { | ||
recognition.start(); | ||
nameInput.value = "Your microphone is activated, speak to record voice"; | ||
}; | ||
|
||
recognition.onresult = function(event) { | ||
const transcript = event.results[0][0].transcript; | ||
const recognizedText = transcript.endsWith('.') ? transcript.slice(0, -1) : transcript; | ||
nameInput.value = recognizedText; | ||
}; | ||
|
||
recognition.onspeechend = function() { | ||
recognition.stop(); | ||
}; | ||
|
||
recognition.onnomatch = function(event) { | ||
nameInput.value = "I didn't recognize that prompt."; | ||
}; | ||
|
||
recognition.onerror = function(event) { | ||
nameInput.value = "Error occurred in recognition: " + event.error; | ||
}; | ||
}); |
Oops, something went wrong.