PyOWM를 이용하여 현재기온 받아오기

현재 간단하게 운영하고 있는 서비스에 현재기온을 알 수 있는 기능을 추가하고 싶어 api를 찾던 중 openweathermap를 발견했다. api doc을 읽으면서 그냥 사용해도 무방할 것 같았지만 왠지 래핑된 파이썬 패키지가 있을거 같아서 찾아보았더니 역시나.. 있었다. official doc은 물론 깃허브에 설명이 너무 잘 되어있어서 사용하는 데에는 크게 무리 없었지만 처음으로 오픈소스를 찾아본 기념으로 정리하려고 한다.

PyOWM

일단 OWM이 뭔지 알아야 할 것 같다. OWM이란? OpenWeatherMap은 현재날씨 뿐만아니라 예보 풍향, 기온 등을 알려주는 온라인 서비스이다. 총 다섯가지 티어로 나누어져있고 프리티어도 존재하기 때문에 무료로 사용할 수 있다. 공식 페이지를 통해 각 티어간의 차이를 알 수 있을 것이다.

나의 경우에는 현재기온만을 필요로 했기때문에 프리티어면 충분했다. owm의 장점으로는 api doc이 설명이 자세하다는 것과 사용하는 것도 편리하다는 것이다. 하지만 더 나아가서 파이썬 사용자들을 위해 누군가가 더 편리하게 만들어서 PyOWM이라는 파이썬 패키지를 제공하고 있는 것이다. 파이썬2의 2.7과 3.2버전 이상을 지원하고 있으며 웹 프레임워크 Django1.10이상의 모델에도 사용할 수 있다.

설치

  1. pip를 이용한다
    1
    pip install pyowm
    매우 편리하다. 쉽다.

사용법

일단 owm이 제공하는 api를 이용하기 위해서는 공식 페이지로 들어가 api key를 받아야한다.
물론 영어로 적혀있지만 간단하기 때문에 쉽게 할 수 있을 것이다.

주의할 점
서비스에 가입하고 api key를 받았더라도 바로 사용할 수 없다. 공식 안내에 따르면 free tier 계정과 startup tier 계정은 받은 api key를 활성화하는 데에 10분이 소요된다고 하니 발급받고 10분 뒤에 사용하도록 한다.

설치한 패키지를 임포트 하는것으로 시작하면 된다.

1
2
3
# 아래 어느것으로 해도 무방하다
# import pyowm
from pyowm import OWM

임포트 한 뒤 OWM 객체를 생성해야 한다.

1
owm = OWM(API_KEY)

어떠한 종류의 api를 구독하는지 명시하지 않았다면 free tier로 간주한다. 유료api를 구독하고 있다면 아래와 같이 하자.

1
owm = OWM(API_KEY, subscription_type='pro') # pro tier를 구독하는 예시

사용하려는 owm api 버전도 지정할 수 있다. 만약 명시하지 않으면 가장 최신버전의 api를 사용한다.

1
owm = OWM(API_KEY, version='2.5') # owm api version == 2.5

지금까지 했다면 최소한의 준비는 됐다. 도시이름을 통해 해당도시의 날씨상황을 가져와보자. 현재 날씨를 받아오기 위해 검색하는 것은 매우 간단하다. 날씨를 알고싶은 지역의 이름을 OWM 객체에 전달해주면 된다. “지명”으로 해도 좋고 “도시ID”와 “위도/경도”로도 검색 할 수 있다.

1
observation = owm.weather_at_place('Seoul,KR')

입력한 지역과 매칭되는 날씨 정보를 포함한 observation 객체가 리턴된다. observation 객체는 두 가지 또다른 객체를 포함하고 있다. 날씨와 관련된 데이터를 포함한 Weather 객체와 지역에 대한 데이터를 가진 Location 객체 이다.

아래와 같이 하면 Weather 객체를 가져올 수 있다.

1
2
seoul_weather = observation.get_weather()
print(seoul_weather) # <Weather - reference time=2013-12-18 09:20, status=Clouds> 를 출력한다.

더 디테일한 날씨정보를 가져오기 위해 아래 예시코드를 참고하자 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
seoul_weather.get_wind()                  # {'speed': 4.6, 'deg': 330}
seoul_weather.get_humidity() # 87
seoul_weather.get_rain() # Get rain volume
seoul_weather.get_clouds() # Get cloud coverage
seoul_weather.get_snow() # Get snow volume
seoul_weather.get_wind() # Get wind degree and speed
seoul_weather.get_pressure() # 기압

seoul_weather.get_temperature() # 온도(캘빈온도)
seoul_weather.get_temperature('celsius') # {'temp_max': 10.5, 'temp': 9.7, 'temp_min': 9.0}

seoul_weather.get_status() # Get weather short status ex) 'Clouds'
seoul_weather.get_detailed_status() # ex) 'Broken clouds'
seoul_weather.get_weather_code() # owm에서 사용하는 상태코드 - ex) 803
seoul_weather.get_sunrise_time() # 일출시각 ex) 1377862896L
seoul_weather.get_sunset_time('iso') # 일몰시각(iso시간) ex) '2013-08-30 20:07:57+00'

위에서 이미 얘기했듯이 observation 객체는 Location 객체도 가지고 있다. 아래는 Location 객체를 가져오는 코드이다.

1
2
location_seoul = observation.get_location()
print(location_seoul)

Location 객체도 다양한 속성이 있다.

1
2
3
4
location_seoul.get_name()    # 'Seoul'
location_seoul.get_lon() # 경도
location_seoul.get_lat() # 위도
location_seoul.get_ID() # 도시ID

실시간 날씨현황뿐만 아니라 예보기능도 있지만 아직 사용해보지 않은 관계로 추후에 정리해보자!!


[참고]
https://github.com/csparpa/pyowm
https://github.com/csparpa/pyowm/blob/master/pyowm/docs/usage-examples.md
https://openweathermap.org/current

Share

리눅스 크론탭 기본(Basic of crontab)

Crontab !?

유닉스 계열의 시간기반 잡 스케줄러이다. 서버를 운영하다 보면 관리의 편의성을 위해 쉘 스크립트를 일정한 주기로 실행하는 등의 고정된 작업을 필요로할때가 있다. 주로 로그를 남기기 위해 사용하는 듯 싶고 나의 경우 운영하고 있는 서비스때문에 주기적으로 크롤링을 해야돼서 크론탭을 이용하고있다.

작업을 고정된 시간, 날짜, 간격에 주기적으로 실행할 수 있도록 스케줄링하기 위해 사용한다
각각의 사용자들은 개인별로 자신들만의 crontab을 가질 수 있으며 관리자가 직접 작업들을 공통으로 지정하기도 한다.

파일 위치

/etc/crontab

주로 시스템 관련 작업들을 등록할때 사용하는 경로이다.

/var/spool/cron

시스템 개별사용자들이 등록해놓은 crontab이 위치해있는 경로이다. 일반적으로 root계정용 하나와 각 계정당 1개의 파일을 가진다.

사용법

기본 형태와 예시를 살펴보자.

1
2
3
4
5
6
7
8
9
10
# crontab -e

# ┌───────────── min (0 - 59)
# │ ┌────────────── hour (0 - 23)
# │ │ ┌─────────────── day of month (1 - 31)
# │ │ │ ┌──────────────── month (1 - 12)
# │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute

예시

1
2
3
4
5
# 매일 20시 (오후 8시)에 export_dump.sh라는 쉘 프로그램을 실행
0 20 * * * /home/oracle/scripts/export_dump.sh

# 매주 일요일 0시 1분에 for_crawling.sh 쉘 프로그램을 실행
0 1 * * 0 /home/test_user/scripts/for_crawling.sh

관련명령어

  • 예약작업 생성 및 수정

    1
    crontab -e
  • 예약된 작업 삭제

    1
    crontab -r
  • crontab 작업 리스트 출력

    1
    crontab -l
  • 시스템 사용자의 crontab 편집

    1
    crontab -u <user_name>

    root 사용자는 개인 사용자의 crontab을 수정하거나 삭제할 수 있다.

  • 크론탭 재시작

    1
    service crond restart

    크론탭을 생성하거나 수정했다면 혹시모르니 꼭 재시작을 해주자!!

간단한 쉘 스크립트를 주기적으로 실행하기위해 이용했던 crontab은 큰 무리없이 지금까지 사용해왔다. 하지만 코드를 조금 변경하면서 파이썬 스크립트를 추가하면서 문제가 발생했고 해결과정을 정리하고자 한다.

crontab 사용시 주의점!!

crontab의 규칙에 맞게 설정을 했음에도 불구하고 동작하는 않은 경우가 발생했다. 인터넷을 찾아보니 두세가지 정도의 이유가 있었다.

1. 환경변수

크론탭은 네 가지 환경변수를 가지고 있다. => SHELL / PATH / MAILTO / HOME

  • SHELL
    등록된 작업을 실행시킨 쉘을 지정한다(크론탭은 실행시에 별도로 쉘을 띄운다). 지정하지 않을시 기본값으로 /bin/sh로 지정된다.

  • PATH
    쉘을 별도로 띄워서 실행하는 특성때문에, 쉘에서 프로그램을 찾기위한 PATH도 별도로 지정해줄 필요가 있다. 로그인해서 쉘을 실행시키는 것이 아니기 때문에 PATH변수를 이용할 수 없기 때문이다.

  • MATILTO
    (크게 중요하진 않은것 같다)크론이 수행한 결과를 메일로 보내준다. 기본값으로 작업을 실행한 주체에게 전송하게 되어있다.

  • HOME
    crontab의 home 디렉토리(:12)경로를 설정한다. 기본적으로는 crontab의 실행유저의 홈디렉토리로 /etc/passwd에 설정된 경로를 따른다.

예시

1
2
3
4
5
6
# crontab -e

SHELL=/usr/bin/zsh
PATH=/sbin:/bin:/usr/sbin:/usr/bin

* * * * * sample.sh

매분마다 sample.sh을 실행하며 프로그램이 작동할 쉘과 경로를 지정해주었다.

2. 권한문제

크론탭을 설정하는 방법에는 crontab -e 명령어를 통한 작성과 직접 /etc/crontab을 편집하는 두 가지 방법이 있다. 두 번째 방법처럼 vi /etc/crontab을 통해 직접 수정을 했을 경우 root 권한 명령을 실행하려면 root권한을 명시해 주어야 한다.

1
2
3
4
5
# crontab -e
* * * * * example.sh

# vi /etc/crontab
* * * * * root example.sh

두 번째 처럼 root 권한을 명시해야 한다!!

3. 절대경로 / 상대경로

절대경로로 작성하는 것을 추천한다 @.@

4. 최소 반복 시간

크론탭의 최소 반복시간은 1분이다. 명심하자.


내가 겪은 문제

파이썬으로 웹 페이지를 크롤링하는 코드를 작성하였고 간단한 설명을 위해 한글로 주석을 달아놓았다. 또한 virtualenv를 사용하고 있었기 때문에 크론이 돌아가는 쉘이 가상환경 경로를 모르는 듯 했다.

약 두 세시간 삽질끝에 이유를 위와 같이 알 수 있었고 정석대로 해결을 못해서 한글주석을 지웠다… 그리고 path설정을 하니 정상작동했다.

  • path 설정
    파이썬 가상환경을 사용하고 있다면, 패키지들과 어떤 파이썬으로 실행되는지 path로 설정해줄 필요가 있다고 한다. 그래서 구동되는 파이썬의 path를 보기위해 다음과 같이 했다.

    1
    2
    3
    4
    python3 # 파이썬 실행

    >>> import sys # sys모듈 임포트
    >>> sys.path # path 출력(리스트 형태)

    sys.path를 실행해서 출력된 path값들을 crontab의 PATH에 추가해 주었다.

  • 가상환경 경로 입력
    스크립트를 실행하는 명령을 입력하기 전에 파이썬 가상환경을 활성화하는 명령을 입력해 보았다.

    1
    2
    3
    # crontab -e

    * * * * * source /path/to/virtualenv/bin/activate && python3 /path/to/file/example.py

    위와 같이 했더니 가상환경을 정상적으로 활성화하고 파이썬 스크립트를 실행했다.

  • 파이썬 경로 입력
    파이썬 인터프리터에게 어떤 파이썬을 사용할 지 알려주는 것이다.

    1
    #!/home/my/virtualenv/bin/python

    스크립트 맨위에 주석을 달아준다.

  • SHELL 경로 지정
    주로 zsh을 설치하여 사용하고 있기 때문에 경로를 바꿔보았다

    1
    2
    # crontab -e
    SHELL=/usr/bin/zsh

    이렇게 했더니 웬걸… python을 찾을 수 없다고 한다. 그래서 sys.path을 통해 파이썬 경로를 알아내어 PATH설정도 해주었는데 그래도 작동하지 않았다..

  • 한글주석 삭제
    한글주석을 지워보았더니 non-ascii 문제가 사라졌다. 그 다음에 path설정을 해주었더니 올바르게 동작…


추가 팁?

귀차니즘으로 인해 아직 해보지는 않았지만 실행할 명령어를 크론탭에서 바로 작성하는 것이 아니라 따로 .sh을 만들고 크론에서 그 .sh을 실행하는 방법이다. 왜 이렇게하면 잘 작동하는 가에 대한 이유를 찾아보려고 했으나 아직까진 발견하지 못했다.

1
2
3
4
5
# vi example.sh
python /path/to/test.py

# crontab -e
* * * * * /path/example.sh

바로 파이썬 스크립트를 입력하지 말고 한번 .sh로 감싼다음에 그 .sh 스크립트를 실행한다는 것이다. 꼭 한번 시도해보자.

Share

hexo와 Github Page를 이용한 블로그

지난 17년에는 블로그가 아닌 Github를 통해 간단하게 마크다운 파일로만 그날그날 공부해왔던 것들을 정리했었다.
당시에도 지킬(Jekyll)을 이용하여 블로그를 할지 간단한게 할지 고민했었는데 올해부터는 hexo와 github page를 이용하여 공부하는 것들을 정리해보려고 한다.

github page와 자주사용되는 정적사이트 생성기로는 지킬(Jekyll)이 있다. Jekyll은 github page에서 기본적으로 지원을 하고 있으며 ruby로 되어 있다고 한다. 그리고 다른 정적사이트 생성기로는 hexo가 있다. hexo는 요즘 frontend와 backend을 막론하고 자주 사용하는 javascript로 되어있으며 jekyll보다 이쁜 테마가 많다고 알려져있다. 예전에 jekyll을 이용하여 잠깐 블로깅을 해본적이 있는데, 이번에는 hexo를 이용하여 해보기로 하며 일회성 이벤트가 아니라 꾸준히 할 수 있기를 기대한다.

hexo를 설치하기 이전에 필요한 준비물이 있다.

  1. node
  2. git

따로 인스톨패키지를 지원하는 것이 아니기 때문에 npm(Node.js package manager)을 이용하여 설치해야만 한다.

설치

  1. hexo-cli 설치하기

    1
    npm i hexo-cli -g

    위 와 같이 입력하면 전역적으로(global) hexo가 설치된다.

  2. 블로그 생성

    1
    2
    3
    hexo init <blog_name> # 블로그 이름을 적어준다
    cd <blog_name>
    npm install # 약자는 hexo i

    init을 하게되면 지정한 이름으로 블로그 폴더가 생성되고 내부에는 블로그에 필요한 파일들이 마구마구 생성된다.
    cd를 이용해 해당 디렉토리에 들어가고 패키지를 인스톨해주면 준비는 끝이다.

  3. 로컬서버 실행

    1
    hexo server # 약자는 hexo s

    배포하기 전에 로컬서버를 통해서 먼저 확인한다. 기본적인 주소는 http://localhost:4000 이다.
    source/_posts 폴더 내부의 md파일이 보여지게 되며 최초생성시에는 hello world와 hexo를 소개하는 페이지가 보일 것이다.

설정하기

hexo의 전반적인 설정은 _config.yml에서 할 수 있다. 꽤나 직관적인 영어로 작성되어 있기 때문에 설정하는 데에 큰 어려움은 없다. 짧막한 예시는 아래의 코드와 같다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Writing
new_post_name: :title.md # File name of new posts
default_layout: draft # layout 기본설정 -> hexo new [layout] 생략 시 draft 모드가 기본값이다
titlecase: false # Transform title into titlecase
external_link: true # Open external links in new tab
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: true
line_number: true
auto_detect: false
tab_replace:

글 작성

글을 작성하는 방법에 자주 사용되는 것은 초고(draft)를 작성하고 발행(publish)하는 것이다.

초고를 작성하기 위해 source/_drafts 폴더를 그리고 발행을 위해 source/_posts 폴더를 만드는 방법도 있지만, 아래와 같은 명령어를 통해 폴더와 파일을 자동으로 생성하는 것이 훨씬 간편하다.

1
hexo new [layout] <document_name>

설정파일의 default_layout을 통해 기본 레이아웃을 설정할 수 있다.

1
2
# _config.yml
default_layout: draft

나의 경우 발행할 글을 바로 작성하는 것보다 초고를 쓰고 읽어본 뒤 발행하는 편이기 때문에 default_layout을 draft로 주었다. 만약 “settings-hexo”라는 이름으로 draft를 생성하고 싶으면 다음과 같이 하면 된다.

1
2
3
hexo new draft "settings-hexo"
# 또는
hexo new "settings-hexo"

source/_drafts 폴더에 settings-hexo.md 라는 마크다운 파일이 생성되었을 것이다. 게시글을 작성했으면 게시글을 포스팅하기 위해 발행할 차례이다. 발행(publish)하는 명령은 다음과 같이 하면 된다.

1
hexo publish <file_name>

source/_posts 폴더 내에 settings-hexo.md가 생겼을 것이고 로컬에서 확인하기 위해 hexo s을 실행해 본다.

다음으로 실제 github page로 배포할 차례이다. 배포 이전에 설정파일에 해주어야할 작업이 있다.

  1. 설정파일 수정
  2. 패키지 설치

설정파일 수정

1
2
3
4
5
6
7
# _config.yml

# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: <address>

설정파일의 맨 아래를 보면 위의 코드와 같은 것이 있다. github page를 이용하기 때문에 type에는 git을 적어주고 repo에는 github page 주소를 적어주어야 한다.

패키지 설치

1
npm install hexo-deployer-git --save

설정파일도 수정하고 패키지도 설치했다면 준비는 완료된 것이다. 배포를 해보자!

배포하기

1
hexo deploy -g

매우 간단하다. 이전에 입력해놓은 주소로 손쉽게 배포할 수 있다. 깃허브에 올라가는 파일은 source파일이 아닌 public 폴더가 올라가게 되며, 문서의 변경내용을 관리하고 싶다면 추가적으로 해야할 일이 있다.

마크다운파일의 변경내용 관리하기

새로운 브랜치를 생성해야 한다. 실제로 블로그에 보이는 파일은 master 브랜치를 통해 배포하고 파일의 변경내용은 새로만든 브랜치에서 하는 것이다. gh-pages라는 브랜치를 새로 생성하자.

1
git checkout -b gh-pages

위의 명령은 gh-pages라는 브랜치를 생성하고 바로 브랜치를 변경해준다. gh-pages 브랜치에 푸시를 하고 hexo deploy 명령어를 통해 배포를 하면 문서파일 관리와 동시에 블로그로 배포할 수 있게 된다!!

Share