def create_app(test_config=None): app = Flask(__name__) CORS(app) if test_config is None: app.config.from_pyfile("config.py") else: app.config.update(test_config) database = create_engine( app.config['DB_URL'], encoding='UTF-8', max_overflow=0) userDao = UserDao(database) tweetDao = TweetDao(database) service = Service() service.tweet_service = TweetService(tweetDao) service.user_service = UserService(userDao, app.config) create_endpoints(app, service) return app
def create_app(test_config = None): #import한 Flask 클래스 객체화시켜서 app에 저 app = Flask(__name__) #CORS 문제 해결 위함 CORS(app) if test_config is None: app.config.from_pyfile("config.py") else: app.config.update(test_config) database = create_engine(app.config['DB_URL'], encoding= 'utf-8', max_overflow = 0) user_dao = UserDao(database) tweet_dao = TweetDao(database) services = Services services.user_service = UserService(user_dao, app.config) services.tweet_service = TweetService(tweet_dao) create_endpoints(app, services) return app
def create_app(test_config=None): app = Flask(__name__) cors = CORS(app, resources={r"/*": {"origins": "*"}}) if test_config is None: app.config.from_pyfile("config.py") else: app.config.update(test_config) database = create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0) ## Persistenace Layer user_dao = UserDao(database) store_dao = StoreDao(database) category_dao = CategoryDao(database) menu_dao = MenuDao(database) order_dao = OrderDao(database) ## Business Layer s3_client = boto3.client("s3", aws_access_key_id=app.config['S3_ACCESS_KEY'], aws_secret_access_key=app.config['S3_SECRET_KEY'], region_name='ap-northeast-2') services = Services services.user_service = UserService(user_dao, app.config, s3_client) services.store_service = StoreService(store_dao, app.config, s3_client) services.menu_service = MenuService(menu_dao, app.config, s3_client) services.order_service = OrderService(order_dao) services.category_service = CategoryService(category_dao) socket_io = SocketIO(app, cors_allowed_origins="*") ## 엔드포인트들을 생성 create_endpoints(app, services, socket_io) return app, socket_io
def create_app(test_config = None): app = Flask(__name__) #SetUp CORS CORS(app) #SetUp config if test_config is None: app.config.from_pyfile('config.py') else: app.config.update(test_config) #SetUp Persistence Layer user_dao = UserDao() #SetUp Business Layer services = Services services.user_service = UserService(user_dao) #SetUp Presentation Layer create_endpoints(app, services) return app
def create_app(test_config=None): app=Flask(__name__) CORS(app) if test_config is None: app.config.from_pyfile('config.py') else: app.config.update(test_config) database=create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0) # persistence layer user_dao=UserDao(database) tweet_dao=TweetDao(database) # business layer services=Service() services.user_service=UserService(user_dao,app.config) services.tweet_service=TweetService(tweet_dao) # create endpoint create_endpoints(app,services) return app
def user_dao(): return UserDao(database)
def user_service(): mock_s3_client = mock.Mock() return UserService(UserDao(database), config.test_config, mock_s3_client)
def create_app(test_config=None): app = Flask(__name__) CORS(app) if test_config is None: app.config.from_pyfile("config.py") else: app.config.update(test_config) database = create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0) ## Persistenace Layer user_dao = UserDao(database) tweet_dao = TweetDao(database) ## Business Layer services = Services services.user_service = UserService(user_dao, config) services.tweet_service = TweetService(tweet_dao) ## 엔드포인트들을 생성 create_endpoints(app, services) return app # import jwt # import bcrypt # # from flask import Flask, request, jsonify, current_app, Response, g # from flask.json import JSONEncoder # from sqlalchemy import create_engine, text # from datetime import datetime, timedelta # from functools import wraps # from flask_cors import CORS # # # ## Default JSON encoder는 set를 JSON으로 변환할 수 없다. # ## 그럼으로 커스텀 엔코더를 작성해서 set을 list로 변환하여 # ## JSON으로 변환 가능하게 해주어야 한다. # class CustomJSONEncoder(JSONEncoder): # def default(self, obj): # if isinstance(obj, set): # return list(obj) # # return JSONEncoder.default(self, obj) # # # def get_user(user_id): # user = current_app.database.execute(text(""" # SELECT # id, # name, # email, # profile # FROM users # WHERE id = :user_id # """), { # 'user_id': user_id # }).fetchone() # # return { # 'id': user['id'], # 'name': user['name'], # 'email': user['email'], # 'profile': user['profile'] # } if user else None # # # def insert_user(user): # return current_app.database.execute(text(""" # INSERT INTO users ( # name, # email, # profile, # hashed_password # ) VALUES ( # :name, # :email, # :profile, # :password # ) # """), user).lastrowid # # # def insert_tweet(user_tweet): # return current_app.database.execute(text(""" # INSERT INTO tweets ( # user_id, # tweet # ) VALUES ( # :id, # :tweet # ) # """), user_tweet).rowcount # # # def insert_follow(user_follow): # return current_app.database.execute(text(""" # INSERT INTO users_follow_list ( # user_id, # follow_user_id # ) VALUES ( # :id, # :follow # ) # """), user_follow).rowcount # # # def insert_unfollow(user_unfollow): # return current_app.database.execute(text(""" # DELETE FROM users_follow_list # WHERE user_id = :id # AND follow_user_id = :unfollow # """), user_unfollow).rowcount # # # def get_timeline(user_id): # timeline = current_app.database.execute(text(""" # SELECT # t.user_id, # t.tweet # FROM tweets t # LEFT JOIN users_follow_list ufl ON ufl.user_id = :user_id # WHERE t.user_id = :user_id # OR t.user_id = ufl.follow_user_id # """), { # 'user_id': user_id # }).fetchall() # # return [{ # 'user_id': tweet['user_id'], # 'tweet': tweet['tweet'] # } for tweet in timeline] # # # def get_user_id_and_password(email): # row = current_app.database.execute(text(""" # SELECT # id, # hashed_password # FROM users # WHERE email = :email # """), {'email': email}).fetchone() # # return { # 'id': row['id'], # 'hashed_password': row['hashed_password'] # } if row else None # # # ######################################################### # # Decorators # ######################################################### # def login_required(f): # @wraps(f) # def decorated_function(*args, **kwargs): # access_token = request.headers.get('Authorization') # if access_token is not None: # try: # payload = jwt.decode(access_token, current_app.config['JWT_SECRET_KEY'], 'HS256') # except jwt.InvalidTokenError: # payload = None # # if payload is None: return Response(status=401) # # user_id = payload['user_id'] # g.user_id = user_id # g.user = get_user(user_id) if user_id else None # else: # return Response(status=401) # # return f(*args, **kwargs) # # return decorated_function # # # def create_app(test_config=None): # app = Flask(__name__) # # CORS(app) # # app.json_encoder = CustomJSONEncoder # # if test_config is None: # app.config.from_pyfile("config.py") # else: # app.config.update(test_config) # # database = create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0) # app.database = database # # @app.route("/ping", methods=['GET']) # def ping(): # return "pong" # # @app.route("/sign-up", methods=['POST']) # def sign_up(): # new_user = request.json # new_user['password'] = bcrypt.hashpw( # new_user['password'].encode('UTF-8'), # bcrypt.gensalt() # ) # # new_user_id = insert_user(new_user) # new_user = get_user(new_user_id) # # return jsonify(new_user) # # @app.route('/login', methods=['POST']) # def login(): # credential = request.json # email = credential['email'] # password = credential['password'] # user_credential = get_user_id_and_password(email) # # if user_credential and bcrypt.checkpw(password.encode('UTF-8'), # user_credential['hashed_password'].encode('UTF-8')): # user_id = user_credential['id'] # payload = { # 'user_id': user_id, # 'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24) # } # token = jwt.encode(payload, app.config['JWT_SECRET_KEY'], 'HS256') # # return jsonify({ # 'user_id': user_id, # 'access_token': token.decode('UTF-8') # }) # else: # return '', 401 # # @app.route('/tweet', methods=['POST']) # @login_required # def tweet(): # user_tweet = request.json # user_tweet['id'] = g.user_id # tweet = user_tweet['tweet'] # # if len(tweet) > 300: # return '300자를 초과했습니다', 400 # # insert_tweet(user_tweet) # # return '', 200 # # @app.route('/follow', methods=['POST']) # @login_required # def follow(): # payload = request.json # payload['id'] = g.user_id # # insert_follow(payload) # # return '', 200 # # @app.route('/unfollow', methods=['POST']) # @login_required # def unfollow(): # payload = request.json # payload['id'] = g.user_id # # insert_unfollow(payload) # # return '', 200 # # @app.route('/timeline/<int:user_id>', methods=['GET']) # def timeline(user_id): # return jsonify({ # 'user_id': user_id, # 'timeline': get_timeline(user_id) # }) # # @app.route('/timeline', methods=['GET']) # @login_required # def user_timeline(): # user_id = g.user_id # # return jsonify({ # 'user_id': user_id, # 'timeline': get_timeline(user_id) # }) # # return app
def user_service(mock_boto3): mock_boto3.client.return_value = mock.Mock() userDao = UserDao(database) return UserService(userDao, config.test_config)
def create_app(test_config=None): class Services: pass app = Flask(__name__) CORS(app) app.config.from_pyfile("config.py") # 테스트 데이터 베이스 업데이트 if test_config: app.config.update(test_config) database = create_engine(app.config['DB_URL'], encoding='utf-8', max_overflow=0) app.database = database # 에러 처리 app.register_error_handler(KeyError, handle_key_error) app.register_error_handler(ValidationError, handle_validation_error) app.register_error_handler(LoginError, handle_login_error) ## Persistenace Layer user_dao = UserDao(database) company_dao = CompanyDao(database) request_dao = RequestDao(database) car_dao = CarDao(database) suggestion_dao = SuggestionDao(database) ## Business Layer services = Services services.user_service = UserService(user_dao, company_dao, config, database) services.company_service = CompanyService(company_dao) services.request_service = RequestService(request_dao, database) services.suggestion_service = SuggestionService(suggestion_dao, request_dao, database) ## 엔드포인트들을 생성 create_endpoints(app, services) ## 채팅을 위한 socket생성 socketio = SocketIO(app, cors_allowed_origins='*') @socketio.on('connect') def connect(): print('Client connected') messages = database.execute(""" SELECT * FROM chats """).fetchall() messages = [dict(message) for message in messages] for message in messages: message['created_at'] = str(message['created_at']) socketio.emit('message', messages) @socketio.on('send_message') def handle_message(message): request_id = message['request_id'] name = message['name'] text = message['text'] try: connection = database.connect() trans = connection.begin() connection.execute( """ INSERT INTO chats ( request_id, name, text ) VALUES ( %s, %s, %s ) """, (request_id, name, text)) trans.commit() except: trans.rollback() chat_messages = database.execute(""" SELECT * FROM chats """).fetchall() messages = [dict(chat_message) for chat_message in chat_messages] for msg in messages: msg['created_at'] = str(msg['created_at']) socketio.emit('message', messages) return app
def user_service(): return UserService(UserDao(database), config)
# ORM 자동 매핑시에는 아래의 옵션과 같이 활성화 : 본 프로젝트는 DBA와 협업 및 빠르고 직관적인 유지관리 사업을 고려하여 text방식의 SQL문 사용 # models.db.init_app(app) # # 서비스 실행순서 참고사항 # before_first_request : 웹 어플리케이션 기동 이후 가장 처음에 들어오는 요청에서만 실행 # before_request : 매 요청시 실행 # after_request : 요청이 끝나 브라우저에 응답하기 전에 실행 # teardown_request : 요청의 결과가 브라우저에 응답하고 난뒤 실행 # teardown_appcontext : HTTP 요청이 완료 되면 실행 되며, 애플리케이션 컨텍스트 내에서 실행 # # 레이어드(Layered) 아키텍처 패턴 적용 # ######################################################### # Persistence Layer ######################################################### user_dao = UserDao(session) dept_dao = DeptDao(session) ######################################################### # Business Layer ######################################################### services = Services services.user_service = UserService(user_dao, app.config) services.dept_service = DeptService(dept_dao) ######################################################### # Presentation Layer ######################################################### user_service = services.user_service dept_service = services.dept_service
class UserService: """ Business Layer Attributes: user_dao : UserDao 클래스 Author: 김민구 History: 2020-12-28(김민구): 초기 생성 2020-12-31(김민구): user_dao를 import 해서 사용하는 방법으로 수정 """ def __init__(self, config): self.config = config self.user_dao = UserDao() def sign_up_logic(self, data, connection): """ 유저생성 Args: data : View 에서 넘겨받은 dict 객체 connection : 데이터베이스 연결 객체 Author: 김민구 Returns: None Raises: 400, {'message': 'key_error', 'error_message': format(e)} : 잘못 입력된 키값 403, {'message': 'user_already_exist', 'error_message': '이미 사용중인 [데이터] 입니다.'} : 중복 유저 존재 History: 2020-12-28(김민구): 초기 생성 2020-12-31(김민구): 에러 문구 변경 """ username_check = self.user_dao.username_exist_check(connection, data) email_check = self.user_dao.email_exist_check(connection, data) phone_check = self.user_dao.phone_exist_check(connection, data) if username_check or email_check or phone_check: raise UserAlreadyExist('이미 사용중인 ' + ', '.join( (' username' * username_check + ' email' * email_check + ' phone' * phone_check).split()) + ' 입니다.') data['permission_type_id'] = 3 data['password'] = bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt()).decode('utf-8') account_id = self.user_dao.create_account(connection, data) data['account_id'] = account_id self.user_dao.create_user(connection, data) def sign_in_logic(self, data, connection): """ 유저 로그인 Args: data : View 에서 넘겨받은 dict 객체 connection : 데이터베이스 연결 객체 Author: 김민구 Returns: token Raises: 400, {'message': 'key_error', 'error_message': format(e)} : 잘못 입력된 키값 403, {'message': 'invalid_user', 'error_message': '로그인에 실패했습니다.'} : 로그인 실패 History: 2020-12-29(김민구): 초기 생성 2020-12-31(김민구): 에러 문구 변경 """ user = self.user_dao.get_user_information(connection, data) if not user or not bcrypt.checkpw(data['password'].encode('utf-8'), user['password'].encode('utf-8')): raise InvalidUser('로그인에 실패했습니다.') token = self.token_generator(user) return token def token_generator(self, user): """ 토근 생성기 Args: user : 유저 Author: 김민구 Returns: token Raises: 400, {'message': 'key_error', 'error_message': format(e)} : 잘못 입력된 키값 500, {'message': 'create_token_denied', 'error_message': '로그인에 실패했습니다.'} : 토큰 생성 실패 History: 2020-12-29(김민구): 초기 생성 2020-12-31(김민구): 에러 문구 변경 """ payload = { 'account_id': user['id'], 'username': user['username'], 'permission_type_id': user['permission_type_id'], 'exp': datetime.utcnow() + timedelta(hours=5) } token = jwt.encode(payload, self.config['JWT_SECRET_KEY'], self.config['JWT_ALGORITHM']).decode('utf-8') if not token: raise TokenCreateDenied('로그인에 실패했습니다.') return token def social_sign_in_logic(self, connection, data): """ 소셜 유저 로그인 Args: data : View 에서 넘겨받은 dict 객체 connection : 데이터베이스 연결 객체 Author: 김민구 Returns: token Raises: 400, {'message': 'key_error', 'error_message': format(e)} : 잘못 입력된 키값 403, {'message': 'invalid_user', 'error_message': '구글 소셜 로그인에 실패했습니다.'} : 유효하지 않은 유저 History: 2020-12-29(김민구): 초기 생성 2020-12-31(김민구): 에러 문구 변경 2021-01-05(김민구): 기존 회원이 존재할 때 username이 달라서 생기는 이슈를 제거함 Notes: 테이블 구조를 바꿔야 합당하나 시간관계상 그냥 진행 - accounts와 1대1관계인 social_users 필요 - 여러 가지 소셜 플랫폼을 관리하는 테이블인 social_platforms 필요 소셜회원은 email주소를 아이디로 판단 소셜회원은 브랜디 계정 전환 전까지 일반 로그인을 할 수가 없다.(비밀번호가 없다) 소셜회원이 브랜디 계정으로 전환할 시 "@소셜 플랫폼 주소"를 제거해서 브랜디 회원에 해당 아이디가 존재하는 지 확인 아이디가 없다면 그 아이디 그대로 회원가입 진행 중복 아이디라면 아이디를 바꿔서 가입할 수 있게 만든다. """ email_check = self.user_dao.email_exist_check(connection, data) if not email_check: data['username'] = data['email'] data['permission_type_id'] = 3 account_id = self.user_dao.social_create_account(connection, data) data['account_id'] = account_id self.user_dao.social_create_user(connection, data) user = self.user_dao.get_user_information(connection, data) else: data['account_id'] = self.user_dao.get_account_id(connection, data) user = self.user_dao.get_user_information(connection, data) if not user: raise InvalidUser('구글 소셜 로그인에 실패했습니다.') token = self.token_generator(user) return token
def __init__(self, config): self.config = config self.user_dao = UserDao()