[n333]Flask(2/2)
■ Key words
ㆍFlask-SQLAlchemy
ㆍMigration
ㆍFlask 구조
■ 주요내용
ㆍApplication 구조
- Flask 뼈구조
· 프로젝트 구조 : config.py - 프로젝트에 대한 전반적인 설정 / flask_app - app 폴더를 독립 패키지로 관리
· Application 구조 : 한 개의 파일로 관리할 수도 있지만, 여러 개의 파일로 나누어 관리하기 위해서는
폴더로 만들고, __init__.py를 각 폴더에 넣어주어 폴더가 패키지로 인식되도록 한다.
· __init__.py : Flask 어플리케이션 실행을 위한 초기 app 제공
· models.py : 모델 정보, 데이터베이스 기능 등을 담는 파일
· services : 어플리케이션에서 사용하는 서비스를 담는 파일
· static : CSS 등의 정적 파일 등을 담음
· templates : Flask에서 클라이언트에 전달할 수 있는 HTML 리소스를 담음
· views : Flask 어플리케이션에서 사용되는 라우트들을 세분화해서 담고 있음
- 모델 관리
- 서비스 폴더 : app.과 서비스를 분리하면 상호의존적이지 않게 되어 더 편하고, 디버깅이 편리해져 관리의 효율성이 높아침
- 라우트 관리 : app.의 복잡성이 높아질 수록(기능이 많고 라우트가 세분화될 수록) 구조 구성에 따른 관리 편이성이 달라짐 / 파일마다 라우트 관리 혹은 기능 위주로 파일 관리 가능
ㆍFlask Database
- Flask SQLAlchemy : Flask에서 SQLAlchemy를 사용하기 위한 패키지
⇒ ORM 방식으로 작동 가능 / table을 python class로 정의하여 접근 가능
* 설치 : pip install flask-sqlalchemy
- Database Model : python class로 model 생성 가능
- Database 연결하기
· 기본연결 : SQLAlchemy의 DB engine 설정과 같이 초기 설정 필요
⇒ db = SQLAlchemy(app)으로 인스턴스 생성
· Flask-SQLAlchemy와 Application Factory 패턴 : Flask의 유연성으로 인해 db 등 객체 위치에 따라
오류가 발생할 수 있음
· Circular Import : App. Factory 패턴에서 DB 객체(object)를 import 할 때 발생할 수 있는 상황
⇒ 순환참조의 오류; 코드가 import에서 순환참조를 하며 아래로 내려갈 수 없음
* 해결방안 : import하는 위치는 최상위가 아닌 필요한 해당 함수(def) 안으로 지정
- Flask-Migrate : git과 같이 python에서 변경된 코드로 변화된 DB의 구조, 모델 등을 추적하고 기록해
DB에 저장할 수 있는 도구 / Alembic이라는 도구를 통해 작동
⇒ Flask의 SQLAlchemy를 활용한 DB의 Migration 담당
* 설치 : pip install Flask-Migrate
· 주요 기능 : library에서 자동으로 model의 변경사항 추적 가능 / downgrade로 update 취소도 가능
· CLI 명령어 : db는 reset 보다는 update(upgrade)/migration을 많이 함; CLI를 통해 명령 가능
· Application Factory 패턴 : 함수 밖에서 migrate 인스턴스 생성 후 함수 내부에서 init_app method를 통해 설정
ㆍEmbedding API : text를 vector로 변경해주는 서비스 library. client/server 두 가지로 구성
* 예시 : iris dataset을 이용하여 Logistic Regression 적용
* 설치 : pip install embedding-as-service-client
- 서버연결 : from embedding_as_service_client import EmbeddingClient
en = EmbeddingClient(host='<호스트 주소>', port=<포트번호>)
- 활용 : 서버연결 시 생성한 인스턴스(en) 활용
· encode() : 서버에 texts라는 파라미터를 받아 처리해주는 기능
· text_list : 서버에 보내게 될 list(최대 1,000개)
· vecs : 서버로 보낸 데이터가 벡터화되어 돌아온 결과 저장(100개의 벡터로 구성된 list)
- GloVe(Global Vectors for Word Representation) : twitter 글을 vector화 가능
- 작업 흐름 : LogistcRegression을 활용한 예시
■ Session note
ㅁ 오전 session
ㆍmodel.py에 다 넣지 못할 때 models 폴더를 만들고 __init__.py 파일을 만들어 여러 개 파일을 모듈로 관리할 수 있음
ㆍroute가 너무 많은 때 blue print를 통해 세부 end point를 만드는 것
ㆍmodel 클래스는 python
ㆍFlask SQLAlchemy는 session이 계속 열려 있으면 메모리를 잡아먹기 때문에 자동으로 닫아줌
; 무게를 덜어주는 것
- commit을 하게 되면 해당 객체(object)에 대한 관리가 필요 없어지기 떄문에 제거해줌
ㆍembedding 사용 시 필요 module : numpy, zmq(flask와 비슷한 기능),
- python -m pip install embedding-as-service- client numpy, zmq
- en = EmbeddingClient(host='13.124.31.20', port=8989)(AWS cloud computer address)
cf> flask는 port=5000 / 파일의 embedding_app.py 파일의 주소 수정 필요
- en.encode(texts=['spongebob', 'patrick']
... ) : list 하나하나마다 벡터화 시킴
- GloVe(논문) : vector화 설명 논문
⇒ twitter_100 model : twit에 특화되어 vector화를 100개를 해줌
ㆍCircular Import : 순환하여 import를 계속함; 여러 파일에서 순환참조
* code .로 vs code 실행 및 파일 추가하기
- FLASK_APP=flask_app flask run : __init__.py 실행
* flask_app에서 import 할 경우 __init__.py에서 불러옴
⇒ 파일을 기억하지 않고 import를 할 때만 불러오기 때문에 db를 앞으로 꺼내놓고, import를 register 하기 전에 넣어줌(from flask_app import main_routes)
ㆍflask_sqlalchemy에서 app.config는 sqlalchemy에서 엔진의 역할이 아니라 주소의 역할이다
- 주소만 지정해주면 알아서 engine을 만들어 관리해줌(db.init_app(app))
ㅁ 오후 session
ㆍBlueprint에서 동일하게 'user'로 객체 지정. main_route.py는 'main'으로 지정
-
ㆍsimple flask : 아래쪽만 해결하면 됨(routing; end point 등록 연습 필요)
* flask jsonify : json.dumps에서 추가적으로 다뤄야 할 것을 한 번에 처리를 해줌
→ dictionary를 json으로 바꿔줌
* route 설정 : @app.route('/users/', dfaults={'user_order':1})
@app.route('/users/<user_order>') : 문자열
→ @app.route('/users/<int:user_order>') ; type 확인!!!
⇒ flask의 유연성이 없으므로, 둘 다 넣어줘야 함
* csv 읽어오기 → list에 담기 → 경로 만들어주기/경로 알려주기/ return username_list[int(user_order)-1]
⇒ csv 읽어 오는 코드 외어두기
* int() : type 변경 →
cf> flask endpoint int
* port(5000)이 열려있으면 다른 포트로 열어야 한다
cf> ctrl d : quit(logout)
ctrl c : cancel
ctrl z : suspend - 뒤에 process 숨겨주는 역할
* from flask import request : query parameter를 가져올 때 flask에서 request를 가져와야 함
→ variable_name = request.args.get('username') ; request.args사용 가능
■ 주요함수
ㆍ
■ Reference
ㆍ