nignx unit 멀티쓰레드 설정

nginx unit 은 1.21.0 버전부터 python 멀티 쓰레드 설정을 할수 있게 되었다.

멀티 쓰레드 설정을 위해서 Appliacation 설정에 threads 키를 추가 하고 원하는 숫자(정수) 를 지정하면 된다.

    "applications": {
        "my_app": {
            "type": "python",
            "path": "/path/to/my/app",
            "module": "wsgi",
            "threads": 4
        }
    }

참고 문서 : https://unit.nginx.org/configuration/#python

nginx unit 는 쓰레드 기반의 아키텍처를 사용하기 때문에 python GIL(글로벌 인터프리터 락)의 영향을 받지 않는다고 한다. https://github.com/nginx/unit/issues/33

Pillow으로 원하는 사이즈로 이미지 만들기(with Flask)

원하는 사이즈의 목업이미지(?)를 만들어는 기능?이 필요했다.

http(s)://Address/{가로}x{세로}” 형식으로 호출하면 아래와 같이 JPG 이미지를 웹으로 출력해주는 형식이다. ex) http(s)://Address/100×100

https(s):/Address/300×200
https(s):/Address/200×200

급하게 만들어서 예외 처리 따위는 되어 있지 않은 코드이지만, 기록해보기로 했다.

import flask
import io
from PIL import Image, ImageDraw, ImageFont

app = flask.current_app


@app.route('/<size>')
def mockup(size):
    # URL로 입력된 사이즈 정보를 소문자로 변경
    size = size.lower()

    if 'x' in size:
        if size.count('x') != 1:
            return create_image()
        elif size.count('x') > 1:
            w = int(size)
            return create_image(w)
        else:
            w, h = int(size.split('x')[0]), int(size.split('x')[1])
            return create_image(w, h)


def create_image(w=200, h=None):
    image_color = 'gray'
    drawline_color = 'white'
    # 높이가 없으면 세로와 같은 크기로 선언
    if h is None:
        h = w
    # 목업 기본 이미지 생성
    box = Image.new(
        mode='RGB',
        size=(int(w), int(h)),
        color=image_color
    )
    draw = ImageDraw.Draw(box)
    # 바운딩 박스, 라인 의 시작점
    margin = min(int(w/10), int(h/10)])
    # 바운딩 박스 그리기
    draw.rectangle(
        (
            # x 시작 좌표
            int(margin),
            # y 시작 좌표
            int(margin),
            # x 끝 좌표
            int(w - margin),
            # y 끝 좌표
            int(h - margin)
        ), outline = drawline_color,
        width = 1
    )
    # \ 표시를 위한 대각선 그리기
    draw.line(
        (
            # x 시작 좌표
            int(margin),
            # y 시작 좌표
            int(margin),
            # x 끝 좌표
            int(w - margin),
            # b 끝 좌표
            int(h - margin)
        ),
        fill = drawline_color, width = 1
    )
    # / 표시를 위한 대각선 그리기
    draw.line(
        (
            # x 시작 좌표
            int(w - margin),
            # y 시작 좌표
            int(margin),
            # x 끝 좌표
            int(margin),
            # y 끝 좌표
            int(h - margin)
        ),
    fill = drawline_color, width = 1
    )
    # 생성한 이미지를 메모리
    byteio = io.BytesIO()
    box.save(byteio, format='JPEGE', optimize=True, qualty=95)
    boxRes = byteio.getvalue()
    byteio.close()
    return flask.Response(boxRes, mimetype='image/jpg')

공공데이터 날씨

data.go.kr 가입 및 API 사용신청 다른분들 글도 많으니 생략.

오픈API 명 : (신)동네예보정보조회서비스

먼저 초단기실황정보(현재날씨정보) 으로 테스트 코드 작성
정리가 안되어 있어도 이해부탁드립니다.

URI정보

# # 초단기 실황
# ForecastGrib
# # 초단기 예보
# ForecastTimeData
# # 동네 예보
# ForecastSpaceData

테스트 코드 (초단기실황)

import requests, json
import datetime

## data.go.kr
api_host = 'http://newsky2.kma.go.kr/service/SecndSrtpdFrcstInfoService2'
api_key = '발급받은  인증키'

## 좌표(제공되는 엑셀에서 확인 가능)
nx = 60; ny = 127

def nowdate():
    return {'basetimedate':datetime.datetime.now().strftime('%Y%m%d%H') + '00',
            'base_date':datetime.datetime.now().strftime('%Y%m%d'),
            'base_time':datetime.datetime.now().strftime('%H') + '00' }

def ForecastReq(ftype, uri):
    ver_data = verchck(ftype)
    url = api_host + uri
    data = {'serviceKey':api_key, 
            'base_date':nowdate().get('base_date'),
            'base_time':nowdate().get('base_time'),
            'nx':nx, 'ny':ny,
            'numOfRows':999,
            '_type':'json'}
    res = requests.get(url, params=data)
    res_data = res.json()
    for t in res_data['response']['body']['items']['item']:
        print(t['baseDate'], 
                t['baseTime'], 
                t['category'], 
                t['obsrValue'])

def Forecast(ftype):
    if ftype == "grib":
        uri = '/ForecastGrib'
        ForecastReq('ODAM', uri)
    else:
        pass

print(Forecast('grib'))

mod_wsgi virtualenv

apache mod_wsgi 에서 virtualenv 을(를) 사용하기 위한 .wsgi Code

참고 url : http://flask.pocoo.org/docs/0.12/deploying/mod_wsgi/#working-with-virtual-environments


# python 2.x
activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
# python 3
activate_this = '/path/to/env/bin/activate_this.py'
with open(activate_this) as file_:
    exec(file_.read(), dict(__file__=activate_this))