Feature Blog write up
Purpose: The purpose of my individual feature was to create a page where people can post facts about those they look up to, and after how long that fact will become a reality about them. This is so that people can set expectations on themselves similar to how the people they look up too once did. With these expectations now written out and saved online, they can now achieve this, all while continuously updating the amount of time it would take for them to achieve that goal. An example of this would be: Lionel Messi's first club was FC Barcelona located in Barcelona, Spain. Time it will take for me to play for FC Barcelona: 5 years. I will continuously update the time it will take for me to get there as certain events happen. An example of these certain events would be, a scout has taken interest in me: 2 years till I play at Barcelona. I am playing for team USA U19: 6 months till I play at Barcelona.
The CoolFact feature was designed to help people lacking in motivation to set expectations upon themselves. As they do the research about the fact of the person they look up too, they will start to understand that the road to success is not easy and that they will struggle for many years before they achieve their goal. This will show them that they are not alone and can achieve their goals.
class CoolFactsAPI:
class _CRUD(Resource):
@token_required()
def post(self):
# Obtain the request data sent by the RESTful client API
data = request.get_json()
# Create a new post object using the data from the request
post = CoolFacts(age=data['age'], coolfacts=data['coolfacts'])
# Save the post object using the Object Relational Mapper (ORM) method defined in the model
post.create()
# Return response to the client in JSON format, converting Python dictionaries to JSON format
return jsonify(post.read())
@token_required()
def put(self):
data = request.get_json()
if not data or not data.get("age") or not data.get("coolfacts"):
return jsonify({"message": "Coolfact and age are required to update"}), 400
coolfact = CoolFacts.query.filter_by(coolfacts=data["coolfacts"], age=data["age"]).first()
if not coolfact:
return jsonify({"message": "Coolfact and age not found"}), 404
# Update the object's attributes
coolfact.coolfacts = data["new_coolfacts"]
coolfact.age = data["new_age"]
if coolfact.update():
#return "hello"
return jsonify({"message": "Coolfact and age updated", "old_coolfact": data["coolfacts"], "new_coolfact": coolfact.coolfacts, "old_age": data["age"], "new_age": coolfact.age})
# coolfact.update({"coolfacts": data["coolfacts"], "age": data["age"]})
# return jsonify({"message": "Coolfact and age updated"})
# Commit changes using update()
#if coolfact.update():
# return jsonify({"message": "Coolfact and age updated", "new_coolfact": coolfact.coolfacts, "new_age": coolfact.age})
#else:
# return jsonify({"message": "Error updating coolfact and age"}), 500
@token_required()
def get(self):
try:
# Query all entries in the BinaryHistory table
entries = CoolFacts.query.all()
# Convert the entries to a list of dictionaries
results = [entry.read() for entry in entries]
# Return the list of results in JSON format
return jsonify(results)
except Exception as e:
# Return an error message in case of failure
return jsonify({"error": str(e)}), 500
@token_required()
def delete(self):
# Obtain the request data
data = request.get_json()
# Find the current post from the database table(s)
post = CoolFacts.query.get(data['id'])
# Delete the post using the ORM method defined in the model
post.delete()
# Return response
return jsonify({"message": "Post deleted"})
api.add_resource(_CRUD, '/coolfacts')
if __name__ == '__main__':
app.run(debug=True)
CoolFactsAPI - RESTful API Overview
This code defines a RESTful API for managing “CoolFacts” using Flask and SQLAlchemy. Below is a breakdown of its functionality.
Class: CoolFactsAPI
- Contains the
_CRUD
inner class, which defines API endpoints for creating, reading, updating, and deleting “CoolFacts” entries.
CRUD Operations (_CRUD
class)
1. post()
(Create)
- Receives JSON data from a client request.
- Creates a new
CoolFacts
entry withage
andcoolfacts
. - Saves it in the database and returns the created entry as JSON.
2. put()
(Update)
- Receives JSON data with
age
andcoolfacts
. - Finds the matching entry in the database.
- Updates the
coolfacts
andage
fields if the entry exists. - Returns a confirmation message with the old and new values.
3. get()
(Read)
- Retrieves all entries from the database.
- Returns them as a JSON list.
4. delete()
(Delete)
- Receives an
id
from the client request. - Deletes the corresponding entry from the database.
- Returns a success message.
Other Features
- Token Authentication: All endpoints are protected using
@token_required()
, meaning only authenticated users can access them. - Error Handling: Includes error messages for missing data, entry not found, and server errors.
- Flask API Integration: The API is registered under
/coolfacts
usingapi.add_resource()
, and the application runs withapp.run(debug=True)
.
Summary
This code provides a secure RESTful API for managing “CoolFacts,” allowing clients to add, update, retrieve, and delete facts using HTTP requests.
class CoolFacts (db.Model):
"""
CoolFacts Model
"""
__tablename__ = 'coolFacts'
id = db.Column(db.Integer, primary_key=True)
coolfacts = db.Column(db.String(255), nullable=False)
age = db.Column(db.String(255), nullable=False)
def __init__(self, coolfacts, age, ):
"""
Constructor for Binary.
"""
self.coolfacts = coolfacts
self.age = age
def __repr__(self):
"""
Represents the QuizCreation object as a string for debugging.
"""
return f"<Coolfacts(id={self.id}, coolfacts='{self.coolfacts}', age='{self.age})>"
def create(self):
"""
Adds the quiz to the database and commits the transaction.
"""
try:
db.session.add(self)
db.session.commit()
except SQLAlchemyError as e:
db.session.rollback()
raise e
def read(self):
"""
Returns the quiz details as a dictionary.
"""
return {
"id": self.id,
"coolfacts": self.coolfacts,
"age": self.age,
}
def update(self):
try:
db.session.add(self)
db.session.commit()
return True
except IntegrityError as e:
logging.error(f"Error creating hobby: {e}")
db.session.rollback()
return False
def delete(self):
"""
Deletes the quiz from the database and commits the transaction.
"""
try:
db.session.delete(self)
db.session.commit()
return True
except IntegrityError as e:
logging.error(f"Error deleting hobby: {e}")
db.session.rollback()
return False
# @staticmethod
# def restore(data):
# """
# Restore the database with the data provided.
# """
# for fact in data:
# _ = fact.pop('id', None) # removes id
# event = CoolFacts.query.filter_by(coolfacts=fact['coolfacts'], age=fact['age']).first() # retrieves the event by coolfacts
# if event:
# event.update(fact)
# else:
# event = CoolFacts(**fact)
# event.create()
@staticmethod
def restore(data):
with app.app_context():
db.session.query(CoolFacts).delete()
db.session.commit()
restored_facts = {}
for fact_data in data:
fact = CoolFacts(
coolfacts=fact_data['coolfacts'],
age=fact_data['age']
)
fact.create()
restored_facts[fact_data['id']] = fact
return restored_facts
def initCoolFacts():
"""
Initializes the QuizCreation table and inserts test data for development purposes.
"""
with app.app_context():
db.create_all() # Create the database and tables
# Sample test data
quizzes = [
CoolFacts(coolfacts="Elon Musk saved Tesla from bankruptcy", age="37"),
CoolFacts(coolfacts="Messi moved to Barcelona, Spain to play soccer and recieve proper medical treatment", age="13"),
CoolFacts(coolfacts="Lebron James was scouted by the Cleveland Cavaliers and played his first NBA game there", age="18")
]
for quiz in quizzes:
try:
quiz.create()
print(f"Created quiz: {repr(quiz)}")
except IntegrityError as e:
db.session.rollback()
print(f"Record already exists or error occurred: {str(e)}")
CoolFacts Model Overview
This Python class, CoolFacts
, defines a SQLAlchemy model for storing “cool facts” in a database. Below is a breakdown of its functionality.
1. Defines the Model
- The
CoolFacts
class represents a table named'coolFacts'
in the database. - It has three columns:
id
(Primary Key, Integer)coolfacts
(String, stores the fact)age
(String, represents the age related to the fact)
2. CRUD Operations
create()
: Adds and commits a new record to the database.read()
: Returns the fact’s details as a dictionary.update()
: Updates an existing record and commits the changes.delete()
: Deletes the record from the database.
3. Data Restoration (restore()
)
- Deletes all existing records and repopulates the table using a provided dataset.
4. Database Initialization (initCoolFacts()
)
- Creates the database and tables if they don’t exist.
- Populates the table with predefined facts for testing.
Summary
This code is a database model for storing and managing cool facts, with built-in methods for creating, reading, updating, deleting, and restoring data.
5 Things I did over 12 weeks
- Coolfacts Backend and other functions
- Create datable called coolfacts with 3 channels: id, coolfacts, age
- Coolfact CRUD operations
- Create(POST): Allows users to create new coolfacts by having them input a coolfact and age. The data is validated so that you must be logged in and have filled out all the required fields to create a new coolfact and age object to be stored in the database.
- Read(GET): Retrieves and returns all coolfacts stored in the database as a list of dictionaries. Each coolfact and age coming from the database is converted into JSON dictionaries for the computer to understand.
- Update(PUT): Allows updating an existing coolfact and age by clicking the update button next to the coolfact and age. All changes are saved to the database
- Delete(DELETE): Allows a user to delete a coolfact and age based on it’s id. Both the coolfact and age is deleted from the database.
- CoolFacts Frontend
- Matched CSS styling with other group mates
- Must be logged in to see data or change data in any way
- Made Update and Delete buttons next to actual data for easy understanding of what data is changing
- Created fetch functions to send JSON requests to backend to display on frontend
- Collaboration with other groupmates
- We collaborated together to solve various errors in each others features using debugging methods such as using print statements and breakpoints to test what was happening
- We made sure each others frontend styling were similar to each others
- Each other’s feature relates to the overall theme of the project and relates to each other as well
- Deployment Testing
- Test on deployed site whether feature works
- Test on cockpit terminal whether init, restore, and backup functions operate as necessary
- Check SQLite data tables whether data is being added, updated, and removed correctly using correct sqlite commands
- Learn how to rebuild properly using the proper docker-compose command
- Changing port numbers and files to work on deployment
- Init, Backup, Restore
- Restore, Backup, and Init: Add init, backup, and restore functions to each feature(done by adding each feature to each function in main so all of them get run at once instead of one at a time)
- Add each API to main.py and functions within it
- Learn how to run an debug init, backup, and restore functions
- Load data from files: Write a function to get data from files in the backup folder
Deployment Testing
When we did deployment, my feature did not work, so I used these commands to test my database model:
- cd striverr_backend
- cd instance/volumes
- I would now access the sqlite tables on the original database by typing in; sqlite3 user_management.db
- To see all the possible databases I would type in, .schema
-
To see my specific database and it’s contents I would type in, SELECT * FROM coolFacts; These commands helped me to check whether my post, get, delete, and put functions were working as they should be
- Whenever I would make big changes to my code I would type in docker_compose down to shut down the website, docker-compose build to start the website, and docker-compose up -d to allow users to access the website via a search engine. __