파이썬 - 네이버 검색 Open API를 이용하여 책 검색하기

|

개인적인 연습 내용을 정리한 글입니다.
더 좋은 방법이 있거나, 잘못된 부분이 있으면 편하게 의견 주세요. :)


들어가기

개발을 공부하면서 API 라는 단어는 많이 들어보았다. 하지만 구체적으로 API가 무엇인지 언제 어떻게 사용하는지에 대한 개념이 모호한 상태였다.

최근 친구와 함께 AskDjango 해커톤에 참여하기로 했다. 주제는 책에 관련된 것으로 하고, 교보문고와 같은 사이트에서 책 정보를 크롤링으로 가져오자는 의견이 있었다. 크롤링 보다 더 좋은 방법이 있지 않을까 하는 생각이 들어서 고민 중이었는데, 마침 참여 중인 8퍼센트 스터디에서 도서검색 API에 대한 이야기가 나왔다. 찾아보니 네이버에서 검색 API를 제공하고 있었고, 테스트를 해보니 아주 간편하게 원하는 도서 정보를 가져올 수 있었다. (이걸 모르고 크롤링을 하려고 했다니..!)

구체적인 API 사용법에 대해서는 네이버 API 사이트 에서 확인할 수 있다. 여기서는 샘플로 제공하는 API 호출 코드의 각각의 기능에 대해서 공부할 겸 정리하려고 한다.


코드개요

  • 네이버 책 검색 API를 활용하여 ‘파이썬’이 포함된 검색결과를 JSON으로 가져온다.
  • 조건
    • 검색어 : ‘파이썬’ (query)
    • 검색결과는 3개 출력 (display=3)
    • 정렬 옵션 : 판매량순 (sort=count)
 import urllib.request
 client_id = "MY_CLIENT_ID" # 애플리케이션 등록시 발급 받은 값 입력
 client_secret = "MY_CLIENT_SECRET" # 애플리케이션 등록시 발급 받은 값 입력
 encText = urllib.parse.quote("파이썬")
 url = "https://openapi.naver.com/v1/search/book?query=" + encText +"&display=3&sort=count"
 request = urllib.request.Request(url)
 request.add_header("X-Naver-Client-Id",client_id)
 request.add_header("X-Naver-Client-Secret",client_secret)
 response = urllib.request.urlopen(request)
 rescode = response.getcode()
 if(rescode==200):
     response_body = response.read()
     print(response_body.decode('utf-8'))
 else:
     print("Error Code:" + rescode)
  • JSON 형식의 결과 데이터는 json.loads() 메소드를 통해서 파이썬에서 활용 가능한 객체 (예: dict) 로 변환하여 사용한다.
import json
json_rt = response.read().decode('utf-8')
py_rt = json.loads(json_rt)

결과값 예시

  • JSON 형식으로 예쁘게 결과값을 가져온다.
{
    "lastBuildDate": "Sat, 15 Jul 2017 18:28:50 +0900",
    "total": 486,
    "start": 1,
    "display": 3,
    "items": [
        {
        "title": "Do it! 점프 투 <b>파이썬</b> (이미 50만 명이 '점프 투 <b>파이썬</b>'으로 시작했다!)",
        "link": "http://book.naver.com/bookdb/book_detail.php?bid=10290989",
        "image": "http://bookthumb.phinf.naver.net/cover/102/909/10290989.jpg?type=m1&udate=20160528",
        "author": "박응용",
        "price": "18800",
        "discount": "16920",
        "publisher": "이지스퍼블리싱",
        "pubdate": "20160303",
        "isbn": "8997390910 9788997390915",
        "description": "스스로 <b>파이썬</b> 프로그램을 만들 수 있는 실력을 키워보자!《DO IT! 점프 투 <b>파이썬</b>》은 지난 10년간 온라인 독자들의 질문 댓글에 답변하며 쌓아온... 책은 <b>파이썬</b>의 문법들을 실생활에서 쉽게 접할 수 있는 일들을 사례로 들어 설명하는 저자의 탁월함이 돋보인다. 더불어 최신 <b>파이썬</b> 3버전을 기준으로 내용을... "

        }
}

각 코드의 의미

urllib 모듈 import

 import urllib.request
  • 웹 서버에 웹 페이지를 요청하고 응답받기 위해서 일반적으로 브라우저를 사용한다.
  • python에서 브라우저 없이 http 프로토콜에 따라서 서버 요청/응답을 할 수 있도록 도와주는 것이 urllib 모듈이다. (파이썬 표준 모듈)
    • request는 클라이언트의 요청을 처리한다.
    • response는 서버의 응답을 처리한다.
    • parse는 URL을 분석한다.

request url 생성

encText = urllib.parse.quote("파이썬") # 한글을 URL에 추가하기 위해서 UTF-8 형식으로 URL 인코딩
url = "https://openapi.naver.com/v1/search/book?query=" + encText +"&display=3&sort=count" # 요청 URL + 요청 변수

Request 객체 생성 및 header 추가

search_request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
  • urllib.request.Request 클래스는 URL 요청과 관련된 정보를 담는 추상화된 클래스이다. http 통신 시 header 값을 설정하거나, HTTP request method 등을 설정 가능하다.
  • Request 클래스의 add_header메소드를 활용하여 헤더 정보를 추가한다. 네이버 API를 사용하려면 클라이언트 정보를 헤더에 포함시켜야 한다.

    HTTP 헤더는 웹서버로 보내는 요청과 요청 데이터를 설명하는 메타 정보들이 들어있습니다. 즉 메서드가 무엇인지, 요청 URL이 무엇인지, http 프로토콜 버전 등이며, 여기에 추가적으로 지정된 이름과 값을 전송할 수 있습니다. 네이버 오픈 API는 기본적으로 클라이언트 아이디와 시크릿값을 헤더에 포함하여 전송해야 이용할 수 있도록 되어 있습니다. (출처)

urlopen 및 response 획득

response = urllib.request.urlopen(request)
  • urllib.request.urlopen 메소드는 url string 혹은 request 객체를 전달 받는다. 여기서는 header 정보를 포함한 request 객체를 전달한다. urlopen 메소드는 http.client.HTTPResponse 객체를 리턴하며 해당 객체는 아래와 같은 메소드를 가진다.
    • geturl() : source 의 url을 반환한다. 일반적으로 redirect 여부를 확인하기 위해 사용한다.
    • getcode() : response의 HTTP status code 를 리턴한다.

HTTP status code 확인 및 response 데이터 디코딩

rescode = response.getcode()
if(rescode==200):
    response_body = response.read()
    print(response_body.decode('utf-8'))
else:
    print("Error Code:" + rescode)
  • getcode 메소드를 통해서 response의 HTTP status code를 확인한다.
  • 네이버 오픈 API 에러 코드 목록
  • status code가 200인 경우 (정상 호출) read() 메소드를 통해서 http.client.HTTPResponse 객체로 부터 데이터를 읽어온다. (바이트형식)
  • decode(‘utf-8’)을 통해서 UTF-8 형식으로 디코딩하여 print 한다.

결론

  • API에 대해서 막연한 두려움이 있었는데, 이번 기회를 통해서 그동안 가졌던 모호한 이미지를 구체화 시킬 수 있었다.
  • 예전에 처음 시작하는 파이썬의 파이썬 라이브러리 모듈 부분은 재미가 없어서 대충 읽고 넘겼었다. api 샘플 코드를 공부하면서 urllib.request 모듈 부분을 다시 찾아서 읽으니 도움이 많이 되었다.
  • 역시 필요성이 발생할 때 공부하는게 효율은 최고인 것 같다.

Django - settings.py 의 SECRET_KEY 변경 및 분리하기

|

Two Scoops of Django 5장을 읽고 연습한 내용을 정리한 글입니다.
더 좋은 방법이 있거나, 잘못된 부분이 있으면 편하게 의견 주세요. :)


들어가기

django-admin startproject 명령을 통해서 장고 프로젝트를 생성하면, 기본으로 settings.py 파일이 함께 포함된다. settings.py 안에는 다양한 설정 항목이 있는데, 그 중에서 SECRET_KEY 라는 것이 있다. 이는 장고 보안 기능에 활용되는 값으로, 그동안 github의 공개 저장소에 SECRET_KEY를 그대로 노출한 상태로 settings.py 파일을 함께 push 했었다.

최근 Two Scoops of Django5.3 코드에서 설정 분리하기 를 읽어보니 비밀 값들은 외부에 공개되면 안된다는 내용이 있었다. 누구나 한번 쯤은 SECRET_KEY를 외부에 노출한 경험은 있을 것 같은데, 이번 기회에 settings.py의 비밀 값을 코드에서 분리해야겠다고 생각했다.

비밀 값들은 반드시 남이 알 수 없어야 한다. 이를 버전 컨트롤 시스템에 추가하면 코드 저장소에 접근할 수 있는 누구에게나 공개된다


SECRET_KEY

SECRET_KEY는 어디에 사용될까? Django 공식문서 를 보면 다음과 같이 안내되어 있다.

  • django.contrib.sessions.backends.cache 이외의 session backend를 사용하고 있거나,
    기본 get_session_auth_hash()를 사용하는 모든 sessions
  • CookieStorage 혹은 FallbackStorage 를 사용하는 모든 messages
  • 모든 PasswordResetView
  • 다른 키가 제공되지 않는 암호화 서명 사용 시 사용된다.
views
그리고 SECRET_KEY는 공개하면 안된다


위 문서와 같이 비밀 키가 노출되면 Django의 보안 기능이 상실될 위험성이 있다.

나는 이미 공개 저장소에 올려버렸는데 어쩌지?!

views
어쩌면 좋지..!


나를 포함해서 이렇게 생각할 분들이 많을 것 같아서 찾아보니 배포 후에도 SECRET_KEY 변경이 가능하다는 글이 있었다. (Is it possible to change the secret key of a Django application after it deployment in production, If so, what would be the impacts?) SECRET_KEY는 주로 쿠키데이터 해시, 암호화 등 임시적인 일에 사용되고, 변경 시 로그인 세션 등의 데이터가 사라질 수 있다. 확인 차 개인 프로젝트의 SECRET_KEY를 변경하여 로컬 서버에서 다시 테스트를 해보니 큰 문제는 발생하지 않았다. 프로젝트 초반이거나, 복잡한 기능이 없는 프로젝트에서는 변경해도 괜찮다고 생각한다. (혹시 아니라면 댓글로 알려주시면 감사합니다!)

SECRET_KEY는 50자의 랜덤 문자로 구성되어 있는데, Django Secret Key Generator 라는 것도 존재한다. 혹은 아래의 코드를 실행해서 임의 50글자를 직접 생성하는 것도 가능하다. (코드 출처)

import string, random


# Get ascii Characters numbers and punctuation (minus quote characters as they could terminate string).
chars = ''.join([string.ascii_letters, string.digits, string.punctuation]).replace('\'', '').replace('"', '').replace('\\', '')

SECRET_KEY = ''.join([random.SystemRandom().choice(chars) for i in range(50)])

print(SECRET_KEY)

SECRET_KEY 분리하기

settings.py 파일에서 비밀 값을 분리하는 방법은 여러가지가 있는데 책에서 소개하는 방법은 2가지이다.

  • 환경변수패턴 : SECRET_KEY의 값을 환경변수에 저장하여 참고한다.
  • 비밀파일패턴 : SECRET_KEY의 값을 별도 파일에 저장하여 참고한다.

1. 환경변수패턴

환경변수란 프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는, 동적인 값들의 모임이다.(위키) 시스템의 실행파일이 놓여 있는 디렉토리의 지정 등 OS 상에서 동작하는 응용소프트웨어가 참조하기 위한 설정이 기록된다. 환경변수를 사용하여 비밀 키를 보관함으로써 걱정 없이 세팅파일을 github 공개 저장소에 추가할 수 있다.

로컬 개발 환경에서 환경 변수를 세팅하려면 다음 코드를 .bashrc 혹은 .bash_profile, .profile, .zshrc 파일에 추가하면 된다. 어느 종류의 shell을 사용하는지에 따라서 편집하는 파일이 달라진다.(mac 사용자 기준) 나의 경우 zsh을 사용하고 있어서 .zshrc에 아래와 같이 환경변수 추가 작업을 진행했다.

$ vim ~/.zshrc # vim을 사용하여 .zshrc 파일을 편집하겠다.

# .zshrc 파일에 아래 코드를 추가해준다.
export INSTA_SECRET_KEY='b_4(!id8ro!1645n@ub55555hbu93gaia0 본인의 고유 비밀 키 추가'

# 환경변수 확인 명령
$ echo $INSTA_SECRET_KEY

추가 완료 후, settings.py 파일을 열어서 SECRET_KEY 의 값을 삭제하고 환경변수로 대체한다.

# settings.py
import os


# 환경변수 INSTA_SECRET_KEY 의 값을 참조한다.
SECRET_KEY = os.environ["INSTA_SECRET_KEY"]

혹은 아래와 같은 예외 처리를 통해서 환경변수가 존재하지 않을 때 원인을 파악하기 쉽도록 할 수 있다.

# settings.py
import os
from django.core.exceptions import ImproperlyConfigured


def get_env_variable(var_name):
  """환경 변수를 가져오거나 예외를 반환한다."""
  try:
    return os.environ[var_name]
  except KeyError:
    error_msg = "Set the {} environment variable".format(var_name)
    raise ImproperlyConfigured(error_msg)


SECRET_KEY = get_env_variable("INSTA_SECRET_KEY")

쉘에서 python3 manage.py runserver 명령을 입력하니 정상적으로 개발 서버가 구동되는 것을 확인 할 수 있었다. 참고로 실제 운영환경에서 환경변수를 세팅하려면, 각자 사용하는 배포도구에 따라서 변수 지정방법이 달라진다.


2. 비밀파일패턴

환경변수는 경우에 따라 적용되지 않을 수 있다. (아파치를 웹 서버로 이용하는 등) 이럴 경우에는 JSON 파일에 비밀 키 정보를 입력하고, settings.py에서 참고하도록 설정할 수 있다. 우선 아래와 같이 secrets.json 파일을 작성한다. (주의 - 이어지는 항목이 없는 경우, 쌍따옴표 뒤에 콤마(,)를 입력해서는 안된다. python git 갱신이력을 깔끔하게 관리하려고 dictionary 마지막 항목에도 콤마를 추가하는 습관이 있어서 그대로 적용했더니 json에서는 오류가 발생했다.)

{
  "SECRET_KEY": "b_4(!id8ro!1645n@ub55555hbu93gaia0 본인의 고유 비밀 키 추가"
}

작성한 secrets.json 파일은 버전관리 시스템에 저장되지 않도록 .gitignore 문서에 추가한다. 그리고 해당 파일을 SECRET_KEY 값으로 참고하기 위해서 다음 코드를 settings.py에 추가한다.

# settings.py

import os, json
from django.core.exceptions import ImproperlyConfigured


secret_file = os.path.join(BASE_DIR, 'secrets.json') # secrets.json 파일 위치를 명시

with open(secret_file) as f:
    secrets = json.loads(f.read())

def get_secret(setting, secrets=secrets):
    """비밀 변수를 가져오거나 명시적 예외를 반환한다."""
    try:
        return secrets[setting]
    except KeyError:
        error_msg = "Set the {} environment variable".format(setting)
        raise ImproperlyConfigured(error_msg)

SECRET_KEY = get_secret("SECRET_KEY")

쉘에서 python3 manage.py runserver 명령을 입력하니 이 방법을 사용해도 정상적으로 개발 서버가 구동되는 것을 확인 할 수 있었다.


결론

AWS 루트키가 github 공개 저장소에 추가되면 악용되어서 요금폭탄을 맞을 수도 있다는 이야기는 많이 들어보았다. 하지만 settings에 대해서는 비교적 신경을 쓰지 못했다. Django 초보라면 대부분 SECRET_KEY를 본인의 공개 저장소에 올려본 경험은 있지 않을까? 물론 배포 전에 변경하고 분리하는 것이 가능 하지만, 그에 따른 부작용이 발생 할 수 있으니 처음부터 관리하는게 좋겠다. 앞으로 first commit 이전에 SECRET_KEY를 환경변수 혹은 json 파일로 분리하거나, 초반에는 .gitignore 파일에 settings.py 파일을 추가해 놓는 것도 괜찮겠다는 생각을 했다.

170710-0716_TIL

|

7월 16일 (일)

  • 장고의 디폴트 User model을 확장하는 연습을 했다. 연습내용
    • 처음 manage.py migrate 명령을 실행하기 전에 settings.py의 AUTH_USER_MODEL을 변경해야 한다는 것을 알았다. ( dependency issue가 발생하여 여러번 시행착오를 겪었다.)
    • AbstractBaseUser을 상속 받아서 nickname, team, avatar 필드를 추가한 Custom User 모델을 만들었다.
    • BaseUserManager을 상속 받아서 유저 생성시에 email, nickname을 함께 받도록 했다.
    • 인스타그램st 프로젝트에서는 OneToOne Relation을 활용해서 profile 모델을 따로 만들고 기본 User와 1:1로 연결했었다. 나중에 django-debug-toolbar를 확인해보니 User 모델을 통해서 Profile 모델의 데이터를 가져올 때 중복으로 DB 요청이 발생하는 문제가 있었다. 그때는 select_related를 활용해서 매번 중복을 제거했다. 이번에는 User 모델 자체를 오버라이드 했으니 중복 쿼리가 발생하는 부분은 개선되지 않을까.

내일 할 일


7월 15일 (토)


7월 14일 (금)

  • Naver Book API를 활용하는 연습을 했다.
    • API를 활용해서 원하는 책 정보를 JSON 형식으로 가져오고, JSON 디코딩을 통해서 Dict 형식으로 템플릿에 context를 넘겨주었다.
    • 템플릿에 책 정보를 표시하고, 원하는 책을 선택하면 해당 정보를 저장하여 db 레코드를 생성하도록 했다.
  • 패캠 인스타그램 연습 repository 커밋 로그를 하나씩 따라가면서, 다른 사람이 작성한 코드를 읽고 Django를 공부했다.

7월 13일 (목)

  • Naver Book API를 사용해서 원하는 책 정보를 json으로 가져오는 연습을 했다.
  • 이번에 스터디와 해커톤에서 책 관련된 프로젝트를 진행하기로 했다. 새로 출간되는 도서 정보가 필요한데 크롤링을 통해서 정보를 가져오자는 팀원의 의견이 있었다. 개인적으로는 크롤링 보다 더 좋은 방법이 있지 않을까 하는 생각이 들어서 고민 중이었는데 마침 스터디에서 도서검색 API 이야기가 나왔다. 마침 네이버에서 도서 검색 API를 제공하고 있어서 사용해보니 원하는 조건의 책 정보를 json으로 이쁘게 가져올 수 있었다. (우와 신기..!) 이제 가져온 json 정보를 db에 저장하고, 정기적으로 정보를 자동 갱신 할 수 있도록 연습해봐야지.

7월 12일 (수)


7월 11일 (화)

  • Two Scoops of Django 4~5 장을 읽었다.
  • Django settings.py 파일에서 SECRET_KEY 설정을 분리하는 부분을 연습했다. 그동안 public repository에 SECRET_KEY가 그대로 노출된 상태로 push를 진행해왔다. AWS 키가 노출되면 안된다는 이야기는 워낙 많이 들어서 조심했지만 SECRET_KEY는 챙기지 못했다. 아마 Django를 처음 배우는 사람이라면 한번쯤은 겪는 과정이 아닐까 싶다. SECRET_KEY 설정을 분리하는 방법은 2가지가 있다. 둘 다 연습해보았는데 앞으로는 git 저장소에 push 하기 전에 꼭 신경써야겠다. (first commit 부터!) 참고
    • 환경변수패턴 (environment variables pattern)
    • 비밀파일패턴 (secrets file pattern)
  • Django Project에서 회원 가입시에 이메일을 발송하는 부분을 연습했다.
    • How to Configure Mailgun To Send Emails in a Django Project 글을 참고해서 Mailgun 서비스를 사용해보기로 했다.
    • 사이트의 설명대로 내가 가진 도메인에 DNS records를 추가하였고, 도메인이 인증되고 상태가 activate으로 바뀌기를 기다렸다.
    • 48시간이 지나도 disabled 상태여서 고객센터에 메일을 보냈다. 원인은 Mailgun의 Business Verification process 때문이고 사용 목적을 포함한 몇가지 질문에 답변하면 도메인 상태를 activate로 바꿔주겠다고 했다. (왜 처음부터 이런 안내는 없었을까? 내가 수상해 보였나..ㅠㅠ)
    • ‘난 학생이고 연습 사이트의 가입 안내 목적으로 하루에 100건 이하의 메일만 보낼 예정이다’ 라고 답변했더니 도메인이 activate로 변경되었다.
    • 드디어 메일을 보내려고 테스트를 진행해보니 ‘Free accounts are for test purposes only. Please upgrade or add the address to authorized recipients in Account Settings.’ 라는 오류 메시지가 뜬다. 수신자 메일 목록을 등록하고 인증받은 사용자에게만 test 메일을 보낼 수 있었다.
    • 테스트로 사용할 수신자 메일 인증을 완료하고 메일이 정상 수신되는 것 까지 확인했다. 인증절차 없이 누구에게나 메일을 보내기 위해서는 아래 2가지 방법을 활용할 수 있다.
      • Mailgun 계정에 신용카드를 등록하고 upgrade 한다.
      • MX 레코드 설정을 추가한다. 참고

7월 10일 (월)

  • 패캠 인스타그램 연습 repository 커밋 로그를 하나씩 따라가면서, 다른 사람이 작성한 코드를 읽고 Django를 공부했다.
    • include 를 활용하여 중복되는 코드의 양을 줄이는 법에 대해서 살펴보았다. include 템플릿명 with type=”list” 와 같이 원하는 context를 keyword arguments 형식으로 템플릿에 넘겨줄 수 있다. 이를 통해서 동일한 include 템플릿이라도 다르게 동작하도록 구현할 수 있다.
    • Model Form을 사용하지 않고 직접 form을 작성하고, clean 메소드를 통해서 유효성 검사를 진행하는 부분을 살펴보았다. Model Form이 얼마나 편한지 다시한번 느낄 수 있었다.
  • 간단한 알고리즘 문제를 풀었다.

git 초보를 위한 풀리퀘스트(pull request) 방법

|

처음으로 github pull request (PR)를 하면서 겪었던 시행착오를 기록합니다.
더 좋은 방법이나, 잘못된 내용이 있으면 편하게 의견 주세요 :)


들어가기

“회사 기술블로그 repository를 포크떠서 후기 작성하시고 저한테 PR 보내주세요”

views
(포크..PR.. 말로만 들어봤는데 먹는 걸까?)


  • 개인 github repository 관리 경험은 있지만 pull request 는 처음이라 어떻게 해야하나 걱정이 앞섰다.
  • 뭐 찾아보면 되겠지..! 하는 마음으로 집에 왔는데, 생각보다 쉽게 설명된 자료를 찾지 못해서 시행착오를 겪었다.
  • 앞으로 협업을 하다보면 pull request 할 일이 많을 거라고 생각해서 이번 기회에 정리해두려고 한다.

개요

  • pull request를 위해서 아래와 같은 절차를 거쳤다. 각 절차에서 작업한 내용은 다음 절에 하나씩 정리하려고 한다. 분명 비효율적인 부분이 있을 수 있는데, 댓글로 알려주시면 정말 정말 도움이 될 것 같다.
  1. Fork
  2. clone, remote설정
  3. branch 생성
  4. 수정 작업 후 add, commit, push
  5. Pull Request 생성
  6. 코드리뷰, Merge Pull Reqest
  7. Merge 이후 branch 삭제 및 동기화

1. Fork

  • 타겟 프로젝트의 저장소를 자신의 저장소로 Fork 한다.

pr1

p2


2. clone, remote 설정

  • fork로 생성한 본인 계정의 저장소에서 clone or download 버튼을 누르고 표시되는 url을 복사한다. (중요 - 브라우저 url을 그냥 복사하면 안 된다)

p3


  • 터미널을 켠다. (mac 기준)
  • 자신의 컴퓨터에서 작업을 하기 위해서 Fork한 저장소를 로컬에 clone 한다.
$ git clone https://github.com/wayhome25/blog.github.io.git
  • 로컬 저장소에 원격 저장소를 추가한다. 위 작업과 동일하게 github 저장소에서 clone or download 메뉴를 통해서 확인한 url을 사용한다.
    • 원본 프로젝트 저장소 (직접 추가 필요)
    • fork한 로컬 프로젝트 (origin이라는 별명으로 기본으로 추가되어 있다. 따로 추가할 필요 없음)
# 원본 프로젝트 저장소를 원격 저장소로 추가
$ git remote add real-blog(별명) https://github.com/원본계정/blog.github.io.git

# 원격 저장소 설정 현황 확인방법
$ git remote -v

3. branch 생성

  • 자신의 로컬 컴퓨터에서 코드를 추가하는 작업은 branch를 만들어서 진행한다.

개발을 하다 보면 코드를 여러 개로 복사해야 하는 일이 자주 생긴다. 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발을 진행할 수 있는데, 이렇게 독립적으로 개발하는 것이 브랜치다. - pro git book

# develop 이라는 이름의 branch를 생성한다.
$ git checkout -b develop
Switched to a new branch 'develop'

# 이제 2개의 브랜치가 존재한다.
$ git branch
* develop
  master

4. 수정 작업 후 add, commit, push

  • 자신이 사용하는 코드 편집 툴을 활용하여 수정 작업을 진행한다.
  • 작업이 완료되면, add, commit, push를 통해서 자신의 github repository (origin)에 수정사항을 반영한다.
  • 주의사항 push 진행시에 branch 이름을 명시해주어야 한다.
# develop 브랜치의 수정 내역을 origin 으로 푸시한다.
$ git push origin develop

5. Pull Request 생성

  • push 완료 후 본인 계정의 github 저장소에 들어오면 Compare & pull reqeust 버튼이 활성화 되어 있다.
  • 해당 버튼을 선택하여 메시지를 작성하고 PR을 생성한다.

p4
p5


6. 코드리뷰, Merge Pull Reqest

  • PR을 받은 원본 저장소 관리자는 코드 변경내역을 확인하고 Merge 여부를 결정한다.

7. Merge 이후 동기화 및 branch 삭제

  • 원본 저장소에 Merge가 완료되면 로컬 코드와 원본 저장소의 코드를 동기화 한다.
  • 작업하던 로컬의 branch를 삭제한다.
# 코드 동기화
$ git pull real-blog(remote 별명)
# 브랜치 삭제
$ git branch -d develop(브랜치 별명)
  • 나중에 추가로 작업할 일이 있으면 git pull real-blog(remote 별명) 명령을 통해 원본 저장소와 동기화를 진행하고 3~7을 반복한다.

결론

  • 시행착오는 있었지만 위와 같은 방법으로 첫 PR을 생성하고 무사히 Merge 까지 되었다! (감격)
  • 당장 내가 PR을 해야하는 상황에서 했던 작업들을 정리한 것이라,
    각 절차의 심오한 의미에 대해서는 다루지 못했다.
  • 더 자세한 내용은 pro git book 에서 확인할 수 있다.
  • 나처럼 급하게 Pull Request 해야하는 분들에게 도움이 되었으면 좋겠다.

170703-0709_TIL

|

7월 9일 (일)

  • 패캠 인스타그램 연습 repository 커밋 로그를 하나씩 따라가면서, 다른 사람이 작성한 코드를 읽고 Django를 공부했다.
    • 내가 작성한 인스타그램 코드와 다르게 구현한 부분이 많아서 도움이 될 것 같다.
    • 프로젝트 레이아웃 방식부터 달랐다. Two Scoops of Django 3장에 나온 것처럼 구성되어 있었다.
      • settings.py 파일은 configuration_root (config) 폴더 안에 위치
      • 프로젝트 레벨에서 공통으로 사용하는 static, template 폴더는 django_project_root 폴더 내에 위치 (manage.py 파일이 위치한 곳)
  • Pycharm을 사용하기 시작했다. 그동안 사용하던 atom과는 단축키가 많이 달라서 불편하지만, python 개발에는 pycharm이 많이 사용되는 것 같아 일부러라도 익숙해지려고 한다. 가장 마음에 드는 기능은 jump to source 기능이다. django 모듈 import시에 해당 소스코드가 궁금하면 바로 확인해 볼 수 있었어서 좋다. 그동안 Django repository에 들어가서 직접 하나씩 찾아봤던 것에 비교하면 훨씬 편리한 것 같다.

7월 8일 (토)


7월 7일 (금)

  • AWS Elastic Beanstalk를 활용하여 배포를 연습해보았다.
    • 웹 콘솔에 프로젝트 zip 파일을 업로드하여 배포를 진행하고, 수정 사항을 반영하여 재배포를 진행했다.
    • CLI 인터페이스 환경에서 Elastic Beanstalk 배포를 진행했다.

7월 6일 (목)

  • Two Scoops of Django 1~3장을 읽었다.
    • 1장 코딩스타일
    • 2장 최적화된 장고 환경 꾸미기
    • 3장 어떻게 장고 프로젝트를 구성할 것인가
  • 3장의 프로젝트 레이아웃 부분은 내가 그동안 사용했던 방법과는 다른 부분이 있어서 신기했다. 현업 개발자 분들꼐 물어보니 책에 있는 내용처럼 사용 하신다고 한다. 나도 새로운 연습 프로젝트를 진행할 때는 새로운 레아아웃을 적용해서 진행해 봐야겠다.
    • settings.py 파일이 포함된 폴더명을 config로 지정 (이러려면 django-admin startproject config로 항상 프로젝트를 시작해야겠다.)
    • 프로젝트 레벨에서 공통을 사용하는 template, static 파일은 project root 레벨 폴더에 저장 (manage.py 파일이 위치하는 곳)
  • flake8 을 활용해서 그동안 작성한 파이썬 파일의 코드스타일을 검사했는데 결과가 처첨했다. pycharm을 사용하면 자동으로 검사해주도록 설정 가능하다고 하다. 찾아보니 atom에도 flake8 패키지가 있었다. 앞으로 코드 스타일에도 좀 더 신경을 쓰면서 코드를 작성해야겠다는 생각을 했다.
  • 8퍼센트 두숟갈 스터디에 참여하고 후기를 작성했다.
    • Pull Request는 처음이라 방법을 찾아보고 시도해보는데 시행착오를 조금 겪었다.
    • 가장 많은 도움을 받은 자료 (당장 PR을 해야하는 상황에서 이해하기 쉽고 간단한 설명이었다.)

7월 5일 (수)

  • 연습 프로젝트를 진행하며 Django를 학습했다. (repository)
    • 배포 관련 강의를 들었다.
    • requirements.txt, settings.py 를 실행환경(개발/배포)에 따라서 분리하였다.
  • 예전에 풀었던 알고리즘 문제들을 다시 풀었다. 2달 전에 풀었고 이번이 벌써 3번째 반복해서 푸는 문제인데, 비교적 간단하지만 개선방법에 대해서 아직 고민할 여지가 있다고 느꼈다. 이걸로 연습이 좀 되면 예전에 풀었던 codility 문제들을 다시 풀어봐야겠다.
  • 장고를 사용하면서 계속 느끼는 점은 파이썬에 대한 이해도를 높이면 장고에 대해서도 더 잘 이해할 수 있겠다는 점이다. 프레임워크 사용에 익숙해져서 파이썬 언어에 대한 감을 잃지 않도록 꾸준히 공부해야겠다.

7월 4일 (화)

  • 연습 프로젝트를 진행하며 Django를 학습했다. (repository)
    • django-allauth 라이브러리를 활용하여 Facebook 로그인 기능을 구현했다.
    • 회원가입 시에 User 모델과 1:1 관계인 Profile 모델의 인스턴스를 함께 생성하도록 하는 부분에서 시간이 많이 걸렸다.
    • 해당 이슈는 DefaultSocialAccountAdapter 을 상속받은 class를 정의하고 save_user 메소드를 오버라이딩 하여 해결하였다.
    • PostgreSQL을 적용하였다.
    • Tag 검색결과가 없는 경우, 인기 Tag 리스트를 함께 노출하는 기능을 추가하였다.
      • Tag 모델과 M:N 관계인 Post의 갯수를 기준으로 Tag 리스트를 가져와야하는 이슈가 있었다.
      • 이는 Queryset의 annotate() 절을 활용하여 해결하였다.
      • 관련하여 Aggregation 공식 문서를 읽었다. Django ORM을 잘 활용할 수 있었으면 좋겠다.

7월 3일 (월)

  • 연습 프로젝트를 진행하며 Django를 학습했다. (repository)
    • 배포를 하고나니 오류가 발생해도 자세한 로그를 확인할 수 없는 문제가 발생했다. (개발중에는 터미널을 통해서 오류 로그를 확인할 수 있었다.)
    • sentry 라는 서비스를 활용하여 해당 문제를 해결하였다. (이제 내가 모르는 사이에 실서버에서 오류가 발생해도 E-mail로 로그를 받아볼 수 있다!)
    • Azure를 활용하여 다시 한번 배포 연습을 진행하였다.
    • 소소한 각종 버그를 수정했다.
  • 배포까지 진행하고 나니 앞으로 어떻게 공부할까에 대한 고민이 생겼다. 인스타그램 말고 또 새로운 서비스를 유사한 방식으로 만들지, 아니면 책과 강의를 통해서 지식을 추가해 나갈지 등 무엇이 더 좋은 방법일지에 대한 고민이다.
    새로운 프로젝트를 진행하는 것도 좋겠지만, 지금 만든 인스타그램 프로젝트를 계속 개선해 나가는 방식으로 Django를 학습하려고 한다. 생각해보면 아직 개선의 여지가 많아서 한동안은 이걸로도 충분히 연습을 할 수 있을 것 같다.
  • 전부터 읽고 싶었던 Two Scoops of Django를 주문했다.