Flask 기초 I

.·2022년 2월 14일

01 Flask 시작하기

웹 서버의 동작 과정 이해하기

웹 서버의 동작 과정


요청과 응답은 어떻게 할까?

  • 미리 약속한 규칙을 통해서 요청하면
    정해진 형태의 데이터응답을 한다.

웹 서버 동작 예시

창구가 API 역할을 하는 것


정해진 형식, 데이터의 통로 API

  • url 주소를 작성하고 Enter키를 크롬창에서 치는 것이 클라이언트가 정해진 형식대로 서버에 데이터를 요청하는 행위
  • 서버가 클라이언트의 요청에 응답해 네이버 페이지를 돌려줌
  • 네이버와 구글의 각각 페이지 접속 주소는 미리 약속된 주소(API 주소)라고 할 수 있다.
  • 미리 약속된 방법으로 요청한 후 해당 페이지를 보게 되는 것이다.
  • 정해진 방식으로 데이터의 통로 역할을 하는것이 바로 API라고 할 수 있다.


Flask Framework란?

Framework

  • 하나의 결과물을 만들기 위해서 제공하는 '틀'
    미리 작성되어 있는 함수 (라이브러리) 이상의 기능을 제공

Flask Framework

  • Flask는 Python을 사용해서 웹 서버를 만들 수 있게 도와주는 Web Framework
  • 다양한 기능을 미리 제공하는 Django와는 다르게 기본적인 기능만 제공하지만 개발이 자유롭다.
  • 나만의 서버를 쉽게 작성할 수 있고, 간단한 코드로 빠르게 실행할 수 있으며 원하는 기능을 유연하게 확장하기 편리하다.


Flask 웹 서버 만들기

Flask Simple Web Server 만들기

  • __name__은 이 파일이 다른 파일에 의해 실행 되었는지, 직접 실행 되었는지 알려주는 것
  • 위의 두 줄은 어떤 Flask 서버를 실행해도 꼭 들어있는 코드
  • @app.route()는 Flask의 기능과 파이썬의 함수가 합쳐져 하나의 API 역할을 함
    route는 데이터가 이동하는 길을 정해준다. (url/api 주소를 만들어줌)


URL을 연결하고 데이터를 화면에 나타내기

어떻게 URL을 연결할까?

  • @app.route()는 url을 만들어 준다.
  • @app.route()와 연결되어 있는 함수를 이용해 HTML, JSON 형식의 데이터를 전달할 수 있다.

JSON 형식의 데이터 나타내기

  • Flask 패키지에서 jsonify를 import
  • jsonify 함수는 jsonify() 안에 있는 내용을 화면에 전달한다.
  • def elice_json() 함수는 app.route()의 url에서 실행할 함수이고, {"name" : "elice"} 라는 데이터를 화면에 전달해준다.

HTML 형식의 데이터 나타내기

파일 준비하기
  • html을 화면에 전달하기 위해서는 html 파일이 필요하다.
  • html 파일을 templates라는 폴더 아래에 넣어준다.
  • templates 폴더에 html 파일을 넣어놓으면 Flask가 자동으로 찾아서 연결해준다.
app.py

  • render_template을 import
  • render_template 함수는 templates라는 폴더 안의 html 파일을 불러와 주는 역할을 한다.
  • templates 폴더 내의 파일 이름과 함수 안의 이름이 같아야 화면에 잘 전달할 수 있다.

여러가지 url 연결하기

@app.route("URL주소")
  • "URL주소"라고 되어있는 부분은 우리가 만들어 줄 수 있는 url의 주소
  • 1개의 @app.route는 1개의 함수와 연결될 수 있다.(가정)

    @app.route(url1)
    @app.route(url2)
    def abc():

=> 함수 abc가 url1과 url2 둘 다 매핑됨(1에서도 함수를 실행시킬 수 있고, 2에서도 함수를 실행시킬 수 있음)

  • @app.route에 연결된 함수의 이름은 중복될 수 없다

  • /student/<name> name 부분을 변수로 받아올 수 있다.
    (/student/elice라고 치면 name이라는 변수에 elice가 들어감)


REST API란?

REST API의 개념

  • HTTP URL을 통해 데이터의 자원을 표현하고
    HTTP Method를 통해서 데이터를 다루는 방법을 의미한다.
    Database, 이미지, 텍스트 등의 다양한 데이터에 적용 할 수 있다.
  • HTTP URI를 통해 자원을 명시하고, HTTP Method를 통해 해당 자원에 대한 CRUD를 적용하는 것



HTTP Method 사용하기

HTTP Method의 개념 - GET/POST

  • GETPOST는 HTTP Method 중 하나
  • GET은 데이터를 URL 뒤에 ?와 함께 사용한다.

    url~~~?name=elice & lecture=python : GET 방식으로 서버에 data를 전송하는 방법 중 하나(보안에 취약하기 때문에 로그인 같은 기능을 만들 때 선호하지 않음)

  • POST는 특정 양식(form)에 데이터를 넣어 전송하는 방법이다.

    데이터를 전송할 때 HTTP Body에 데이터를 넣어 전송하는 방식(보안에 좋고 데이터 길이 제한이 없음)


GET/POST 예시

  • GET 방식 예시

  • POST 방식 예시


app.route()에 method 옵션 사용하기

  • POST 방식으로 url1에 접근하면 에러
  • 이렇게 방식을 나누면 url1번과 url2번이 같아도 상관이 없음(method가 다르기 때문)

GET 요청만 사용하기

  • request.args.get['name']은 url~~~?name = elice라고 되어 있을 때 ? 뒤에 있는 변수의 이름을 []안에 적어주면 그 값을 가져올 수 있다. (url?lecture=pyton일 때 request.args.get['lecture']면 python을 가져옴)

POST 요청만 사용하기 - templates/index.html 만들기

  • elice/1234 데이터가 form이라는 형식에 묶여 서버에 전송된다.
  • 서버에서는 id:elice pwd:1234 이렇게 저장이 됨

여러가지 url 연결하기




02 서비스 다루기

Blueprint와 Jinja Template

Blueprint란?

  • API들을 분류/관리
  • Flask의 기능이 늘어날수록, 코드의 양이 증가한다.
  • 이 때, Blueprint를 사용해서 길어진 코드를 모듈화해주어 수정 개발과 유지보수에 용이하게 코드를 관리할 수 있다.

Blueprint를 사용하지 않았을 때

  • @app.route가 api의 개수(여기선 api가 많다)
  • 만약 게시판 기능 중 글을 수정하는 API를 찾아야하는데 API의 수가 많다보니 찾기가 힘듦

Blueprint를 사용하였을 때

  • app.py는 오로지 서버 실행에만 집중할 수 있다.
  • API들을 따로 모아서 파이썬 파일을 만들고 사용

Jinja2란?

  • Jinja2는 Python에서 가장 많이 사용되는 템플릿이다.
  • 서버에서 받아온 데이터를 효과적으로 보여주고
    비교적 간략한 표현으로 데이터를 가공할 수 있다.(HTML 내에서 Python 문법처럼 데이터를 불러오고 출력할 수 있음)

Jinja2 Template에서 데이터 넘겨주기 - 단일변수

  • return render_tempate 안에 선언해준 변수 이름으로 데이터가 전송된다.

Jinja2 Template에서 데이터 넘겨주기 - list

  • {% %}를 사용하면 저 안에서 python 문법을 사용할 수 있다.
  • endfor는 for문이 끝났다고 알려주는 거 같은 느낌(if문에서도 endif써줌)

Jinja2 Template에서 데이터 넘겨주기 - dictionary

  • 딕셔너리 값을 가져올 때는 key값을 기준으로 가져온다.


게시판을 위한 CRUD 설계 및 제작

CRUD



Authentication이란?

Authentication vs Authorization

  • 인증 : 로그인(2FA, OTP, SMS, PIN 등)
  • 권한 : 이 서버에서 어떠한 역할/기능을 하고 사용할 수 있는지

Authentication

  • 사용자가 누구인지 확인하는 절차(회원가입하고 로그인하는 과정)


로그인 기능 구현

쿠키

  • 클라이언트에 저장되는 키/값이 들어있는 데이터
  • 사용자가 따로 요청하지 않아도 Request 시에 자동으로 서버에 전송한다.

세션

  • 쿠키를 기반으로 하지만 서버 측에서 관리하는 데이터
  • 클라이언트에 고유 ID를 부여하고 클라이언트에 알맞은 서비스를 제공한다.
  • 서버에서 관리하기 때문에 보안이 쿠키보다 우수하다.

로그인 예제

  • user_id : 화면으로부터 입력받은 데이터
  • user['user_id] : 서버가 가지고 있는 데이터
  • user.id : 유저의 고유한 id(세션에 유저의 정보를 모두 넣으면 위험할 수도 있으므로 고유한 id 같은 거만 넣음)

로그아웃 예제



로깅

로깅이란?

  • 로깅프로그램이 작동할 때 발생하는 이벤트(프로그램의 기능)를 추적하는 행위를 말한다.
  • 프로그램의 문제들을 파악하고 유지보수 하는 데 사용되며, 로깅을 통해 발생한 에러를 추적할 수 있다.

로깅 - level

  • DEBUG < INFO < WARNING < ERROR < CRITICAL
    기본 로거 레벨 세팅은 WARNING이기 때문에 설정 없이 INFO, DEBUG를 출력할 수 없다.
    높은 레벨은 아래 레벨을 신경쓰지 않는다.

  • 기본은 WARNING이기 때문에 info는 출력하지 않는다.

  • logging.getLogger() : 어떤 것으로 로깅을 할 것인지
  • setlevel(logging.DEBUG) : DEBUG로 세팅
  • DEBUG로 세팅하였기 때문에 info 출력된다.

Flask에서 로깅

  • 에러가 발생했을 때 Flask의 logger를 사용하여 에러를 확인할 수 있다.
  • import logging 안해줘도 된다.



03 RDB로 리소스 관리 및 저장하기

관계형 데이터베이스

데이터베이스

  • 데이터를 저장하는 공간으로서, 서비스를 개발하는 곳에서는 빠질 수 없는 중요한 요소입니다.

관계형 데이터베이스(RDb)

  • 키(key)값(value)들의 간단한 관계를 테이블 화 시킨 데이터베이스
  • 특징 : 정형화 된 Data, DML을 사용해 데이터 간 결합, 제약조건 등의 설정을 통해 데이터를 추출할 수 있다.

RDB의 형태


RDB와 Flask의 상호작용

RDB와 Flask

  • 파이썬은 오픈 소스와 상용 DB에 대한 대부분의 DB엔진을 위한 패키지를 가지고 있다.
  • Flask에서 입력받은 내용을 DB에 저장할 수 있다.
    ->효율적인 데이터 관리 가능


간단한 게시판 만들기

구현 사항

  • 사용자 검색
  • 사용자 추가(중복 사용자는 방지)
  • 게시판 내용 생성, 조회, 수정, 삭제

게시판 등록

  • Ex) Create => cur.execute("INSERT INTO Board (name, context) values(?,?)", (name, context))
  • con = sqlite3.connect(db정보) => DB에 연결
  • cur = con.cursor() => sql문을 다룰 수 있게 도와주는 커서라는 객체
  • cur.execute(~~~)


Flask JWT

JWT(JSON Web Token)란?

  • 웹 표준으로서 두 개체에서 JSON 객체를 사용하여 통신합니다.(JSON Web Token은 하나의 인증 매개체)

JWT 생김새

  • Header에는 토큰의 타입과 알고리즘을 저장한다.
  • Payload에는 토큰에 담을 정보를 넣는다.
  • Signature에는 헤더와 정보의 인코딩 값들과 관련된 비밀키가 들어있다.

JWT 구조

  • JWT는 HEader ,Payload, Signature 3가지로 이뤄지며, JSON 형태인 각 부분은 Base64로 인코딩되어 표현된다.
  • 각각의 부분을 이어주기 위해 . 구분자를 사용한다.

Payload

  • 클레임은 3가지로 나누어져 있다.(register, public, private)
  • 등록된 클레임(registered) : 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터(토큰 발급자(issuer), 토큰 제목(subject), 대상자(audience), exp(만료시간), iat(토큰이 발급된 시간), jti(고유식별자))이다.
  • 공개 클레임(public) : 충돌이 방지된 이름을 가지고 있어야 한다. 충돌을 방지하기 위해 클레임 이름을 URI 형식으로 짓는다.(공개 클레임 예제 =>{https://elice.io: true})
  • 비공개 클레임(private) : 등록과 공개를 제외한 클레임이자 사용자 정의 클레임으로 서버와 클라이언트 협의로 사용되는 클레임이다. 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다. 이 클레임은 공개 클레임과 달리 이름이 중복되어 충돌될 수 있으니 유의해아 한다.(비공개 클레임 예제 => {"student_name": "elice"}

Signature

JWT 예시



04 SQL Alchemy

SQL Alchemy와 ORM

ORM이란?

  • 데이터베이스에 객체를 통해 접근하는 방법을 ORM(Object Relational Mapping, 객체 관계 매핑)이라고 한다.
  • ORM은 SQL 질의어가 없어도 데이터베이스를 다룰 수 있도록 도와준다.
  • Python의 Class(객체로 봄)를 사용해 DB에 접근

SQL 쿼리 vs ORM

  • Member()는 Class
  • member1.name, member1.age에 값을 넣어 클래스 안의 각각의 요소들에 데이터를 저장

ORM 장점

  • DB를 코드로 다룰 수 있다.
  • 테이블 구조가 변경될 때, ORM 모델만 수정하면 된다.
  • 코드로 작성하기 때문에 쿼리를 직관적으로 이해할 수 있다.

SQL Alchemy란?

  • 파이썬 ORM 라이브러리
    -> 파이썬 코드에서 Database와 연결하기 위해 사용할 수 있는 라이브러리

DB와 Model

DB와 Model

  • 첫 번째 줄이 앞에서 봤던 member1 = Member()
    member1.name = ~~
    member1.age=~~와 같은 의미

ORM Model

  • db = SQLAlchemy()
    이렇게 하면 db에 SQLAlchemy의 모든 기능을 사용할 수 있음
  • id, name, age는 직접 넣어주지는 않지만 어떤 데이터가 들어갈 것이라고 명시해주는 것
  • members = Members()라고 해주면 members라는 변수 이름으로 데이터베이스에 접근할 수 있음

  • db.session.query(Members) = Members.query : Members테이블에 ORM 쿼리 사용 할거라는 뜻
  • .filter(Members.name ==name) : Members 테이블의 name이 내가 가진 name과 같은 것만 가져오겠다는 뜻


Query

CRUD 예제 - Create: 데이터 저장

  • Create 할 때는 db.session.add(내가 만든 클래스 안에 있는 변수들을 테이블 안에 넣을 것이다) 생각하기

CRUD 예제 - Read: 데이터 읽기

  • Members 테이블에 ORM 쿼리 사용
  • .all() : list형태로 데이터가 반환
  • db.session.query(Members).first() : 젤 처음 데이터 하나만 가져옴(Model 객체 반환)

CRUD 예제 - Update: 데이터 수정

  • Read를 먼저 해주고 Update
  • members[0].name => 이렇게 해야함

CRUD 예제 - Delete: 데이터 삭제

  • Read 먼저 해주고 Delete
  • 얘는 .first()이므로 [0]이 없어도 됨

Query 사용법 - equal

Query 사용법 - not equal

Query 사용법 - like

  • Member.name.like('%Elice%')와 같음

Query 사용법 - in

Query 사용법 - not in

  • ~:not

Query 사용법 - is null

Query 사용법 - is not null

Query 사용법 - and

  • db.session.query(Member).filter((A조건) & (B조건) & (C조건)) : and조건이랑 같음

Query 사용법 - or

Query 사용법 - order by

Query 사용법 - limit

Query 사용법 - offset

limit과 offset 같이 사용 가능

member_list = Member.query.order_by(Member.age.desc()).limit(limit_num).offset(offset_num)

Query 사용법 - count



이미지 출처 - Elice

0개의 댓글