Flask

장현웅·2023년 8월 15일
0

Flask

Flask는 Python의 마이크로 웹 프레임워크이다. 컴퓨터 프로그래밍에서 프레임워크는 소프트웨어의 개발에 필수적이고 표준적인 부분에 해당하는 설계와 구현을 재사용 가능하도록, 일련의 협업화된 형태의 클래스들로 제공하는 반제품 소프트웨어 모듈이라고 볼 수 있다. 간단하게 말하면, 서버를 구동시켜주는 편한 코드 모음이라고 볼 수 있고 웹 서버를 구동하는데 필요한 복잡한 코드들을 쉽게 가져다 쓸 수 있다.

프레임워크는 명확하게 정의된 API를 가지고 코드를 재사용 가능한 형태로 구조화한다는 점에서 라이브러리와 비슷하지만 라이브러리는 특정 언어를 더 쓰기 편하게 많은 기능을 미리 만들어 제공하는 것이고, 프레임워크는 특정 언어를 특화된 구조로 체계화 한 것이다. 쉽게 말해, 특정 언어를 이용해서 만든 산출물이라고 할 수 있다. Javascript와 다른 언어들도 저마다의 프레임워크와 라이브러리가 있다.

Python이 철이라고 한다면, 철이라는 재료를 사용하기 쉽게 무기(라이브러리)를 만들 수도 있고, 철로 집(프레임워크)를 지어서 어떠한 환경이나 생태계를 구성할 수 있다.

- Flask 프로젝트 폴더 구조

Flask는 만들 프로젝트의 구조가 정해져있다.

prac 폴더 구조
- - -
prac
|— venv
|— app.py (서버)
|— templates
         |— index.html (클라이언트 파일)

1) Flask로 만들 프로젝트 폴더 만들기
2) 프로젝트 폴더 안에 app.py 파일 생성
3) 가상환경(venv) 만들고 활성화하기
4) 활성화된 가상환경에서 pip install flask로 Flask 프레임워크를 설치

- Flask 기초 실행

1) Flask 시작코드를 app.py 파일에 넣고 터미널에서 실행

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is my Home!'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

2) 브라우저에 'localhost:5000' 입력

-> 내 컴퓨터에서 내가 만든 웹 서비스에 접속한 것. 인터넷 망에 오픈한 것은 아니고 나한테만 오픈해놓고 나만 보는 것.

3) 좀 더 웹사이트 느낌이 나도록 코드를 추가해보자.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is my Home!'

@app.route('/mypage') # 다른 URL을 추가한 것.
def mypage():  
   return 'This is My Page!'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

4) 브라우저에 'localhost:5000/mypage' 입력

EX) 스즈메의 문단속 영화페이지
https://movie.daum.net/moviedb/main?movieId=161806

movie.daum.net -> 은행 지점
/moviedb/main -> 창구 이름
movieId=161806 -> 데이터

?를 기준으로 앞부분이 서버 주소, 뒷부분이 데이터

5) 이번엔 'This is My Page!'대신에 버튼을 넣어보자.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is my Home!'

@app.route('/mypage')
def mypage():  
   return '<button>버튼입니다</button>' # 따옴표 꼭

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

-> 이렇게 보면 저 안에 html이나 부트스트랩 등 넣어보면 실행은 되겠지만 엄청 힘들 것이다.

프론트엔드와 백엔드가 어떻게 연결되는지 알아보자.

Flask - Html 파일과 연동해보기

prac 폴더 구조
- - -
prac
|— venv
|— app.py (서버)
|— templates
         |— index.html (클라이언트 파일)

1) 프로젝트 폴더에 'templates'폴더 만들기
2) 'templates'폴더에 'index.html'파일 만들기
3) 'index.html'파일에 예제 코드 넣기

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey(){
            alert('안녕!')
        }
    </script>
</head>
<body>
    <button onclick="hey()">나는 버튼!</button>
</body>
</html>

4) Flask의 render_template 기능을 이용하여 'index.html'을 'app.py'에 가져와보자.

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is my Home!'

@app.route('/mypage')
def mypage():  
   return render_template('index.html') 

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

-> 'index.html'이라는 프론트엔드 파일을 'app.py'라는 백엔드 서버가 돌면서 데이터를 가져다주는 것.

5) Html에 다른 태그를 붙여보자.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey(){
            alert('안녕!')
        }
    </script>
</head>
<body>
    <h1>제목을 입력합니다</h1>
    <button onclick="hey()">나는 버튼!</button>
</body>
</html>

그리고 페이지를 새로고침하면,

-> 바뀐 html을 가져다 주는 것을 볼 수 있다.

Flask - API(은행 창구에서 은행원의 역할을 하는 서버) 만들기

API 만들기 / 프론트엔드로 API를 부르기 / 데이터를 받아보기(Fetch)

  • API(Application Programming Interface)
    운영체제와 응용프로그램 사이의 통신에 사용되는 언어나 메시지 형식으로 라이브러리에 접근하기 위한 규칙들을 정의한 것
    서버가 클라이언트의 요청을 받으려면 문이 있어야 하는데 API는 은행 창구와 같이 그 창구에 접근하는 방식이다.

  • HTTP(HyperText Transfer Protocol)
    웹 서버와 사용자의 인터넷 브라우저 사이에 문서를 전송하기 위해 사용되는 통신 규약이다.

클라이언트가 요청할 때에도, "방식"이 존재한다. 클라이언트는 요청할 때 HTTP request method(요청 메소드)를 통해, 어떤 요청 종류인지 응답하는 서버 쪽에 정보를 알려주는 것이다. HTTP request method에는 여러 방식이 존재하는데, 가장 많이 쓰이는 GET, POST 방식을 주로 다뤄보자.

GET / POST 방식

  • GET

URL을 통해 모든 데이터를 전달. 통상적으로 데이터 조회(Read)를 요청할 때, 사용

예) 영화 목록 조회
→ 데이터 전달 : URL 뒤에 물음표를 붙여 key=value로 전달
→ 예) https://movie.daum.net/moviedb/main?movieId=161806

→ 물음표(?)뒤 movieId의 값에 다른 값을 넣으면 다른 페이지가 나온다.
→ 예) https://movie.daum.net/moviedb/main?movieId=161807

→ 예) https://www.google.com/search?q=스파르타코딩클럽

  • POST

GET 방식처럼 데이터가 왔다 갔다하는 것을 ?로 하는게 아니고 눈에 보이지 않는다. 컴퓨터끼리만 알아들을 수 있는 방법으로 데이터를 전달한다. 통상적으로 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때 사용

예) 회원가입(생성), 회원탈퇴(삭제), 비밀번호 수정(변경) // (회원정보 조회 - GET)
→ 데이터 전달 : 바로 보이지 않는 HTML body에 key:value 형태로 전달

- GET, POST 요청에서 클라이언트의 데이터를 받는 방법

  • GET 요청 API코드
@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})

1) Get 요청 API 코드를 app.py(백엔드)에 넣어준다.

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html') 

@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

2) API를 만들고 사용하는 과정에서 flask의 request와 jsonify 이 두 기능이 필요하다. render_template와 마찬가지로 이 두 기능도 붙여넣는다.

from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html') 

@app.route('/test', methods=['GET'])  # '/test'라는 창구로 GET요청으로 들어온다.(methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give') # 그때 'title_give'라는 데이터가 있으면 가져와서(request.args.get('title_give')) 'title_receive'라는 변수에 넣자.
   print(title_receive) # 개발자가 볼 수 있게 프린트해보자.
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})  # 백엔드에서 프론트로 데이터를 이렇게 내려주자.

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

3) 이제 HTML(프론트엔드)에서 GET 요청이 잘 되었는지 Fetch 코드를 통해 확인해보자.

GET 요청 확인 Fetch 코드

fetch("/test").then(res => res.json()).then(data => {
		console.log(data)
})

3-1) html의 hey() 함수에 GET 요청 확인 Fetch 코드 넣기

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey() {
            fetch("/test").then(res => res.json()).then(data => {
                console.log(data) // "/test"라는 URL에 요청을 해서 어떤 데이터를 받아서 콘솔에 찍자.
            })
        }
    </script>
</head>

<body>
    <h1>제목을 입력합니다</h1>
    <button onclick="hey()">나는 버튼!</button>
</body>

</html>

3-2) 이제 app.py 터미널에서 flask가 잘 실행되는지 확인하고 브라우저 localhost:5000에 가서 hey()함수 기능이 들어간 '나는 버튼!' 버튼을 누른 후 콘솔에 출력되는지 확인해보자.

→ 이 데이터는 app.py(백엔드)의 return jsonify({'result':'success', 'msg': '이 요청은 GET!'})에서 html(프론트엔드)로 내려준 것이다.

3-3) 내려주는 데이터의 메시지를 바꿔서 확인해보자.
return jsonify({'result':'success', 'msg': '이 요청은 GET!!!!!!!!!!!!!!!!!!!!'})


  • POST 요청 API코드
@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

1) POST 요청 API 코드를 app.py(백엔드)에 넣어준다.

from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html') 

@app.route('/test', methods=['POST']) # '/test'라는 창구로 POST요청으로 들어온다.(methods=['POST'])
def test_post():
   title_receive = request.form['title_give'] # 그때 'title_give'라는 데이터가 있으면 가져와서(request.args.get('title_give')) 'title_receive'라는 변수에 넣자.
   print(title_receive) # 개발자가 볼 수 있게 프린트해보자.
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'}) # 백엔드에서 프론트로 데이터를 이렇게 내려주자.

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

3) 이제 HTML(프론트엔드)에서 GET 요청이 잘 되었는지 Fetch 코드를 통해 확인해보자.

POST 요청 확인 Fetch코드

let formData = new FormData();
formData.append("title_give", "블랙팬서");

fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => {
    console.log(data)
})

3-1) html의 hey() 함수에 POST 요청 확인 Fetch 코드 넣기

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey() {
            let formData = new FormData(); // formData라는 변수를 따로 만들어서
            formData.append("title_give", "블랙팬서"); // 여기에 데이터를 실어서  // 여기 "title_give"는 app.py의 'title_receive'로 받아서 print한다.

            fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => { // 보낸다.
                console.log(data)
            })
        }
    </script>
</head>

<body>
    <h1>제목을 입력합니다</h1>
    <button onclick="hey()">나는 버튼!</button>
</body>

</html>

3-2) 이제 app.py 터미널에서 flask가 잘 실행되는지 확인하고 브라우저 localhost:5000에 가서 hey()함수 기능이 들어간 '나는 버튼!' 버튼을 누른 후 콘솔에 출력되는지 확인해보자.

3-3) 터미널에서 "블랙팬서"가 찍히는지 확인

4) 데이터 흐름 파악
→ hey() 함수의 버튼을 누른다.
→ 데이터가 쌓인다.("title_give", "블랙팬서")
→ 쌓인 데이터를 formData라는 변수에 담는다.

let formData = new FormData();
formData.append("title_give", "블랙팬서");

→ 그 데이터(formData)를 "/test"라는 곳에 보낸다(Fetch).

fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => {
	console.log(data)
            })

→ html(프론트엔드)에서 보낸 데이터는 app.py(백엔드)에서 받는다.

@app.route('/test', methods=['POST'])

→ Fetch로 가지고 온 데이터 중 "title_give"라는 것이 있는지 확인

title_receive = request.form['title_give']

→ 있는게 확인 되었다면 쌓인 데이터("블랙펜서")를 넣어준다.

title_receive = "블랙펜서"

→ 받은 데이터 출력

print(title_receive)

→ 끝났으니까 이제 백엔드(app.py)에서 프론트엔드(html)로 데이터를 내려주자.

 return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

→ 내려온 데이터가 html(프론트엔드)에 담긴 것을 확인

console.log(data)

→ 브라우저 새로고침 후 콘솔에서 내려받은 데이터 확인

console.log({'result':'success', 'msg': '이 요청은 POST!'})

0개의 댓글