5주차 - 웹개발 종합반

Jang Seok Woo·2021년 12월 13일
0

웹개발

목록 보기
22/31
post-custom-banner
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3e9b61fa-7a3a-4ebc-b502-407eaf7619ee/css__280x280.png **매 주차 강의노트 시작에 PDF파일을 올려두었어요!** ✔️ **왕초보 시작반**과 동일한 강의입니다 ! ☺️

[수업 목표]

  1. Flask 프레임워크를 활용해서 API를 만들 수 있다.

  2. '마이 페이보릿 무비스타'를 완성한다.

  3. EC2에 내 프로젝트를 올리고, 자랑한다!

    [목차]

💡 모든 토글을 열고 닫는 단축키 Windows : `Ctrl` + `alt` + `t` Mac : `⌘` + `⌥` + `t`

01. 5주차 설치

  • 이번주 수업을 위해 설치할 것들!
    • Filezilla 설치하기
    • 가비아 가입하기 & 도메인 구입하기
      • 접속하기 & 가입하기: https://www.gabia.com
      • 가비아에서 할인이벤트(500원/1년)를 진행하는 도메인을 구매해서 진행 할 예정입니다. 🚨 기억하기 - **무통장입금(가상계좌)**으로 결제하시기를 추천드립니다! - 로그인 후, 메인 페이지에서 원하는 도메인을 검색해주세요. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d4138b87-8a22-42b2-aefa-07bbe629ffd3/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d4138b87-8a22-42b2-aefa-07bbe629ffd3/Untitled.png) - 마침 .shop 도메인이 500원/1년으로 할인중이니, 추천드립니다. :-) 💡 원하는 도메인을 구매하세요! `bumkyulee.shop` 은 제가 구매했으니, 당연히 여러분은 안 되겠죠? 🤣 ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c472ce4a-0390-4064-8bce-3d7aa3f54482/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c472ce4a-0390-4064-8bce-3d7aa3f54482/Untitled.png) - 결제를 마무리해주세요. 👉 결제 기간을 1년으로 맞춰주세요! 그래야 500원 찬스! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/abf95f4c-fdc5-44eb-8df0-8b5891e6cf20/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/abf95f4c-fdc5-44eb-8df0-8b5891e6cf20/Untitled.png) - 무통장입금을 선택! 👉 1,000원 이하는 카드 결제가 안된대요~! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/48d61e7d-3265-49a3-9756-1a7fdca3eac5/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/48d61e7d-3265-49a3-9756-1a7fdca3eac5/Untitled.png) - 토스, 카카오페이, 은행 앱 등을 이용해 계좌이체를 진행합니다! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8133298d-bc01-4c35-8cc5-3949c9e56410/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8133298d-bc01-4c35-8cc5-3949c9e56410/Untitled.png) - [마이페이지(링크)](https://my.gabia.com/service#/)에 접속하고, 10분 정도 기다리면 → 총 서비스 수가 '1'로 바뀔 거예요! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a5a643ef-5be1-4557-90b0-5f3c8ca8f573/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a5a643ef-5be1-4557-90b0-5f3c8ca8f573/Untitled.png)

02. 5주차 오늘 배울 것

  • 오늘 배울 것 이야기 - 5주차: 미니프로젝트3 👉 오늘은 아직 익숙해지지 않았을 당신을 위해! 같은 난이도의 유사한 프로젝트를 진행하며 머릿속의 퍼즐을 맞출 예정입니다. 그리고 드디어! 친구들도 볼수록 배포하는 일까지, 한번 쭉-해보겠습니다! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8793b9cd-1f21-400e-a3ee-b8258e637e83/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8793b9cd-1f21-400e-a3ee-b8258e637e83/Untitled.png)

03. [무비스타] - 프로젝트 세팅

🔥 **sparta → projects → moviestar 폴더를 열고 시작!**
  • 1) 문제 분석 - 완성작부터 보기!
    • [코드스니펫] - 무비스타 보러가기
      [http://spartacodingclub.shop/moviestar](http://spartacodingclub.shop/moviestar)
  • 2) 프로젝트 준비 - flask 폴더 구조 만들기 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ae218471-7196-428f-90e7-71c35df70372/Untitled.png

04. [무비스타] - DB 만들기(데이터 쌓기)

  • 3) 프로젝트 준비 - 프로젝트에서 사용할 데이터 넣기(웹 스크래핑) 👉 **API를 설계하고 만드는 것에 집중**할 수 있게, 1) 사용할 데이터를 웹 스크래핑해서, 2) 데이터베이스에 저장하는 코드를 미리 작성해두었어요. - **moviestar** 폴더 안에 ****`init_db.py` 파일을 만들어 아래 코드를 복사-붙여넣기해주세요. - **[코드스니펫] - 무비스타-init_db.py** ```python import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.dbsparta # DB에 저장할 영화인들의 출처 url을 가져옵니다. def get_urls(): 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('https://movie.naver.com/movie/sdb/rank/rpeople.nhn', headers=headers) soup = BeautifulSoup(data.text, 'html.parser') trs = soup.select('#old_content > table > tbody > tr') urls = [] for tr in trs: a = tr.select_one('td.title > a') if a is not None: base_url = 'https://movie.naver.com/' url = base_url + a['href'] urls.append(url) return urls # 출처 url로부터 영화인들의 사진, 이름, 최근작 정보를 가져오고 mystar 콜렉션에 저장합니다. def insert_star(url): 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, headers=headers) soup = BeautifulSoup(data.text, 'html.parser') name = soup.select_one('#content > div.article > div.mv_info_area > div.mv_info.character > h3 > a').text img_url = soup.select_one('#content > div.article > div.mv_info_area > div.poster > img')['src'] recent_work = soup.select_one( '#content > div.article > div.mv_info_area > div.mv_info.character > dl > dd > a:nth-child(1)').text doc = { 'name': name, 'img_url': img_url, 'recent': recent_work, 'url': url, 'like': 0 } db.mystar.insert_one(doc) print('완료!', name) # 기존 mystar 콜렉션을 삭제하고, 출처 url들을 가져온 후, 크롤링하여 DB에 저장합니다. def insert_all(): db.mystar.drop() # mystar 콜렉션을 모두 지워줍니다. urls = get_urls() for url in urls: insert_star(url) ### 실행하기 insert_all() ``` - ****`init_db.py` 파일을 실행하면 내 mongoDB의 `mystar` collection에 영화인 정보가 저장됩니다. - mystar 콜렉션에 데이터가 저장된 모습은 다음과 같습니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bed8c103-91e7-4099-a55b-d90aa9772422/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bed8c103-91e7-4099-a55b-d90aa9772422/Untitled.png)

05. [무비스타] - 뼈대 준비하기

  • 4) 프로젝트 준비 - index.html, app.py 준비하기
    • [코드스니펫] - 무비스타-index.html
      <!DOCTYPE html>
      <html lang="ko">
          <head>
              <meta charset="UTF-8"/>
              <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
              <title>마이 페이보릿 무비스타 | 프론트-백엔드 연결 마지막 예제!</title>
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
              <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css"/>
              <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
              <style>
                  .center {
                      text-align: center;
                  }
      
                  .star-list {
                      width: 500px;
                      margin: 20px auto 0 auto;
                  }
      
                  .star-name {
                      display: inline-block;
                  }
      
                  .star-name:hover {
                      text-decoration: underline;
                  }
      
                  .card {
                      margin-bottom: 15px;
                  }
              </style>
              <script>
                  $(document).ready(function () {
                      showStar();
                  });
      
                  function showStar() {
                      $.ajax({
                          type: 'GET',
                          url: '/api/list?sample_give=샘플데이터',
                          data: {},
                          success: function (response) {
                              alert(response['msg']);
                          }
                      });
                  }
      
                  function likeStar(name) {
                      $.ajax({
                          type: 'POST',
                          url: '/api/like',
                          data: {sample_give:'샘플데이터'},
                          success: function (response) {
                              alert(response['msg']);
                          }
                      });
                  }
      
                  function deleteStar(name) {
                      $.ajax({
                          type: 'POST',
                          url: '/api/delete',
                          data: {sample_give:'샘플데이터'},
                          success: function (response) {
                              alert(response['msg']);
                          }
                      });
                  }
      
              </script>
          </head>
          <body>
              <section class="hero is-warning">
                  <div class="hero-body">
                      <div class="container center">
                          <h1 class="title">
                              마이 페이보릿 무비스타😆
                          </h1>
                          <h2 class="subtitle">
                              순위를 매겨봅시다
                          </h2>
                      </div>
                  </div>
              </section>
              <div class="star-list" id="star-box">
                  <div class="card">
                      <div class="card-content">
                          <div class="media">
                              <div class="media-left">
                                  <figure class="image is-48x48">
                                      <img
                                              src="https://search.pstatic.net/common/?src=https%3A%2F%2Fssl.pstatic.net%2Fsstatic%2Fpeople%2Fportrait%2F201807%2F20180731143610623-6213324.jpg&type=u120_150&quality=95"
                                              alt="Placeholder image"
                                      />
                                  </figure>
                              </div>
                              <div class="media-content">
                                  <a href="#" target="_blank" class="star-name title is-4">김다미 (좋아요: 3)</a>
                                  <p class="subtitle is-6">안녕, 나의 소울메이트(가제)</p>
                              </div>
                          </div>
                      </div>
                      <footer class="card-footer">
                          <a href="#" onclick="likeStar('김다미')" class="card-footer-item has-text-info">
                              위로!
                              <span class="icon">
                    <i class="fas fa-thumbs-up"></i>
                  </span>
                          </a>
                          <a href="#" onclick="deleteStar('김다미')" class="card-footer-item has-text-danger">
                              삭제
                              <span class="icon">
                    <i class="fas fa-ban"></i>
                  </span>
                          </a>
                      </footer>
                  </div>
              </div>
          </body>
      </html>
    • [코드스니펫] - 무비스타-app.py
      from pymongo import MongoClient
      
      from flask import Flask, render_template, jsonify, request
      
      app = Flask(__name__)
      
      client = MongoClient('localhost', 27017)
      db = client.dbsparta
      
      # HTML 화면 보여주기
      @app.route('/')
      def home():
          return render_template('index.html')
      
      # API 역할을 하는 부분
      @app.route('/api/list', methods=['GET'])
      def show_stars():
          sample_receive = request.args.get('sample_give')
          print(sample_receive)
          return jsonify({'msg': 'list 연결되었습니다!'})
      
      @app.route('/api/like', methods=['POST'])
      def like_star():
          sample_receive = request.form['sample_give']
          print(sample_receive)
          return jsonify({'msg': 'like 연결되었습니다!'})
      
      @app.route('/api/delete', methods=['POST'])
      def delete_star():
          sample_receive = request.form['sample_give']
          print(sample_receive)
          return jsonify({'msg': 'delete 연결되었습니다!'})
      
      if __name__ == '__main__':
          app.run('0.0.0.0', port=5000, debug=True)

06. [무비스타] - GET연습(보여주기)

  • 5) 문제 분석 - 화면과 동작 살펴보기
    • 우리가 만들 기능은 영화인 정보를 카드로 보여주기(Read) 입니다.

    • 화면에 어떤 데이터가 어떤 부분에 보여지는지 영화인 카드 화면 코드를 보며 분석해보겠습니다.
      - 영화인 이름
      - 영화인 이미지 : 이미지 src 속성
      - 좋아요 개수
      - 최근 작품 내용이 들어가는 부분

      👉 `index.html`을 크롬에서 실행시켜 크롬 개발자도구 - 검사하기(Inspector)로 어떤 요소에 어떤 데이터가 보일지 분석해보세요.

      https://s3-us-west-2.amazonaws.com/secure.notion-static.com/483108cb-0530-4edc-975b-5c595c8420d5/Untitled.png

      <!-- 다음 코드가 하나의 카드를 이루는 div 입니다. -->
      <div class="card">
        <div class="card-content">
          <div class="media">
            <div class="media-left">
              <figure class="image is-48x48">
                <img
                  src="https://search.pstatic.net/common/?src=https%3A%2F%2Fssl.pstatic.net%2Fsstatic%2Fpeople%2Fportrait%2F201807%2F20180731143610623-6213324.jpg&type=u120_150&quality=95"
                  alt="Placeholder image"
                />
              </figure>
            </div>
            <div class="media-content">
              <a href="https://movie.naver.com//movie/bi/pi/basic.nhn?st=1&code=397373" target="_blank" class="star-name title is-4">김다미 (좋아요: 3)</a>
              <p class="subtitle is-6">안녕, 나의 소울메이트(가제)</p>
            </div>
          </div>
        </div>
        <footer class="card-footer">
          <a href="#" onclick="likeStar('김다미')" class="card-footer-item has-text-info">
            위로!
            <span class="icon">
              <i class="fas fa-thumbs-up"></i>
            </span>
          </a>
          <a href="#" onclick="deleteStar('김다미')" class="card-footer-item has-text-danger">
            삭제
            <span class="icon">
              <i class="fas fa-ban"></i>
            </span>
          </a>
        </footer>
      </div>
  • 6) API 만들고 사용하기 - 영화인 조회 API (Read → GET) 👉 만들 API **** 1. **조회(Read) 기능**: 영화인 정보 전체를 조회 2. **좋아요(Update) 기능**: 클라이언트에서 받은 이름(name_give)으로 찾아서 좋아요(like)를 증가 3. **삭제(Delete) 기능**: 클라이언트에서 받은 이름(name_give)으로 영화인을 찾고, 해당 영화인을 삭제 👉 정리하면, **만들 API 정보**는 아래와 같습니다. **A. 요청 정보** - 요청 URL= `/api/list` , 요청 방식 = `GET` - 요청 데이터 : 없음 **B. 서버가 제공할 기능** : 데이터베이스에 영화인 정보를 조회(Read)하고, 영화인 정보를 응답 데이터로 보냄 C**. 응답 데이터 :** (JSON 형식) 'stars_list'= 영화인 정보 리스트 - 1. 클라이언트와 서버 연결 확인하기 - 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요. - 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요! [서버 코드 - `app.py`] ```python @app.route('/api/list', methods=['GET']) def show_stars(): sample_receive = request.args.get('sample_give') print(sample_receive) return jsonify({'msg': 'list 연결되었습니다!'}) ``` [클라이언트 코드 - `index.html`] ```jsx function showStar() { $.ajax({ type: 'GET', url: '/api/list?sample_give=샘플데이터', data: {}, success: function (response) { alert(response['msg']); } }); } ``` 👉 **동작 테스트** 새로고침했을 때, 'list 연결되었습니다.' 라는 메시지가 뜨면 동작하는 것입니다. - 2. 서버부터 만들기 👉 API 는 약속이라고 했습니다. 위에 미리 설계해 둔 API 정보를 보고 만들어보죠! 영화인 정보 전체를 조회하기 위해 서버가 받을 정보는 없습니다. 조건없이 모든 정보를 보여줄 것이니까요! 따라서 서버 로직은 다음 단계로 구성되어야 합니다. 1. mystar 목록 전체를 검색합니다. ID는 제외하고 like 가 많은 순으로 정렬 2. 성공하면 success 메시지와 함께 stars_list 목록을 클라이언트에 전달 ```python @app.route('/api/list', methods=['GET']) def show_stars(): movie_star = list(db.mystar.find({}, {'_id': False}).sort('like', -1)) return jsonify({'movie_stars': movie_star}) ``` - 3. 클라이언트 만들기 👉 API 는 약속이라고 했습니다. API를 사용할 클라이언트를 만들어보죠! 영화인 정보 전체를 조회하기 위해 서버가 받을 정보는 없습니다. 조건없이 모든 정보를 보여줄 것이니까요! 따라서 클라이언트 로직은 다음 단계로 구성되어야 합니다. 1. #star_box의 내부 html 태그를 모두 삭제 2. 서버에 1) GET 방식으로, 2) /api/list 라는 주소로 stars_list를 요청 3. 서버가 돌려준 stars_list를 stars라는 변수에 저장 4. for 문을 활용하여 stars 배열의 요소를 차례대로 조회 5. stars[i] 요소의 name, url, img_url, recent, like 키 값을 활용하여 값 조회 6. 영화인 카드 코드 만들어 #star-box에 붙이기 ```jsx function showStar() { $.ajax({ type: 'GET', url: '/api/list?sample_give=샘플데이터', data: {}, success: function (response) { let mystars = response['movie_stars'] for (let i = 0; i < mystars.length; i++) { let name = mystars[i]['name'] let img_url = mystars[i]['img_url'] let recent = mystars[i]['recent'] let url = mystars[i]['url'] let like = mystars[i]['like'] let temp_html = `` $('#star-box').append(temp_html) } } }); } ``` - 4. 완성 확인하기 👉 **동작 테스트** 화면을 새로고침 했을 때 영화인 정보가 조회되는지 확인합니다.

07. [무비스타] - POST연습(좋아요+1)

  • 7) API 만들고 사용하기 - 좋아요 API (Update → POST) 👉 **만들 API** 1) 조회: 영화인 정보 전체를 조회 **2) 좋아요: 클라이언트에서 받은 이름(name_give)으로 찾아서 좋아요(like)를 증가** 3) 삭제: 클라이언트에서 받은 이름(name_give)으로 영화인을 찾고, 해당 영화인을 삭제 👉 정리하면, **만들 API 정보**는 아래와 같습니다. **A. 요청 정보** - 요청 URL= `/api/like` , 요청 방식 = `POST` - 요청 데이터 : 영화인 이름(name_give) **B. 서버가 제공할 기능** : 영화인 이름(요청 데이터)과 일치하는 영화인 정보의 좋아요 수를 한 개 증가시켜 데이터베이스에 업데이트하고(Update), 성공했다고 응답 메세지를 보냄 C**. 응답 데이터 :** (JSON 형식) 'msg'='좋아요 완료!' - 1) 클라이언트와 서버 연결 확인하기 - 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요. - 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요! [서버 코드 - `app.py`] ```python @app.route('/api/like', methods=['POST']) def like_star(): sample_receive = request.form['sample_give'] print(sample_receive) return jsonify({'msg': 'like 연결되었습니다!'}) ``` [클라이언트 코드 - `index.html`] ```jsx function likeStar(name) { $.ajax({ type: 'POST', url: '/api/like', data: {sample_give:'샘플데이터'}, success: function (response) { alert(response['msg']); } }); } ``` 👉 **동작 테스트** '위로' 버튼을 눌렀을 때, 'like 연결되었습니다!' 내용의 alert창이 뜨면 제대로 동작하는 것입니다. - 2) 서버부터 만들기 👉 API 는 약속이라고 했습니다. 위에 미리 설계해 둔 API 정보를 보고 만들어보죠! 영화인 카드의 좋아요 수를 증가시키기 위해 서버가 클라이언트에게 전달받아야하는 정보는 다음과 같습니다. - 영화인의 이름 (name_give) 따라서 서버 로직은 다음 단계로 구성되어야 합니다. 1. 클라이언트가 전달한 name_give를 name_receive 변수에 넣습니다. 2. mystar 목록에서 find_one으로 name이 name_receive와 일치하는 star를 찾습니다. 3. star의 like 에 1을 더해준 new_like 변수를 만듭니다. 4. mystar 목록에서 name이 name_receive인 문서의 like 를 new_like로 변경합니다. ```python @app.route('/api/like', methods=['POST']) def like_star(): name_receive = request.form['name_give'] target_star = db.mystar.find_one({'name': name_receive}) current_like = target_star['like'] new_like = current_like + 1 db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}}) return jsonify({'msg': '좋아요 완료!'}) ``` - 3) 클라이언트 만들기 👉 API 는 약속이라고 했습니다. API를 사용할 클라이언트를 만들어보죠! 좋아요 수를 증가시키기 위해 클라이언트가 전달할 정보는 다음과 같습니다. - 영화인의 이름 (name_give) 따라서 클라이언트 로직은 다음 단계로 구성되어야 합니다. 1. 서버에 1) POST 방식으로, 2) /api/like 라는 url에, 3) name_give라는 이름으로 name을 전달합니다. (참고) POST 방식이므로 data: {'name_give': name} 사용 2. '좋아요 완료!' alert 창을 띄웁니다. 3. 변경된 정보를 반영하기 위해 새로고침합니다. ```jsx function likeStar(name) { $.ajax({ type: 'POST', url: '/api/like', data: {name_give:name}, success: function (response) { alert(response['msg']); window.location.reload() } }); } ``` - 4) 완성 확인하기 👉 **동작 테스트** '위로' 버튼을 눌렀을 때 좋아요 수가 증가하고 영화인 카드의 순위가 변경되는지 확인합니다.

08. [무비스타] - POST연습(삭제하기)

  • 8) API 만들고 사용하기 - 카드 삭제 API (Delete → POST) 👉 만들 API **** 1. **조회(Read) 기능**: 영화인 정보 전체를 조회 2. **좋아요(Update) 기능**: 클라이언트에서 받은 이름(name_give)으로 찾아서 좋아요(like)를 증가 3. **삭제(Delete) 기능**: 클라이언트에서 받은 이름(name_give)으로 영화인을 찾고, 해당 영화인을 삭제 👉 정리하면, **만들 API 정보**는 아래와 같습니다. **A. 요청 정보** - 요청 URL= `/api/delete` , 요청 방식 = `POST` - 요청 데이터 : 영화인 이름(name_give) **B. 서버가 제공할 기능** : 영화인 이름(요청 데이터)와 일치하는 영화인 정보를 데이터베이스에서 삭제(Delete)하고, 성공했다고 응답 메세지를 보냄 C**. 응답 데이터 :** (JSON 형식) 'msg'='삭제 완료!' - 1) 클라이언트와 서버 연결 확인하기 - 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요. - 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요! [서버 코드 - `app.py`] ```python @app.route('/api/delete', methods=['POST']) def delete_star(): sample_receive = request.form['sample_give'] print(sample_receive) return jsonify({'msg': 'delete 연결되었습니다!'}) ``` [클라이언트 코드 - `index.html`] ```jsx function deleteStar(name) { $.ajax({ type: 'POST', url: '/api/delete', data: {sample_give:'샘플데이터'}, success: function (response) { alert(response['msg']); } }); } ``` 👉 **동작 테스트** '삭제' 버튼을 눌렀을 때, 'delete 연결되었습니다!' alert창이 뜨면 클라이언트 코드와 서버 코드가 연결 되어있는 것입니다. - 2) 서버부터 만들기 👉 API 는 약속이라고 했습니다. 위에 미리 설계해 둔 API 정보를 보고 만들어보죠! 영화인 카드를 삭제하기 위해 필요한 정보는 다음과 같습니다. - 영화인의 이름 (name_give) 따라서 서버 로직은 다음 단계로 구성되어야 합니다. 1. 클라이언트가 전달한 name_give를 name_receive 변수에 넣기 2. mystar 에서 delete_one으로 name이 name_receive와 일치하는 star를 제거 3. 성공하면 success 메시지를 반환 ```python @app.route('/api/delete', methods=['POST']) def delete_star(): name_receive = request.form['name_give'] db.mystar.delete_one({'name': name_receive}) return jsonify({'msg': '삭제 완료!'}) ``` - 3) 클라이언트 만들기 👉 API 는 약속이라고 했습니다. API를 사용할 클라이언트를 만들어보죠! 영화인 카드를 삭제하기 위해 필요한 정보는 다음과 같습니다. - 영화인의 이름 (name_give) 따라서 클라이언트 로직은 다음 단계로 구성되어야 합니다. 1. 서버에 1) POST 방식으로, 2) /api/delete 라는 url에, 3) name_give라는 이름으로 name을 전달 (참고) POST 방식이므로 data: {'name_give': name} 2. '삭제 완료! 안녕!' alert창 띄우기 3. 변경된 정보를 반영하기 위해 새로고침 ```jsx function deleteStar(name) { $.ajax({ type: 'POST', url: '/api/delete', data: {name_give:name}, success: function (response) { alert(response['msg']); window.location.reload() } }); } ``` - 4) 완성 확인하기 👉 **동작 테스트** 삭제 버튼을 눌렀을 때 영화인 카드가 삭제되는지 확인합니다.
  • 9) 전체 완성 코드
    • [💻 코드 - index.html]
      <!DOCTYPE html>
      <html lang="ko">
          <head>
              <meta charset="UTF-8"/>
              <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
              <title>마이 페이보릿 무비스타 | 프론트-백엔드 연결 마지막 예제!</title>
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
              <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css"/>
              <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
              <style>
                  .center {
                      text-align: center;
                  }
      
                  .star-list {
                      width: 500px;
                      margin: 20px auto 0 auto;
                  }
      
                  .star-name {
                      display: inline-block;
                  }
      
                  .star-name:hover {
                      text-decoration: underline;
                  }
      
                  .card {
                      margin-bottom: 15px;
                  }
              </style>
              <script>
                  $(document).ready(function () {
                      showStar();
                  });
      
                  function showStar() {
                      $.ajax({
                          type: 'GET',
                          url: '/api/list?sample_give=샘플데이터',
                          data: {},
                          success: function (response) {
                              let mystars = response['movie_stars']
                              for (let i = 0; i < mystars.length; i++) {
                                  let name = mystars[i]['name']
                                  let img_url = mystars[i]['img_url']
                                  let recent = mystars[i]['recent']
                                  let url = mystars[i]['url']
                                  let like = mystars[i]['like']
      
                                  let temp_html = `<div class="card">
                                                      <div class="card-content">
                                                          <div class="media">
                                                              <div class="media-left">
                                                                  <figure class="image is-48x48">
                                                                      <img
                                                                              src="${img_url}"
                                                                              alt="Placeholder image"
                                                                      />
                                                                  </figure>
                                                              </div>
                                                              <div class="media-content">
                                                                  <a href="${url}" target="_blank" class="star-name title is-4">${name} (좋아요: ${like})</a>
                                                                  <p class="subtitle is-6">${recent}</p>
                                                              </div>
                                                          </div>
                                                      </div>
                                                      <footer class="card-footer">
                                                          <a href="#"token interpolation">${name}')" class="card-footer-item has-text-info">
                                                              위로!
                                                              <span class="icon">
                                                    <i class="fas fa-thumbs-up"></i>
                                                  </span>
                                                          </a>
                                                          <a href="#"token interpolation">${name}')" class="card-footer-item has-text-danger">
                                                              삭제
                                                              <span class="icon">
                                                    <i class="fas fa-ban"></i>
                                                  </span>
                                                          </a>
                                                      </footer>
                                                  </div>`
                                  $('#star-box').append(temp_html)
                              }
                          }
                      });
                  }
      
                  function likeStar(name) {
                      $.ajax({
                          type: 'POST',
                          url: '/api/like',
                          data: {name_give:name},
                          success: function (response) {
                              alert(response['msg']);
                              window.location.reload()
                          }
                      });
                  }
      
                  function deleteStar(name) {
                      $.ajax({
                          type: 'POST',
                          url: '/api/delete',
                          data: {name_give:name},
                          success: function (response) {
                              alert(response['msg']);
                              window.location.reload()
                          }
                      });
                  }
      
              </script>
          </head>
          <body>
              <section class="hero is-warning">
                  <div class="hero-body">
                      <div class="container center">
                          <h1 class="title">
                              마이 페이보릿 무비스타😆
                          </h1>
                          <h2 class="subtitle">
                              순위를 매겨봅시다
                          </h2>
                      </div>
                  </div>
              </section>
              <div class="star-list" id="star-box">
              </div>
          </body>
      </html>
    • [💻 코드 - app.py]
      from pymongo import MongoClient
      
      from flask import Flask, render_template, jsonify, request
      
      app = Flask(__name__)
      
      client = MongoClient('localhost', 27017)
      db = client.dbsparta
      
      # HTML 화면 보여주기
      @app.route('/')
      def home():
          return render_template('index.html')
      
      # API 역할을 하는 부분
      @app.route('/api/list', methods=['GET'])
      def show_stars():
          movie_star = list(db.mystar.find({}, {'_id': False}).sort('like', -1))
          return jsonify({'movie_stars': movie_star})
      
      @app.route('/api/like', methods=['POST'])
      def like_star():
          name_receive = request.form['name_give']
      
          target_star = db.mystar.find_one({'name': name_receive})
          current_like = target_star['like']
      
          new_like = current_like + 1
      
          db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}})
      
          return jsonify({'msg': '좋아요 완료!'})
      
      @app.route('/api/delete', methods=['POST'])
      def delete_star():
          name_receive = request.form['name_give']
          db.mystar.delete_one({'name': name_receive})
          return jsonify({'msg': '삭제 완료!'})
      
      if __name__ == '__main__':
          app.run('0.0.0.0', port=5000, debug=True)
🔥 와, API 사용하고 만들기 한 번 더 복습하니 조금은 익숙해지죠? 마이페이보릿 무비스타 프로젝트도 완성!

09. 내 프로젝트를 서버에 올리기

  • 10) "웹서비스 런칭" 에 필요한 개념 소개 👉 이제 내가 만든 프로젝트를 배포해봅니다. 배포는 누구나 내 서비스를 사용할 수 있게 하기 위해서 작업들이에요. 웹 서비스를 런칭하는 거죠! - 웹 서비스를 런칭하기 위해 클라이언트의 요청에 항상 응답해줄 수 있는 서버에 프로젝트를 실행시켜줄 거에요. - 언제나 요청에 응답하려면, 1) 컴퓨터가 **항상** 켜져있고 프로그램이 실행되어 있어야하고, 2) 모두가 접근할 수 있는 공개 주소인 공개 IP 주소(Public IP Address)로 나의 웹 서비스에 **접근할 수 있도록** 해야해요. - 서버는 그냥 컴퓨터라는거 기억나시죠? 외부 접속이 가능하게 설정한 다음에 내 컴퓨터를 서버로 사용할 수도 있어요. - 우리는 AWS 라는 클라우드 서비스에서 편하게 서버를 관리하기 위해서 항상 켜 놓을 수 있는 컴퓨터인 EC2 사용권을 구입해 서버로 사용할 겁니다. - **[열 걸음 더 🏃]** IP 주소와 포트 - 사실 우리가 접속하는 컴퓨터는 숫자로 되어있는 주소(IP 주소)가 붙어있어요. 우리가 아는 URL 은 우리가 알아보기 쉽게 하는 등의 이유로 IP 주소를 알파벳으로 바꾼 거에요. 이렇게 변환해주는 시스템을 DNS 라고 합니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ec83d1a9-9eb9-4c74-aad2-a95b797b1604/week06_ip.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ec83d1a9-9eb9-4c74-aad2-a95b797b1604/week06_ip.png) - IP 주소(줄여서 IP라고 부릅니다) : 컴퓨터가 통신할 수 있도록 컴퓨터마다 가지는 고유한 주소라고 생각하면 됩니다. 정확히는 네트워크가 가능한 모든 기기가 통신할 수 있도록 가지고 있는 특수한 번호입니다. 서버는 하나의 주소를 가지고 있습니다. - 포트(port) : 하나의 IP에 여러 포트가 있습니다. 하나의 포트에 하나의 프로그램을 실행시킬 수 있습니다.

10. AWS 서버 구매하기

  • 11) EC2 서버 구매하기
    • AWS EC2 서버 사기
      • [코드스니펫] - EC2 콘솔페이지
        [https://ap-northeast-2.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-2](https://ap-northeast-2.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-2#Instances:sort=instanceId)
      • 구매 화면들 따라하기 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e0bfe685-84c5-4931-ba99-196597f756cc/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3764fb78-a3e6-429c-aaf5-621f639513e8/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f3fb0c6d-ce53-4979-bf07-97bc71a06852/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1154a440-44e9-40a6-ad20-fcd4ae58bfc1/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c8e983f6-07e6-4fa7-8b4a-d48b70a97302/Untitled.png
  • 12) EC2 서버 종료하는 방법 (1년 후 자동결제 방지!) 💡 **중지 또는 종료하는 법. 무료 기간(1년) 후 결제가 되기 전에, 이렇게 종료하세요!** 대상 인스턴스에 마우스 우클릭 > '인스턴스 상태' 를 클릭합니다. 중지 또는 종료 중 하나를 클릭하면 명령을 실행합니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4cd9daaf-4901-4492-881f-aa3dc6560646/_2020-04-29__11.15.14.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4cd9daaf-4901-4492-881f-aa3dc6560646/_2020-04-29__11.15.14.png)
  • 13) EC2에 접속하기
    • AWS EC2에 접속하기 (준비 상식 편)
      • SSH(Secure Shell Protocol)
        • 다른 컴퓨터에 접속할 때 쓰는 프로그램입니다. 다른 것들 보다 보안이 상대적으로 뛰어납니다.

        • 접속할 컴퓨터가 22번 포트가 열려있어야 접속 가능합니다. AWS EC2의 경우, 이미 22번 포트가 열려있습니다. 확인해볼까요?

          https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8eae74ae-4c61-46d4-8203-560001f366db/Untitled.png

    • AWS EC2에 접속하기
      • Mac OS: Mac은 ssh가 있어서, 명령어로 바로 접근 가능!
        • 터미널을 열기 (spotlight에 terminal 입력)
        • 방금 받은 내 Keypair의 접근 권한을 바꿔주기
          sudo chmod 400 받은키페어를끌어다놓기 
        • SSH로 접속하기
          ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피
          예) 아래와 비슷한 생김새!
          ssh -i /path/my-key-pair.pem ubuntu@13.125.250.20
      • Window: ssh가 없으므로, git bash라는 프로그램을 이용!
        • gitbash를 실행하고, 아래를 입력!
          ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피
          예) 아래와 비슷한 생김새!
          ssh -i /path/my-key-pair.pem ubuntu@13.125.250.20
        • Key fingerprint 관련 메시지가 나올 경우 Yes를 입력해주세요!
        • git bash를 종료할 때는 exit 명령어를 입력하여 ssh 접속을 먼저 끊어주세요.
  • 14) 간단한 리눅스 명령어 연습하기
    • 리눅스는 윈도우 같지 않아서, '쉘 명령어'를 통해 OS를 조작한다. (일종의 마우스 역할)

      [가장 많이 쓰는 몇 가지 명령어]

    • 팁! 리눅스 커널에서 윗화살표를 누르면 바로 전에 썼던 명령어가 나옵니다.

      ls: 내 위치의 모든 파일을 보여준다.
      
      pwd: 내 위치(폴더의 경로)를 알려준다.
      
      mkdir: 내 위치 아래에 폴더를 하나 만든다.
      
      cd [갈 곳]: 나를 [갈 곳] 폴더로 이동시킨다.
      
      cd .. : 나를 상위 폴더로 이동시킨다.
      
      cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기
      
      rm -rf [지울 것]: 지우기
      
      sudo [실행 할 명령어]: 명령어를 관리자 권한으로 실행한다.
      sudo su: 관리가 권한으로 들어간다. (나올때는 exit으로 나옴)

11. 서버 세팅하기

  • 15) filezilla를 이용해서, 간단한 python 파일을 올려봅니다.
    • 서버에 업로드 할 간단한 파일을 다운로드 받습니다.
      • [코드스니펫] - test.py

        [test.py](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/593aa12f-0c04-40dc-9573-40e1b641c2c1/test.py)

        예) test.py

        # 아주 간단하게, 이 정도만 적어볼까요?
        # 그리고 적당한 곳에 파일을 저장해봅니다.
        print('hello sparta!!')
    • 파일질라 실행, 다음과 같이 설정 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5564e4cb-ffc5-49ba-9dc4-56efce3a49ad/Untitled.png
    • 정보들을 입력하고, ok 누르면 서버의 파일들을 볼 수 있음
      (Host: 내 EC2서버의 ip // User: ubuntu 로 입력)
      ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c91661f0-1274-4f35-b9c2-3a09879a0b09/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c91661f0-1274-4f35-b9c2-3a09879a0b09/Untitled.png)
    • 마우스로 드래그 해서 파일을 업로드/다운로드하면 됩니다!
      (자, 그럼 이제 간단한 파이썬 파일을 하나 만들어서 업로드 해볼까요?)
      ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/47a40685-1be7-421f-939f-0fdad19c7d81/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/47a40685-1be7-421f-939f-0fdad19c7d81/Untitled.png)
  • 16) 파이썬 파일 실행해보기
    • EC2 콘솔창에서 아래와 같이 입력합니다.
      # home 디렉토리로 이동
      cd ~
      
      # 실행. 콘솔창에 hellow world!가 뜨는 것을 확인 할 수 있습니다.
      python3 [test.py](http://test1.py)
  • 17) 서버 환경 통일하기 💡 우리는 지금 막! 컴퓨터를 구매한 상태예요. 여기에 이런저런 세팅들(업그레이드, DB설치, 명령어 통일 등)을 해줘야 본격적으로 이용할 때 편리하답니다! - **[코드스니펫] - EC2 한방에 세팅하기** [initial_ec2.sh](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d3623fe8-8b17-45d1-bb70-304e88dfb537/initial_ec2.sh) 파일질라로 업로드하고, git bash(또는 터미널)에서 아래 코드를 차례대로 입력해주세요. 3분 정도 기다리면 모든 세팅이 완료됩니다. ```bash sudo chmod 755 initial_ec2.sh ``` ```bash ./initial_ec2.sh ```
  • 18) 다시, 파이썬 파일을 실행해보기 💡 자 이제, python 이라고 입력해도 가능! ```bash python [test.py](http://test1.py) ```
  • 19) [한 걸음 더] 서버 환경 세팅 - 혼자 해보기 💡 실제 업무에서는 아래 내용을 인프라 엔지니어 또는 개발 팀장님이 해두시는 경우가 많습니다. 튜터들도 모두 외우고 있는 코드가 아니기에, 맥락만 이해해주시면 되겠습니다! 1. 한국시간 세팅 💡 EC2 컴퓨터의 시간대를 한국으로 맞추는 명령어 ```bash sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime ``` 2. 파이썬 (python3 → python) 💡 python3 명령어를 python으로 사용할 수 있게 하는 명령어 ```bash sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10 ``` 3. pip (pip3 → pip) 💡 1) pip3 설치 2) pip3 명령어를 pip으로 사용할 수 있게 하는 명령어 * 한 줄 씩 복사 붙여넣기! ```bash # pip3 설치 sudo apt-get update sudo apt-get install -y python3-pip # pip3 대신 pip 라고 입력하기 위한 명령어 sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 ``` 4. mongoDB 설치 - 1. mongoDB 설치 코드 👉 mongoDB 공식자료를 참고해서 정리했습니다. [(링크)](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/) 한 줄 한 줄이 무슨 뜻인지는 지금 굳이 알 필요 없어요! ```bash wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list sudo apt-get update sudo apt-get install -y mongodb-org ``` - 2. mongoDB 실행하기 ```bash # 실행. 아무 반응이 없으면, 잘 실행된 것! # 리눅스는 보통 잘 되면 아무것도 안나와요!^^; sudo service mongod start ``` - 3. mongoDB 접속 계정 생성하기 👉 우리가 만든 mongoDB를 외부에 열어주기 전에, 접속에 필요한 아이디와 비밀번호를 세팅해봅시다! (설정 안하면 누구나 DB정보를 볼 수 있다는..!) ```bash mongo ``` 👉 좌측에 '>' 표시가 나오면 성공적으로 MongoDB에 접속한 것입니다! 다음 명령어를 순차적으로 입력해주세요. 눈치 채셨겠지만, test, test 자리에 내가 넣고 싶은 아이디/비밀번호를 넣으면 됩니다. (영어로..!) ```bash # admin으로 계정 바꾸기 use admin; # 계정 생성하기 db.createUser({user: "test", pwd: "test", roles:["root"]}); ``` 👉 아래와 같은 화면을 보면 완성! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8ed4ba36-eca6-4666-8fc8-1eaa13677c67/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8ed4ba36-eca6-4666-8fc8-1eaa13677c67/Untitled.png) ```bash # 나오기 exit # MongoDB 재시작 sudo service mongod restart ``` - 4. mongoDB를 외부에 열어주기 👉 mongoDB는 디폴트로 내부에서만 접속을 허용하고 있습니다. 이 작업은 외부에서 접근이 가능하도록 잠금을 풀어주는 것입니다. 리눅스 자체 에디터(고급 메모장 정도로 생각!)인 Vim이 등장합니다. `a` 를 눌러야 입력 모드가 되고, `:wq` 를 눌러야 저장하고 나올 수 있습니다. ```bash sudo vi /etc/mongod.conf # sudo: 관리자(SuperUser) 권한으로 다음을 실행 # => "관리자 권한으로 /etc 폴더 아래 mongod.conf 파일을 Vim으로 켜줘!"라는 뜻입니다 ``` 위 명령어를 실행하신 후, 아래 방향 화살 키를 누르시면 다음과 같은 내용이 보입니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d69ab257-4f63-4c57-aad0-53df01a6b404/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d69ab257-4f63-4c57-aad0-53df01a6b404/Untitled.png) ```bash # 입력 모드 전환 i ``` 위 붉은 박스의 내용을 아래와 같이 바꿔주세요! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c734f71b-5d8e-40a3-893b-75085f4cc89c/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c734f71b-5d8e-40a3-893b-75085f4cc89c/Untitled.png) ```bash # 내용 저장하고 에디터 종료하기. esc 누르고 다음 입력. :wq # 재시작 sudo service mongod restart ``` - 5. Robo3T를 이용해서, "내 컴퓨터에서"→"서버에 있는 mongoDB"에 접속하기 - 좌측 상단 빨간 상자 내 아이콘을 클릭합니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9c1c7cfd-3fbd-4432-b9b9-7272bba0caf3/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9c1c7cfd-3fbd-4432-b9b9-7272bba0caf3/Untitled.png) - Create 클릭! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ae1164b5-d27d-4628-80f6-3636ed4eb64c/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ae1164b5-d27d-4628-80f6-3636ed4eb64c/Untitled.png) - 접속 정보를 세팅합니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c05af560-65c7-41e2-93da-7b953cb9bbd2/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c05af560-65c7-41e2-93da-7b953cb9bbd2/Untitled.png) - 상단 Authentication 탭을 클릭합니다. 1. Perform authentication 체크박스를 클릭합니다. 2. 생성한 계정의 아이디와 비밀번호를 입력하고, 'save'를 클릭합니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1e94bb78-ca6d-43db-a30b-00ba4db1482f/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1e94bb78-ca6d-43db-a30b-00ba4db1482f/Untitled.png) 5. 포트포워딩 (80포트 → 5000포트) 💡 80포트로 들어오는 요청을 5000포트로 넘겨주는 명령어 ```bash sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000 ```

12. flask 서버를 실행해보기

  • 20) flask 서버를 실행해보기
    • 기초적인 flask 서버 파일을 하나 만들어봅니다.
      • [코드스니펫] - 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)
    • filezilla를 통해 EC2에 업로드한 다음, 실행해봅니다.
      # 실행
      python app.py
      👉 에러가 납니다! 뭐라고 에러가 나는가요? 👉 정답: flask 패키지가 없는데? - 라는 에러입니다. 그럼, 패키지를 설치해볼까요?
  • 21) pip로 패키지를 설치하기 💡 우리가 file → setting → .. 에서 `+` 버튼 누르고 설치했던 작업을, 명령어로 하면 이렇게 된답니다! 🤓 ```bash pip install flask ```
  • 22) 다시 flask 서버를 실행해보기
    • 아래 명령어로 flask 서버를 실행합니다.
      python app.py
    • 서버 실행이 되면, 크롬에서 접속을 해봅니다.
      크롬 브라우저 창에 아래와 같이 입력합니다.
      
      http://[내 EC2 IP]:5000/
      👉 아직, 작동하지 않을 걸요! → AWS에서 약간의 설정이 더 필요합니다.

13. AWS에서 포트 열어주기

  • 23) AWS에서 5000포트를 열어주기
    • EC2 서버(=가상의 내 컴퓨터)에서 포트를 따로 설정하는 것 외에도,
      AWS EC2에서도 자체적으로 포트를 열고/닫을 수 있게 관리를 하고 있습니다.
      → 그래서 AWS EC2 Security Group에서 인바운드 요청 포트를 열어줘야 합니다.
    • 일단, EC2 관리 콘솔로 들어갑니다. 그리고 보안그룹(영문: Security Group)을 눌러 들어갑니다. 여기선 launch-wizard-1 이라고 쓰여 있네요 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/abb33a37-8c2c-42d2-a670-7a8ac2bc39db/Untitled.png
    • 해당 보안그룹을 클릭합니다. https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d019b103-c370-4928-b9b3-f7adb40dcaaf/_2020-03-23__9.41.03.png
    • Edit inbound rules를 선택합니다. https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bc614d79-8f0b-47ab-8b6b-897b1cc846b5/_2020-03-23__9.41.18.png
    • 세 가지 포트를 추가해봅니다. → 80포트: HTTP 접속을 위한 기본포트 → 5000포트: flask 기본포트 → 27017포트: 외부에서 mongoDB 접속을 하기위한 포트 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5f2b83c6-f6ab-4589-8bfa-a44232b5c642/_2020-03-23__9.42.08.png
  • 24) 다시 접속해봅니다!
    • http://내아이피:5000 → 잘 작동하는 것을 확인할 수 있습니다.
    • 이제 app.py 파일을 수정하고, 다듬어서 올리면 진짜 프로젝트가 되겠죠?

14. 원페이지쇼핑몰 업로드해보기

  • 25) Robo3T를 이용해서, "내 컴퓨터에서"→"서버에 있는 mongoDB"에 접속하기
    • 좌측 상단 빨간 상자 내 아이콘을 클릭합니다. https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9c1c7cfd-3fbd-4432-b9b9-7272bba0caf3/Untitled.png
    • Create 클릭! https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ae1164b5-d27d-4628-80f6-3636ed4eb64c/Untitled.png
    • 접속 정보를 세팅합니다. https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c05af560-65c7-41e2-93da-7b953cb9bbd2/Untitled.png
    • 상단 Authentication 탭을 클릭합니다.
      1. Perform authentication 체크박스를 클릭합니다.

      2. 생성한 계정의 아이디와 비밀번호를 입력하고, 'save'를 클릭합니다.

        https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1e94bb78-ca6d-43db-a30b-00ba4db1482f/Untitled.png

  • 26) 원페이지쇼핑몰 완성본을 filezilla로 EC2에 업로드해봅니다.
    • 그 전에! MongoDB 접속 세팅을 바꿔주세요! 💡 AWS의 MongoDB에 아이디와 비밀번호를 추가했으니, 우리의 pymongo에도 아이디와 비밀번호를 입력해주어야 합니다! 그래야 pymongo가 올바르게 DB에 접근할 수 있습니다. [app.py](http://app.py) 파일을 열어서, 아래 처럼 가운데 한 줄을 바꿔주세요! - **[코드스니펫] - pymongo 계정 접속** ```python client = MongoClient('mongodb://test:test@localhost', 27017) ``` 아래와 같은 뜻이에요! ```python client = MongoClient('mongodb://아이디:비밀번호@localhost', 27017) ```
    • 파일질라에서 homework 폴더 째로 드래그 드롭으로 EC2 인스턴스의 home/ubuntu 폴더에 업로드합니다.
  • 27) 완성본을 실행해봅니다.
    • 실행하려고 시도하기
      # home 디렉토리로 이동
      cd ~
      
      # 해당 폴더로 이동해서 아래 코드를 실행합니다.
      python app.py
    • 에러가 나죠? 패키지를 설치하지 않았기 때문입니다.
      # 설치하기
      pip install pymongo
    • 다시 실행해봅니다
      python app.py
  • 28) 접속해봅니다!
    • 브라우저에서 접속하기
      http://내AWS아이피:5000/

15. 포트포워딩

  • 29) 포트 번호를 떼고 접속해봅니다! 💡 앗, 어떻게 되는걸까! → 아까 세팅해뒀으니까요~! 🤗 ```bash http://내AWS아이피/ ```
  • 30) 포트 번호 없애기 - 기본 개념 💡 우리는 이미 포트포워딩 세팅을 해뒀기 때문에, 여기서는 개념만! - 지금은 5000포트에서 웹 서비스가 실행되고 있습니다. 그래서 매번 :5000 이라고 뒤에 붙여줘야 하죠. 뒤에 붙는 포트 번호를 없애려면 어떻게 해야할까요? - http 요청에서는 80포트가 기본이기 때문에, 굳이 :80을 붙이지 않아도 자동으로 연결이 됩니다. - 포트 번호를 입력하지 않아도 자동으로 접속되기 위해, 우리는 80포트로 오는 요청을 5000 포트로 전달하게 하는 포트포워딩(port forwarding) 을 사용하겠습니다. - 리눅스에서 기본으로 제공해주는 포트포워딩을 사용할 것입니다. 그림으로 보면 아래와 같습니다. ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/072c6efc-1c4f-4446-89de-43111b207798/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/072c6efc-1c4f-4446-89de-43111b207798/Untitled.png)

16. nohup 설정하기

  • 31) SSH 접속을 끊어도 서버가 계속 돌게 하기
    • 현재 상황 Git bash 또는 맥의 터미널을 종료하면 (=즉, SSH 접속을 끊으면) 프로세스가 종료되면서, 서버가 돌아가지 않고 있습니다. 그러나 우리가 원격접속을 끊어도, 서버는 계속 동작해야겠죠?
    • 원격 접속을 종료하더라도 서버가 계속 돌아가게 하기
      # 아래의 명령어로 실행하면 된다
      nohup python app.py &
    • 서버 종료하기 - 강제종료하는 방법
      # 아래 명령어로 미리 pid 값(프로세스 번호)을 본다
      ps -ef | grep 'app.py'
      
      # 아래 명령어로 특정 프로세스를 죽인다
      kill -9 [pid값]
    • 다시 켜기
      nohup python app.py &
  • 32) SSH 접속을 종료한 뒤, 접속해봅니다!
    • 브라우저에서 접속하기
      http://내AWS아이피/

17. 도메인 구입하기

  • 33) 도메인 구입/연결
    • 도메인을 구매한다는 것은, 네임서버를 운영해주는 업체에, IP와 도메인 매칭 유지비를 내는 것입니다. 한국 또는 글로벌 업체 어디든 상관 없지만, 우리는 한국의 '가비아'라는 회사에서 구입해보겠습니다.
  • 34) 구입 후 아래 화면을 띄워주세요
    • 링크: https://my.gabia.com/service#/ (DNS 관리툴 클릭) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/72d0c3ea-b766-494e-83de-a8085f271f12/Untitled.png (도메인 연결 클릭) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/27c7cfbc-c822-4250-877f-0b249ce7c989/Untitled.png (DNS 설정 클릭) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ec8009de-8751-4ede-a9f6-11d2e7e5dd3b/Untitled.png (호스트 이름에 @, IP주소에 IP주소를 입력합니다) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5246fe90-0235-444f-ba62-4426b0404e3f/Untitled.png (이렇게!) https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b5267fc7-7870-4e44-ae32-7d7aae681d6c/Untitled.png
  • 35) 10분 정도 기다려주세요!
    • 네임서버에 내 도메인-IP가 매칭되는 시간이 필요합니다.
  • 36) IP주소로 접근해보기
    • 내 IP주소로 지금 flask 서버가 잘 돌고 있나요? 먼저 확인해봅니다.
      http://내AWS아이피/
    • 약간의 시간을 가진 후, 내 도메인으로 접근하면, 접속이 됩니다.
      http://내도메인/

18. og 태그

  • 37) og 태그 만들기
    • 나홀로메모장에서 배웠던 og:image, og:title, og:description 태그 기억하시나요? 👉 내 프로젝트도 카톡/페이스북/슬랙에 공유했을 때 예쁘게 나오도록, 미리 꾸며봅시다! ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bd5fd2dd-c4c5-4441-8ffa-6ab161e63821/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bd5fd2dd-c4c5-4441-8ffa-6ab161e63821/Untitled.png)
    • static 폴더 아래에 이미지 파일을 넣고, 각자 프로젝트 HTML의 ~ 사이에 아래 내용을 작성하면 og 태그를 개인 프로젝트에 사용할 수 있습니다. 👉 1. "내 사이트의 제목" 입력하기 2. "보고 있는 페이지의 내용 요약" 입력하기 3. 적당한 이미지를 만들거나/골라서 static폴더에 ogimage.png로 저장하기! (사이즈 800x400인 이미지를 구글에서 검색!) - **[코드스니펫] - og태그 넣기** ```jsx ```
    • 참고! 이미지를 바꿨는데 이전 ogimage가 그대로 나와요! 👉 그것은 페이스북/카카오톡 등에서 처음 것을 한동안 저장해놓기 때문입니다. - 페이스북 og 태그 초기화 하기: [https://developers.facebook.com/tools/debug/](https://developers.facebook.com/tools/debug/) - 카카오톡 og 태그 초기화 하기: [https://developers.kakao.com/tool/clear/og](https://developers.kakao.com/tool/clear/og)

🔥 **🎉 와! 수료를 축하합니다!!🎉**

이로써 5주 간의 모든 수업이 끝났습니다. 의미있고 뿌듯했던 5주로 기억되길 진심으로 바랍니다. 새로운 강의로 찾아뵐게요. 많은 기대 부탁드려요!

또 만나요~!😍 (그러나! 마지막 숙제가 아래에 있다는 사실! 😎 )

19. 5주차 끝 & 숙제 설명

📃 **내 도메인을 제출해주세요!**

착착착 잘 따라오셨다면, 원페이지 쇼핑몰을 EC2에 잘 올려두셨을 거예요.

  • 열심히 돌아가고 있는 나의 웹서비스를 제출하시면, 이번 숙제는 끝이랍니다~!🤓

Copyright ⓒ TeamSparta All rights reserved.

profile
https://github.com/jsw4215
post-custom-banner

0개의 댓글