[웹개발] Flask / API

2023. 1. 5. 11:06자격증(다다익선)/웹개발(HTML,Javascript)

728x90

https://chanytv.tistory.com/140

 

[웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초

[웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보니 나 또한 이 프로그램을 쓰지만 무료로 제공되는 프로그램도 많다고

chanytv.tistory.com

https://chanytv.tistory.com/141

 

[웹개발] 부트스트랩 & 폰트 / Javascript 기초

https://chanytv.tistory.com/140 [웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초 [웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보

chanytv.tistory.com

https://chanytv.tistory.com/144

 

[웹개발] jQuery & Ajax

https://chanytv.tistory.com/140 [웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초 [웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보

chanytv.tistory.com

https://chanytv.tistory.com/146

 

[웹개발] 파이썬 & mongoDB

https://chanytv.tistory.com/140 [웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초 [웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보

chanytv.tistory.com

 

[웹개발] Flask / API


Flask

 

Flask는 뭔가 찾아봤다. Python Web Framework 즉 간단한 웹사이트를 만들거나 API를 만들 때 사용하는 것이다. 간단한 코드 몇 줄로 서버를 만든다 생각하면 될 듯하다. 파이참을 통해 작업 중이니 사용하는 프로그램에 맞춰 환경설정을 먼저 해줘야 한다. 이후 app.py란 파일을 하나 만드는데, 통상적으로 가장 많이 사용하는 이름이라 한다.

 

기본 코드는 아래와 같다.

from flask import Flask
app = Flask(__name__)

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

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

참 이 짧은 코드 몇 줄로 서버가 만들어진다는게 신기하긴 하다.

실행을 시킨 후 웹브라우저에 http://localhost:5000 입력하면 내가 입력한 값이 뜨는 것을 확인할 수 있다.

새로운 페이지를 추가하는 방법은 무엇일까? @app.route('/')에서 경로만 바꿔주면 된다. 예를들 아래와 같이 하면 된다.

@app.route('/mypage')
def mypage():  
   return 'This is My Page!'

폴더구성도 항상 아래와 같이 해야 한다. 안 하면 큰 일어난가 보다.ㅋㅋ

ㄴstatic 폴더 (이미지, css파일을 넣어둡니다)

ㄴtemplates 폴더 (html파일을 넣어둡니다)

ㄴapp.py 파일

 

index.html는 templates폴더 안에 넣어주고 최초 기본 코드에서 아래와 같이 바꿔만 주면 html파일을 불러오게 된다.

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

GET & POST

 

서버를 만들었으니 이제 데이터를 주고받게끔 코딩을 해줘야 한다.

 

GET 방식의 경우 아래와 같이 진행하면 된다.

##app.yp

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

##index.html - script 안에다가

   $.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
    }
  })

POST방식은 아래와 같다.

## app.py

@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
   
## index.html / script 속

$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
    }
  })

GET과 POST방식 비슷하다. app와 index 간에 왔다 갔다 하는 부분이 있는데 서버와 클라이언트 관계라고 생각하면 그렇게 어려운 건 아닌 것 같다. 연습을 통해 좀 더 알아보자.

 

app.py

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

from pymongo import MongoClient
client = MongoClient('내 URL')
db = client.dbsparta

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

@app.route("/mars", methods=["POST"])
def mars_post():
    name_receive = request.form['name_give']
    address_receive = request.form['address_give']
    size_receive = request.form['size_give']

    doc = {
        'name': name_receive,
        'address': address_receive,
        'size': size_receive
    }

    db.orders.insert_one(doc)

    return jsonify({'msg': '주문 완료!'})

@app.route("/mars", methods=["GET"])
def mars_get():
    orders_list = list(db.orders.find({},{'_id':False}))
    return jsonify({'orders':orders_list})

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

index.html

    <script>
        $(document).ready(function () {
            show_order();
        });
        function show_order() {
            $('#order-box').empty()
            $.ajax({
                type: 'GET',
                url: '/mars',
                data: {},
                success: function (response) {
                    let rows = response['orders']
                    for (let i = 0; i < rows.length; i++) {
                        let name = rows[i]['name']
                        let address = rows[i]['address']
                        let size = rows[i]['size']

                        let temp_html = `<tr>
                                            <td>${name}</td>
                                            <td>${address}</td>
                                            <td>${size}</td>
                                          </tr>`
                        $('#order-box').append(temp_html)
                    }

                }
            });
        }
        function save_order() {
            let name = $('#name').val()
            let address = $('#address').val()
            let size = $('#size').val()

            $.ajax({
                type: 'POST',
                url: '/mars',
                data: { name_give:name, address_give:address, size_give:size },
                success: function (response) {
                    alert(response['msg'])
                    window.location.reload()
                }
            });
        }
    </script>
</head>
<body>
    <div class="mask"></div>
    <div class="order">
        <h1>화성에 땅 사놓기!</h1>
        <h3>가격: 평 당 500원</h3>
        <p>
            화성에 땅을 사둘 수 있다고?<br/>
            앞으로 백년 간 오지 않을 기회. 화성에서 즐기는 노후!
        </p>
        <div class="order-info">
            <div class="input-group mb-3">
                <span class="input-group-text">이름</span>
                <input id="name" type="text" class="form-control">
            </div>
            <div class="input-group mb-3">
                <span class="input-group-text">주소</span>
                <input id="address" type="text" class="form-control">
            </div>
            <div class="input-group mb-3">
                <label class="input-group-text" for="size">평수</label>
                <select class="form-select" id="size">
                  <option selected>-- 주문 평수 --</option>
                  <option value="10평">10평</option>
                  <option value="20평">20평</option>
                  <option value="30평">30평</option>
                  <option value="40평">40평</option>
                  <option value="50평">50평</option>
                </select>
              </div>
              <button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>
        </div>
        <table class="table">
            <thead>
              <tr>
                <th scope="col">이름</th>
                <th scope="col">주소</th>
                <th scope="col">평수</th>
              </tr>
            </thead>
            <tbody id="order-box">
              <tr>
                <td>홍길동</td>
                <td>서울시 용산구</td>
                <td>20평</td>
              </tr>
              <tr>
                <td>임꺽정</td>
                <td>부산시 동구</td>
                <td>10평</td>
              </tr>
              <tr>
                <td>세종대왕</td>
                <td>세종시 대왕구</td>
                <td>30평</td>
              </tr>
            </tbody>
          </table>
    </div>
</body>
</html>

네이버 영화에서 정보를 가져와 mongoDB에 저장 후 다시 내 홈페이지로 불러오는 방법이다. meta 태그를 불러와 저장하는 방법이 조금 다르니 그 부분을 유념하면서 보면 좋을 것 같다.

 

app.py

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

from pymongo import MongoClient
client = MongoClient('내 URL')
db = client.dbsparta

import requests
from bs4 import BeautifulSoup

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

@app.route("/movie", methods=["POST"])
def movie_post():
    url_receive = request.form['url_give']
    star_receive = request.form['star_give']
    comment_receive = request.form['comment_give']

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url_receive, headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    og_image = soup.select_one('meta[property="og:image"]')
    og_title = soup.select_one('meta[property="og:title"]')
    og_description = soup.select_one('meta[property="og:description"]')

    image = og_image['content']
    title = og_title['content']
    description = og_description['content']

    doc = {
        'image':image,
        'title':title,
        'desc':description,
        'star':star_receive,
        'comment':comment_receive
    }

    db.movies.insert_one(doc)

    return jsonify({'msg':'POST 연결 완료!'})

@app.route("/movie", methods=["GET"])
def movie_get():
    movies_list = list(db.movies.find({},{'_id':False}))
    return jsonify({'movies':movies_list})

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

index.html

    <script>
        $(document).ready(function(){
          listing();
        });

        function listing() {
            $('#cards-box').empty()
            $.ajax({
                type: 'GET',
                url: '/movie',
                data: {},
                success: function (response) {
                    let rows = response['movies']
                    for(let i = 0; i < rows.length; i++) {
                        let image = rows[i]['image']
                        let title = rows[i]['title']
                        let desc = rows[i]['desc']
                        let star = rows[i]['star']
                        let comment = rows[i]['comment']

                        let star_image = '⭐'.repeat(star)

                        let temp_html = `<div class="col">
                                            <div class="card h-100">
                                                <img src="${image}"
                                                     class="card-img-top">
                                                <div class="card-body">
                                                    <h5 class="card-title">${title}</h5>
                                                    <p class="card-text">${desc}</p>
                                                    <p>${star_image}</p>
                                                    <p class="mycomment">${comment}</p>
                                                </div>
                                            </div>
                                        </div>`

                        $('#cards-box').append(temp_html)
                    }
                }
            })
        }

        function posting() {
            let url = $('#url').val()
            let star = $('#star').val()
            let comment = $('#comment').val()

            $.ajax({
                type: 'POST',
                url: '/movie',
                data: {url_give: url, star_give: star, comment_give: comment},
                success: function (response) {
                    alert(response['msg'])
                    window.location.reload()
                }
            });
        }

        function open_box(){
            $('#post-box').show()
        }
        function close_box(){
            $('#post-box').hide()
        }
    </script>
</head>

<body>
<div class="mytitle">
    <h1>내 생애 최고의 영화들</h1>
    <button onclick="open_box()">영화 기록하기</button>
</div>
<div class="mypost" id="post-box">
    <div class="form-floating mb-3">
        <input id="url" type="email" class="form-control" placeholder="name@example.com">
        <label>영화URL</label>
    </div>
    <div class="input-group mb-3">
        <label class="input-group-text" for="inputGroupSelect01">별점</label>
        <select class="form-select" id="star">
            <option selected>-- 선택하기 --</option>
            <option value="1">⭐</option>
            <option value="2">⭐⭐</option>
            <option value="3">⭐⭐⭐</option>
            <option value="4">⭐⭐⭐⭐</option>
            <option value="5">⭐⭐⭐⭐⭐</option>
        </select>
    </div>
    <div class="form-floating">
        <textarea id="comment" class="form-control" placeholder="Leave a comment here"></textarea>
        <label for="floatingTextarea2">코멘트</label>
    </div>
    <div class="mybtns">
        <button onclick="posting()" type="button" class="btn btn-dark">기록하기</button>
        <button onclick="close_box()" type="button" class="btn btn-outline-dark">닫기</button>
    </div>
</div>
<div class="mycards">
    <div class="row row-cols-1 row-cols-md-4 g-4" id="cards-box">
        <div class="col">
            <div class="card h-100">
                <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                     class="card-img-top">
                <div class="card-body">
                    <h5 class="card-title">영화 제목이 들어갑니다</h5>
                    <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                    <p>⭐⭐⭐</p>
                    <p class="mycomment">나의 한줄 평을 씁니다</p>
                </div>
            </div>
        </div>
        <div class="col">
            <div class="card h-100">
                <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                     class="card-img-top">
                <div class="card-body">
                    <h5 class="card-title">영화 제목이 들어갑니다</h5>
                    <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                    <p>⭐⭐⭐</p>
                    <p class="mycomment">나의 한줄 평을 씁니다</p>
                </div>
            </div>
        </div>
        <div class="col">
            <div class="card h-100">
                <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                     class="card-img-top">
                <div class="card-body">
                    <h5 class="card-title">영화 제목이 들어갑니다</h5>
                    <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                    <p>⭐⭐⭐</p>
                    <p class="mycomment">나의 한줄 평을 씁니다</p>
                </div>
            </div>
        </div>
        <div class="col">
            <div class="card h-100">
                <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                     class="card-img-top">
                <div class="card-body">
                    <h5 class="card-title">영화 제목이 들어갑니다</h5>
                    <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                    <p>⭐⭐⭐</p>
                    <p class="mycomment">나의 한줄 평을 씁니다</p>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

</html>

 

728x90