-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from Matsadura/BaseModel
[FIX/ADD] Fix IMPORTANT BROKEN docker errors, ADD Base Database Schema…
- Loading branch information
Showing
14 changed files
with
308 additions
and
10 deletions.
There are no files selected for viewing
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
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 |
---|---|---|
@@ -1,6 +1,2 @@ | ||
MOVIE_API_HOST=0.0.0.0 | ||
MOVIE_API_PORT=5000 | ||
MOVIE_DB_HOST=mysql_db | ||
MOVIE_DB_USER=CINEMA_USER | ||
MOVIE_DB_PASSWORD=CINEMA_PASSWORD | ||
MOVIE_DB_NAME=CINEMA_DB |
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
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,8 @@ | ||
#!/usr/bin/python3 | ||
""" Contains the flask blueprint """ | ||
from flask import Blueprint | ||
|
||
app_views = Blueprint('app_views', __name__, url_prefix="/api") | ||
|
||
from api.views.users import * # nopep8 | ||
from api.views.index import * # nopep8 |
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,23 @@ | ||
#!/usr/bin/python3 | ||
"""Metrics Routes""" | ||
from api.views import app_views | ||
|
||
|
||
@app_views.route('/status') | ||
def status(): | ||
"""Return the API status all wrapped in a json object""" | ||
return {"status": "OK"}, 200 | ||
|
||
|
||
@app_views.route('stats') | ||
def stats(): | ||
"""Return the count of all classes""" | ||
from models.user import User | ||
from models.mood import Mood | ||
from models.recommendation import Recommendation | ||
from models import storage | ||
|
||
return {"Users": storage.count(User), | ||
"Moods": storage.count(Mood), | ||
"Recommendations": storage.count(Recommendation) | ||
} |
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 |
---|---|---|
@@ -1,11 +1,23 @@ | ||
FROM python:3.8-slim | ||
|
||
RUN apt-get update && apt-get upgrade -y | ||
RUN apt-get install -y pkg-config | ||
RUN apt-get install -y default-libmysqlclient-dev | ||
RUN apt-get install -y build-essential | ||
|
||
WORKDIR /movie_name | ||
|
||
COPY . /movie_name | ||
|
||
RUN pip3 install flask==2.1.0 werkzeug==2.1.1 flask-cors==4.0.1 sqlalchemy==1.4.22 python-dotenv | ||
RUN pip3 install flask==2.1.0 werkzeug==2.1.1 flask-cors==4.0.1 sqlalchemy==1.4.22 mysqlclient==2.2.4 python-dotenv | ||
|
||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* | ||
|
||
EXPOSE 5000 | ||
|
||
CMD ["python3", "-m", "server.api.app"] | ||
COPY wait-for-mysql.sh /usr/local/bin/wait-for-mysql.sh | ||
RUN chmod +x /usr/local/bin/wait-for-mysql.sh | ||
|
||
WORKDIR /movie_name/server | ||
|
||
CMD ["wait-for-mysql.sh", "python3", "-m", "api.app"] |
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,8 @@ | ||
#!/usr/bin/python3 | ||
"""Initialize the models package.""" | ||
|
||
from models.engine.db_storage import DBStorage | ||
|
||
|
||
storage = DBStorage() | ||
storage.reload() |
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,75 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
Contains class BaseModel | ||
""" | ||
|
||
from datetime import datetime | ||
import models | ||
from sqlalchemy import Column, String, DateTime | ||
from sqlalchemy.ext.declarative import declarative_base | ||
import uuid | ||
|
||
time = "%Y-%m-%dT%H:%M:%S.%f" | ||
Base = declarative_base() | ||
|
||
|
||
class BaseModel: | ||
"""The BaseModel class from which future classes will be derived""" | ||
id = Column(String(60), primary_key=True) | ||
created_at = Column(DateTime, default=datetime.utcnow) | ||
updated_at = Column(DateTime, default=datetime.utcnow) | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""Initialization of the base model""" | ||
if kwargs: | ||
for key, value in kwargs.items(): | ||
if key != "__class__": | ||
setattr(self, key, value) | ||
if kwargs.get("created_at", None) and type(self.created_at) is str: | ||
self.created_at = datetime.strptime(kwargs["created_at"], time) | ||
else: | ||
self.created_at = datetime.utcnow() | ||
if kwargs.get("updated_at", None) and type(self.updated_at) is str: | ||
self.updated_at = datetime.strptime(kwargs["updated_at"], time) | ||
else: | ||
self.updated_at = datetime.utcnow() | ||
if kwargs.get("id", None) is None: | ||
self.id = str(uuid.uuid4()) | ||
else: | ||
self.id = str(uuid.uuid4()) | ||
self.created_at = datetime.utcnow() | ||
self.updated_at = self.created_at | ||
|
||
def __str__(self): | ||
"""String representation of the BaseModel class""" | ||
return "[{:s}] ({:s}) {}".format(self.__class__.__name__, self.id, | ||
self.__dict__) | ||
|
||
def __repr__(self): | ||
"""String representation of the BaseModel class""" | ||
return "[{:s}] ({:s}) {}".format(self.__class__.__name__, self.id, | ||
self.__dict__) | ||
|
||
def save(self): | ||
"""Updates the attribute 'updated_at' with the current datetime""" | ||
self.updated_at = datetime.utcnow() | ||
models.storage.new(self) | ||
models.storage.save() | ||
|
||
def to_dict(self): | ||
"""Returns a dictionary containing all keys/values of the instance""" | ||
new_dict = self.__dict__.copy() | ||
if "created_at" in new_dict: | ||
new_dict["created_at"] = new_dict["created_at"].strftime(time) | ||
if "updated_at" in new_dict: | ||
new_dict["updated_at"] = new_dict["updated_at"].strftime(time) | ||
new_dict["__class__"] = self.__class__.__name__ | ||
if "_sa_instance_state" in new_dict: | ||
del new_dict["_sa_instance_state"] | ||
if "password" in new_dict: | ||
del new_dict["password"] | ||
return new_dict | ||
|
||
def delete(self): | ||
"""Delete the current instance from the storage""" | ||
models.storage.delete(self) |
Empty file.
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,83 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
Contains the class DBStorage | ||
""" | ||
|
||
from models.base_model import BaseModel, Base | ||
from models.mood import Mood | ||
from models.recommendation import Recommendation | ||
from models.user import User | ||
from os import getenv | ||
from sqlalchemy import create_engine | ||
from sqlalchemy.orm import scoped_session, sessionmaker | ||
|
||
classes = {"Mood": Mood, "Recommendation": Recommendation, "User": User} | ||
|
||
|
||
class DBStorage: | ||
"""Interaacts with the MySQL database""" | ||
__engine = None | ||
__session = None | ||
|
||
def __init__(self): | ||
"""Instantiate a DBStorage object""" | ||
MOVIE_DB_USER = getenv('MOVIE_DB_USER') | ||
MOVIE_DB_PASSWORD = getenv('MOVIE_DB_PASSWORD') | ||
MOVIE_DB_HOST = getenv('MOVIE_DB_HOST') | ||
MOVIE_DB_NAME = getenv('MOVIE_DB_NAME') | ||
self.__engine = create_engine('mysql+mysqldb://{}:{}@{}/{}'. | ||
format(MOVIE_DB_USER, | ||
MOVIE_DB_PASSWORD, | ||
MOVIE_DB_HOST, | ||
MOVIE_DB_NAME)) | ||
|
||
def all(self, cls=None): | ||
"""query on the current database session""" | ||
new_dict = {} | ||
for clss in classes: | ||
if cls is None or cls is classes[clss] or cls is clss: | ||
objs = self.__session.query(classes[clss]).all() | ||
for obj in objs: | ||
key = obj.__class__.__name__ + '.' + obj.id | ||
new_dict[key] = obj | ||
return (new_dict) | ||
|
||
def new(self, obj): | ||
"""Add the object to the current database session""" | ||
self.__session.add(obj) | ||
|
||
def save(self): | ||
"""Commit all changes of the current database session""" | ||
self.__session.commit() | ||
|
||
def delete(self, obj=None): | ||
"""Delete from the current database session obj if not None""" | ||
if obj is not None: | ||
self.__session.delete(obj) | ||
|
||
def reload(self): | ||
"""Reloads data from the database""" | ||
Base.metadata.create_all(self.__engine) | ||
sess_factory = sessionmaker(bind=self.__engine, expire_on_commit=False) | ||
Session = scoped_session(sess_factory) | ||
self.__session = Session | ||
|
||
def close(self): | ||
"""Call remove() method on the private session attribute""" | ||
self.__session.remove() | ||
|
||
def get(self, cls, id): | ||
"""Returns the object based on the class and its ID, | ||
or None if not found""" | ||
objs = self.all(cls).values() | ||
for obj in objs: | ||
if obj.id == id: | ||
return obj | ||
return None | ||
|
||
def count(self, cls=None): | ||
""" | ||
Returns the number of objects in storage matching the given class. | ||
If no class is passed, returns the count of all objects in storage. | ||
""" | ||
return len(self.all(cls).keys()) |
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 @@ | ||
#!/usr/bin/env python3 | ||
"""Holds class Mood""" | ||
from models.base_model import BaseModel, Base | ||
from sqlalchemy import Column, String | ||
from sqlalchemy.orm import relationship | ||
|
||
|
||
class Mood(BaseModel, Base): | ||
"""Representation of a user """ | ||
__tablename__ = 'moods' | ||
mood = Column(String(24), nullable=False) | ||
recommendations = relationship("Recommendation", | ||
back_populates="mood", | ||
cascade="all, delete-orphan") | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""Initializes user""" | ||
super().__init__(*args, **kwargs) |
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,26 @@ | ||
#!/usr/bin/env python3 | ||
"""Holds class Recommendation""" | ||
from models.base_model import BaseModel, Base | ||
from sqlalchemy import Column, String, Boolean, ForeignKey | ||
from sqlalchemy.orm import relationship | ||
|
||
|
||
class Recommendation(BaseModel, Base): | ||
"""Representation of a vault """ | ||
__tablename__ = 'Recommendation' | ||
user_id = Column(String(128), | ||
ForeignKey('users.id', ondelete='CASCADE'), | ||
nullable=False) | ||
mood_id = Column(String(128), | ||
ForeignKey('moods.id', ondelete='CASCADE'), | ||
nullable=False) | ||
weather = Column(String(128), nullable=False) | ||
recommendaton = Column(String(128), nullable=True) | ||
seen = Column(Boolean, nullable=False) | ||
like = Column(Boolean, nullable=False) | ||
mood = relationship("Mood", back_populates="recommendations") | ||
user = relationship("User", back_populates="recommendations",) | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""initializes vault""" | ||
super().__init__(*args, **kwargs) |
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,25 @@ | ||
#!/usr/bin/env python3 | ||
"""Holds class User""" | ||
from models.base_model import BaseModel, Base | ||
from sqlalchemy import Column, String | ||
from sqlalchemy.orm import relationship | ||
import hashlib | ||
|
||
|
||
class User(BaseModel, Base): | ||
"""Representation of a user """ | ||
__tablename__ = 'users' | ||
email = Column(String(128), nullable=False) | ||
password = Column(String(128), nullable=False) | ||
first_name = Column(String(128), nullable=False) | ||
last_name = Column(String(128), nullable=False) | ||
recent_mood = Column(String(24), nullable=False) | ||
recommendations = relationship("Recommendation", | ||
back_populates="user", | ||
cascade="all, delete-orphan") | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""Initializes user""" | ||
kwargs["password"] = hashlib.sha256( | ||
kwargs["password"].encode()).hexdigest() | ||
super().__init__(*args, **kwargs) |
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,3 @@ | ||
#!/bin/sh | ||
sleep 10 | ||
exec "$@" |