업무로 API 서비스를 만들 때,

최근에는 Python을 이용하는 것이 편하다보니 주로 FastAPI를 이용하곤 한다.

 

그러다가 2달 전쯤 새로운 웹-프레임워크(Web-Framework) 소식을 듣게 되었다.

- https://news.hada.io/topic?id=16091

GeekNews

 

새로운 프레임워크임에도 불구하고 의외로(?) 반응이 꽤 괜찮다.

 

사이트도 산뜻하게 디자인되어 있다.

- https://fastht.ml/

FastHTML

 

FastHTML 스스로 만든 페이지이겠지?! ㅋㅋㅋ

어!? 나처럼 생각하는 사람이 많아서인지..... 그렇다고 한다!!!

FastHTML

 

5천개가 넘는 Star와 200건이 넘는 Fork를 자랑하는 프로젝트이다.

- https://github.com/AnswerDotAI/fasthtml

GitHub

 

GeekNews에서 괜히 경쟁력이 있다는 말을 한 것이 아니다.

의외로 많은 것들이 제공/지원되고 있다.

- https://gallery.fastht.ml/

FastHTML Gallery

 

1. Installation

설치 과정은 Python 패키지답게 정말 심플하다.

- https://github.com/AnswerDotAI/fasthtml?tab=readme-ov-file#installation

Installation

 

그래서, Python 가상환경 만들고 pip 설치를 진행했는데...

Error

 

얼라료?!

에러!? 이런!!

 

패키지를 아예 찾지 못하는 것이 이상해서...

혹시나 하고 Python 버전을 올려봤다.

Python 3.10.9

 

이런, Python 3.8.x 버전은 지원하지 않는 것으로 보인다.

짧게 살펴봤지만, Document 어디에서도 Python 버전 제약에 대한 설명이 없었는데....

 

 

2. Usage

준비가 되었으니 빨리 Hello를 외쳐보자.

 

main.py

 

실행은 그냥 하면 된다.

Execute

 

실행 결과에서 안내해주는 주소를 참고해서

웹-브라우저로 결과를 확인해보자.

Chrome

 

소스코드를 확인해보면 다음과 같다.

View Source

 

그런데, 웹-브라우저에서 "Hello World!" 부분을 클릭해도 아무런 일이 발생하지 않는다.

(내부적으로는 404 에러가 발생하겠지만 ^^)

 

소스코드에 8-9 라인을 다음과 같이 추가하고 Save를 해보자.

update

 

그러면, 다음과 같이 파일이 변경된 것을 감지하고 자동으로 Reloading을 한다!!!

브라보 !!!

Reloading

 

웹-브라우저에서 "Hello World!" 부분을 클릭하면

다음과 같이 다른 내용이 출력된다.

Click

 

호오~ 정말 심플하네!!!

 

 

3. Example

여러 예시들을 참고하면 도움이 될 것이다.

- https://github.com/AnswerDotAI/fasthtml-example

GitHub

 

다양한 App 예시들을 볼 수 있다.

Exaples

 

음... 과연 앞으로도 지속적으로 성장을 할 것인지

관심있게 지켜봐야겠다.

반응형

요즘 저녁에 러닝을 하기 위해 격일로 조금 일찍 퇴근을 하는데.

비 예보가 있다는 것을 미처 인지하지 못해서 일도 못하고 러닝도 못하는 그런 사태가...

 

이런 핑계(?)로 갑자기 날씨 정보를 API로 얻어오는 것을 한 번 해보고 싶어졌다.

갑자기? 갑자기!

 

날씨 정보를 어디에서 얻어와야 할까!?

당연히 기상청 !!!

https://www.data.go.kr/data/15084084/openapi.do

 

무료인데다가 심지어 샘플 코드까지 제공해주고 있다.

샘플코드 - Python

 

사용을 위해서는 오른쪽 상단에 위치한 "활용신청"을 클릭하면 된다.

활용신청

 

적절한 내용으로 작성하여 신청하면, 즉시 승인이 된다.

신청 결과

 

상세 내용을 보면 다음과 같이 인증키 정보를 확인할 수 있다.

상세 내용

 

이제 잘 동작하는지 검증을 해보자.

 

1. Python 환경을 맞춰야 한다.

- requests 모듈을 사용하기 위해 설치가 필요하다.

 

2. 지역 위경도값을 확인하자.

- 공공데이터 포털에서 제공하는 참고문서를 다운로드 받아야 한다.

  . 기상청41_단기예보 조회서비스_오픈API활용가이드_(240715).zip

 

- 압축을 풀면 문서 파일이 2개 나오는데, 위경도 정보가 있는 엑셀 파일을 확인하면 된다.

 

- 내가 확인하고자 하는 지역의 X, Y 값을 확인하면 된다.

 

3. 코드 작성

- 다음과 같이 간단한 코드를 작성해보자.

  . API 키는 일반 인증키(Decoding )으로 사용했다.

 

- 실행 결과는 다음과 같이 나온다.

 

 

각 값들의 의미나 활용 관련하여서는 다운로드 받은 참고 자료 中 워드 파일을 살펴보면 된다.

sample

 

일단 기본적인 확인을 해봤으니,

아침에 자동으로 알람 오도록 만들어봐야겠다! ^^

반응형

[문제] Python으로 "Hello world!"를 가장 간단하게 출력하는 방법은?

[정답] 다음과 같은 방법을 생각해낸 사람은 파이썬 고수!!!

Hello world!

 

 

[문제] "python -m antigravity"를 실행하면 어떤 결과가 나올까?

[정답] 'antigravity'의 뜻은 반중력이며, 모든 것을 밀어내는 성질을 의미한다.

antigravity

 

응?! 아무것도 출력되는 것 없이 그냥 끝난다. 그런데... 갑자기 웹 브라우져가 실행되는데...

https://xkcd.com/353/

 

설마 XKCD를 처음보는 분이 계실리가.....?!

 

계실 수도 있으니 ^^ 설명을 해보자면,

 

랜들 먼로(Randall Munroe)가 일주일에 3번 연재하는 Web-Comic으로

공대 개그, Geek스러운 개그가 주된 유머 코드이다.

 

XKCD

 

웹사이트 메뉴 中 WHAT IF? 컨텐츠를 기반으로 책도 출간했다. 번역본도 있다.

아주 위험한 과학책

 

재밌지 않나!?

python CLI 가지고 별 이상한 일이 다 생긴다 ^^

 

 

[문제] python 으로 그래픽 UI를 어떻게 표현할 수 있는지 쉽게 설명할 수 있는 방법은?

[정답] python 에는 오랜 역사(?)를 갖고 있는 거북이(turtle) 모듈이 있다.

turtle demo

 

응!? turtle demo도 지원해준다고!?

turtle example

 

신기한(?) 윈도우가 하나 실행된다.

examples

 

하나 골라 보자.

clock example

 

turtle 모듈을 이용한 예제 코드도 볼 수 있고,

윈도우 하단의 "START"를 클릭하면 실행 결과도 확인할 수 있다.

 

"python -m turtledemo" 실행 하나만으로 이런 어플이 뜬다니,

대체 이런 것들은 어디에 숨어있었던 것인지...

 

그동안 Python을 몇 년 동안 만져왔는데, 지금까지 이런 것들을 전혀 몰랐다니!

 

 

생각보다 재미있어서 이런 것들 찾아서 몇 번 더 포스팅해보겠다 ^^

 

 

반응형

라이선스 이슈를 피해서 Anaconda 사용하는 방법에 대해서 이미 포스팅을 했었다.

  - 회사에서 Anaconda 사용하기 (Miniconda + conda-forge)

 

 

그런데, Ubuntu 운영체제를 기준으로 작성했다보니

Windows 환경을 사용하는 분들의 불만 아닌 불만이 있는 것 같아서... Windows 버전도 추가로 작성해본다.

 

① Miniconda 설치

② conda-forge 등록

③ conda 가상환경 생성

④ Jupyter Notebook 설치 

 

 

 

① Miniconda 설치

  - Windows 버전의 Miniconda3 Installer를 다운로드 받아서 설치하면 된다.

    . https://docs.anaconda.com/free/miniconda/

 

Miniconda

 

  - 약 78MB 정도의 용량의 설치파일이 다운로드 된다.

 

Installer

 

  - 이후 옵션은 모두 default로 해서 설치를 진행하도록 하자 (경로 등록 등도 일단 그냥 무시하자)

 

 

Complete

 

  - 우리는 설명서 따위는 보지 않는 ...... ^^

 

② conda-forge 등록

  - Windows 키보드를 눌러보면 새로 설치된 앱을 확인할 수 있다.

 

실행

 

  - 본인 취향대로 골라서 실행하면 되지만, 여기에서는 밑에 있는 "Anaconda Prompt (miniconda3)"를 선택했다.

 

prompt

 

  - 명령어는 다음과 같다.

(base) C:\Users\whatw>conda config --add channels conda-forge

(base) C:\Users\whatw>conda config --set channel_priority strict

(base) C:\Users\whatw>conda config --show channels
channels:
  - conda-forge
  - defaults

 

③ conda 가상환경 생성

  - 일단 conda 가상환경을 생성해야 한다. 이 때, 사용할 Python 버전을 지정하면 된다.

 

conda

 

  - 중간에 계속 설치를 진행할 것인지 묻는 부분이 나오는데, 그냥 엔터 때리면(?) 된다.

(base) C:\Users\whatw>conda create -n p39 python=3.9.15
Channels:
 - conda-forge
 - defaults
Platform: win-64
Collecting package metadata (repodata.json): done

...

done
#
# To activate this environment, use
#
#     $ conda activate p39
#
# To deactivate an active environment, use
#
#     $ conda deactivate

 

  - 설치 완료 부분을 보면 가상환경을 실행하는 방법과 종료하는 방법을 알려준다.

 

④ Jupyter Notebook 설치

  - 앞에서 생성한 가상환경 內 Jupyter Notebook을 설치해야하기에 우선 가상환경을 실행하자.

 

active

 

  - 프롬프트 앞 부분을 보면 현재 실행중인 환경 정보를 알려준다. 항상 신경쓰자.

 

  - 이제는 Jupyter Notebook 패키지를 설치하자.

(p39) C:\Users\whatw>pip install jupyter notebook ipykernel
Collecting jupyter
  Downloading jupyter-1.0.0-py2.py3-none-any.whl.metadata (995 bytes)
Collecting notebook
  Downloading notebook-7.1.2-py3-none-any.whl.metadata (10 kB)

...

 

  - 커널도 등록하자

(p39) C:\Users\whatw>python -m ipykernel install --user --name p39 --display-name "python 3.9"
Installed kernelspec p39 in C:\Users\whatw\AppData\Roaming\jupyter\kernels\p39

 

  - 'Jupyter Notebook'이 실행될 경로를 하나 만든 뒤, 그 곳에서 실행하자.

 

execute

 

  - 갑자기 웹브라우저가 아래와 같이 실행되면 성공한 것이다.

 

jupyter notebook

 

  - 오른쪽 "New" 버튼을 통해 notebook을 생성하자.

 

hello

 

잘 된다!

 

반응형

Chapter 03

 

어느덧 3주차 스터디까지 왔다! 와아 ~~~~ !!!

2주차 우수혼공족에 선정되어 간식 선물까지 받았다 ~~~ !!! 꺄아 ~~~~ !!!

 

우수혼공족

 

▶ 요약

3-1. 불필요한 데이터 삭제하기
- *.loc[]
  . slicing(슬라이싱)
    ( *.loc[:, '번호':'등록일자'] )
  . boolean array(불리언 배열)
    ( df.loc[:, df.column != 'map'] )
- *.drop()
  . 지칭하는 column을 삭제
    ( *.drop(column_name, axis=1) )
  . 지칭하는 row를 삭제
    ( *.drop([0,1]) # 0행, 1행을 삭제 )
- *.dropna()
  . NaN 값을 1개라도 갖고 있으면 column 삭제
    ( *.dropna(axis=1) )
  . NaN 값을 모두 갖고 있으면 column 삭제
    ( *.dropna(axis=1, how='all') )
- *.duplicated()
  . 지정한 columns의 값이 동일하면 중복된 행의 값을 리턴
    ( *.duplicated(subset=['도서명','저자','ISBN'], keep=False) )
- *.groupby()
  . 지정한 columns의 값이 동일한 것들을 묶어줌
    ( *.groupby(by=['도서명', '저자', 'ISBN', '권'], dropna=False).sum() )

3-2. 잘못된 데이터 수정하기
- *.info()
  . DataFrame의 다양한 통계를 보여주는 유용한 method
- *.isna()
  . NaN 값을 갖고 있는 column을 보여줌
    ( *.isna().sum() )
- Nan
  . None
  . np.nan
- *.fillna()
  . NaN 값을 갖고 있는 columns에 지정한 값을 채움
    ( *.fillna('없음') )
    ( *['부가기호'].fillna('없음') )
    ( *.fillna( {'부가기호':'없음'} ) )
- *.replace()
  . 값 exchange
    ( *.replace(np.nan, '없음') )
    ( *.replace( [np.nan, '2021'], ['없음', '21']) )
    ( *.replace( {np.nan: '없음', '2021' : '21']) )
    ( *.replace( {'부가기호': np.nan}, '없음') )
    ( *.replace( {'부가기호': {np.nan : '없음'}, '발행년도': {'2021' : '21'}} ) )
  . 정규표현식
    ( *.replace( {'발행년도': {r'\d{2}(\d{2})' : r'\1'}}, regex=True) )

 

 

▶ 기본 미션

p. 182의 확인 문제 2번 풀고 인증하기

 

[문제]

1번 문제의 df1 데이터프레임에서 'col1' 열의 합을 계산하는 명령으로 올바르지 않은 것은 무엇인가요?

 

 

df1['col1'].sum()

df1[['col1']].sum()

df1.loc[:, df1.columns == 'col1'].sum()

df1.loc[:, [False,False,True]].sum()

 

 

※ 위 문제에서 bold 표기한 부분은 책에서 잘못된 부분을 수정한 내용입니다.

    - 문제에서 "것은" 부분이 빠져있었습니다.

    - 보기에서 "df"가 아니라 "df1"이라고 해야합니다.

 

[풀이]

④ 에서 boolean으로 표기된 내역을 보면 [False,False,True]로 되어있기에 'col1'이 아니라 'col3'의 합계가 출력된다.

 

그러면, 이것을 검증해보자.

 

일단, 데이터를 준비해봤다.

NaN 값을 처리하기 위해 Numpy의 np.nan을 사용했다.

 

 

각 보기의 값을 확인해보자.

 

 

확인 끝~

 

 

▶ 선택 미션

p. 219의 확인 문제 5번 풀고 인증하기

 

[문제]

다음과 같은 df 데이터프레임에서 df.replace(r'ba.*', 'new', regex=True)의 결과는 무엇인가요?

 

보기는 생략.

 

※ 위 문제에서 bold 표기한 부분은 책에서 잘못된 부분을 수정한 내용입니다.

    - 문제에서 "같은" 부분이 빠져있었습니다.

 

[풀이]

정규식을 이용한 replace() 문제이다.

정규식을 보면 r'ba.*' 부분을 살펴보면 'ba'로 시작하는 문자열을 지칭하고 있다.

그래서 'ba'로 시작하는 문자열을 'new'로 바꿔치기하면 된다.

 

교재(책) 보기로 보면 ③ 번에 해당하는 결과가 정답이 된다.

 

이것을 검증해보자.

 

 

 

이번 Chapter는 비교적 수월했다.

남은 기간 스스로에게 파이팅 !!!

 

반응형

 

최근 특히 AI 관련한 개발 업무를 하게 되면서 Anaconda를 필요로 하는 경우가 많다.

 

https://www.anaconda.com/

 

그런데, 문제는 ... 라이선스 이슈가 있기에 회사에서 사용하려면 주의를 해야 한다.

 

"어?! 오픈소스 아니야?"

 

라고 생각하는 분들이 많을 것 같은데,

홈페이지 주소를 보면 알겠지만 Anaconda는 300명 이상의 임직원을 보유하고 있는 회사다.

 

하지만, 아주 선량하게도 오픈소스 커뮤니티도 유지하면서

오픈소스 프로젝트나 교육 기관 등에서 무료로 사용할 수 있도록 해주고 있다.

 

Pricing

 

그런데, 문제는 저기 보이는 "Free" 요금제의 조건이다.

 

Free Plans

 

200명 이상의 임직원이 있는 곳이라면 .... 무료로 사용하면 안된다.

조금 더 자세히 살펴보자.

 

https://www.anaconda.com/blog/anaconda-commercial-edition-faq

 

2020년도에 (아마도 먹고 살기 위해) 서비스 약관을 변경했다.

200명 이상 규모의 회사에서 사용하기 위해서는 Enterprise Edition을 사용해야 한다.

 

그런데, 더 자세히 살펴보기 바란다.

 

"Anaconda vs. Anaconda's repositories"

 

Anaconda를 사용하는 것이 문제가 아니라

Anaconda의 저장소를 사용하는 것이 문제란다.

 

어!? 그러면 Anaconda' s repositories를 사용하지 않으면 되는 것 아닌가?!

 

https://www.anaconda.com/about-us

 

CEO이자 창립자인 피터 왕 형님(?)이 reddit에서 직접 그냥 대놓고 방법을 알려주셨다.

 

https://www.reddit.com/r/Python/comments/iqsk3y/comment/g4xuabr/

 

Miniconda + conda-forge 조합으로 사용하면

Anaconda의 commercial 약관에 영향을 받지 않는다.

 

결론 !!!

200명 이상 임직원을 보유하고 있는 회사에서는 Miniconda + conda-forge 조합으로 설치해서 사용하면 된다.

 

▶ Miniconda

쓸데 없는 패키지 설치 없이 깔끔하게 설치되는 가벼운 conda 이다.

 

https://docs.conda.io/projects/miniconda/en/latest/

 

Ubuntu 환경에서 설치하는 과정을 살펴보겠다.

❯ mkdir -p ~/miniconda3

❯ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
--2024-01-10 23:13:40--  https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
repo.anaconda.com (repo.anaconda.com) 해석 중... 104.16.130.3, 104.16.131.3, 2606:4700::6810:8203, ...
다음으로 연결 중: repo.anaconda.com (repo.anaconda.com)|104.16.130.3|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 200 OK
길이: 141613749 (135M) [text/x-sh]
저장 위치: `/home/chani22/miniconda3/miniconda.sh'

/home/chani22/miniconda3/miniconda.sh        100%[==============================>] 135.05M  57.3MB/s    / 2.4s     

2024-01-10 23:13:43 (57.3 MB/s) - `/home/chani22/miniconda3/miniconda.sh' 저장함 [141613749/141613749]


❯ bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
PREFIX=/home/chani22/miniconda3
Unpacking payload ...
                                                                                                               
Installing base environment...


Downloading and Extracting Packages:


Downloading and Extracting Packages:

Preparing transaction: done
Executing transaction: done
installation finished.

❯ rm -rf ~/miniconda3/miniconda.sh

❯ ~/miniconda3/bin/conda init zsh
no change     /home/chani22/miniconda3/condabin/conda
no change     /home/chani22/miniconda3/bin/conda
no change     /home/chani22/miniconda3/bin/conda-env
no change     /home/chani22/miniconda3/bin/activate
no change     /home/chani22/miniconda3/bin/deactivate
no change     /home/chani22/miniconda3/etc/profile.d/conda.sh
no change     /home/chani22/miniconda3/etc/fish/conf.d/conda.fish
no change     /home/chani22/miniconda3/shell/condabin/Conda.psm1
no change     /home/chani22/miniconda3/shell/condabin/conda-hook.ps1
no change     /home/chani22/miniconda3/lib/python3.11/site-packages/xontrib/conda.xsh
no change     /home/chani22/miniconda3/etc/profile.d/conda.csh
modified      /home/chani22/.zshrc

==> For changes to take effect, close and re-open your current shell. <==  

 

마지막의 init은 새로운 버전으로 업데이트하거나 했을 때 초기화 하는 것인데 그냥 첫 설치 때도 해봤다.

bash 쓰시는 분들은 뒤의 zsh 부분을 바꿔치기하면 된다.

 

 

▶ conda-forge

conda가 설치되면 기본적으로 등록되어 있는 channel은 "https://repo.anaconda.com/pkgs/" 이다.

저 저장소가 바로 문제가 되는 최종 사용자 라이선스 계약(EULA) 항목이 존재하는 곳이다.

- https://legal.anaconda.com/policies/en/?name=end-user-license-agreement#end-user-license-agreement

 

그러면 conda-forge는 무엇일까?

 

https://conda-forge.org/

 

community 리딩의 많은 기여자들의 활발한 참여로 운영되는 저장소이다.

 

정말 많은 패키지들이 등록되고 있고 그렇다보니

Anaconda의 공식 저장소보다 더 많은 패키지들이 존재하기에 commercial 이슈가 아니더라도

일부러 conda-forge를 저장소로 등록해서 사용자들도 많다고 한다.

 

conda에서는 이러한 저장소를 channel이라는 용어를 사용하고 있다.

❯ conda config --add channels conda-forge

❯ conda config --set channel_priority strict

❯ conda config --show channels
channels:
  - conda-forge
  - defaults

 

끝이다.

 

말이 좀 많았는데 실제로 손으로 직접 해야하는 것은 별 것 없다.

이걸로 compliance 이슈를 하나 해결할 수 있다 ^^

 

 

그러면, 실습을 하나 해보자 !!!

 

▶ Jupyter Notebook 실행하기

 

① 가상환경 생성하기

명령어 실행하는 위치는 어디든 무관하다.

❯ conda create -n python_39 python=3.9.15
Channels:
 - conda-forge
 - defaults
Platform: linux-64
Collecting package metadata (repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: /home/chani22/miniconda3/envs/python_39

  added / updated specs:
    - python=3.9.15


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    _libgcc_mutex-0.1          |      conda_forge           3 KB  conda-forge
    _openmp_mutex-4.5          |            2_gnu          23 KB  conda-forge
    bzip2-1.0.8                |       hd590300_5         248 KB  conda-forge
    ca-certificates-2023.11.17 |       hbcca054_0         151 KB  conda-forge
    ld_impl_linux-64-2.40      |       h41732ed_0         688 KB  conda-forge
    libffi-3.4.2               |       h7f98852_5          57 KB  conda-forge
    libgcc-ng-13.2.0           |       h807b86a_3         755 KB  conda-forge
    libgomp-13.2.0             |       h807b86a_3         412 KB  conda-forge
    libnsl-2.0.1               |       hd590300_0          33 KB  conda-forge
    libsqlite-3.44.2           |       h2797004_0         826 KB  conda-forge
    libuuid-2.38.1             |       h0b41bf4_0          33 KB  conda-forge
    libzlib-1.2.13             |       hd590300_5          60 KB  conda-forge
    ncurses-6.4                |       h59595ed_2         864 KB  conda-forge
    openssl-3.2.0              |       hd590300_1         2.7 MB  conda-forge
    pip-23.3.2                 |     pyhd8ed1ab_0         1.3 MB  conda-forge
    python-3.9.15              |hba424b6_0_cpython        21.0 MB  conda-forge
    readline-8.2               |       h8228510_1         275 KB  conda-forge
    setuptools-69.0.3          |     pyhd8ed1ab_0         460 KB  conda-forge
    tk-8.6.13                  |noxft_h4845f30_101         3.2 MB  conda-forge
    tzdata-2023d               |       h0c530f3_0         117 KB  conda-forge
    wheel-0.42.0               |     pyhd8ed1ab_0          56 KB  conda-forge
    xz-5.2.6                   |       h166bdaf_0         409 KB  conda-forge
    ------------------------------------------------------------
                                           Total:        33.5 MB

The following NEW packages will be INSTALLED:

  _libgcc_mutex      conda-forge/linux-64::_libgcc_mutex-0.1-conda_forge 
  _openmp_mutex      conda-forge/linux-64::_openmp_mutex-4.5-2_gnu 
  bzip2              conda-forge/linux-64::bzip2-1.0.8-hd590300_5 
  ca-certificates    conda-forge/linux-64::ca-certificates-2023.11.17-hbcca054_0 
  ld_impl_linux-64   conda-forge/linux-64::ld_impl_linux-64-2.40-h41732ed_0 
  libffi             conda-forge/linux-64::libffi-3.4.2-h7f98852_5 
  libgcc-ng          conda-forge/linux-64::libgcc-ng-13.2.0-h807b86a_3 
  libgomp            conda-forge/linux-64::libgomp-13.2.0-h807b86a_3 
  libnsl             conda-forge/linux-64::libnsl-2.0.1-hd590300_0 
  libsqlite          conda-forge/linux-64::libsqlite-3.44.2-h2797004_0 
  libuuid            conda-forge/linux-64::libuuid-2.38.1-h0b41bf4_0 
  libzlib            conda-forge/linux-64::libzlib-1.2.13-hd590300_5 
  ncurses            conda-forge/linux-64::ncurses-6.4-h59595ed_2 
  openssl            conda-forge/linux-64::openssl-3.2.0-hd590300_1 
  pip                conda-forge/noarch::pip-23.3.2-pyhd8ed1ab_0 
  python             conda-forge/linux-64::python-3.9.15-hba424b6_0_cpython 
  readline           conda-forge/linux-64::readline-8.2-h8228510_1 
  setuptools         conda-forge/noarch::setuptools-69.0.3-pyhd8ed1ab_0 
  tk                 conda-forge/linux-64::tk-8.6.13-noxft_h4845f30_101 
  tzdata             conda-forge/noarch::tzdata-2023d-h0c530f3_0 
  wheel              conda-forge/noarch::wheel-0.42.0-pyhd8ed1ab_0 
  xz                 conda-forge/linux-64::xz-5.2.6-h166bdaf_0 


Proceed ([y]/n)? 


Downloading and Extracting Packages:
                                                                                                                                                                                   
Preparing transaction: done                                                                                                                                                        
Verifying transaction: done                                                                                                                                                        
Executing transaction: done                                                                                                                                                        
#                                                                                                                                                                                  
# To activate this environment, use                                                                                                                                                
#                                                                                                                                                                                  
#     $ conda activate python_39                                                                                                                                                   
#                                                                                                                                                                                  
# To deactivate an active environment, use                                                                                                                                         
#                                                                                                                                                                                  
#     $ conda deactivate                                                                                                                                                           
  

 

② 가상환경 활성화 하기

친절하게 앞에서 알려준대로 실행하면 된다.

❯ conda activate python_39

 

③ 패키지 설치

❯ pip install jupyter notebook ipykernel
Collecting jupyter
  Downloading jupyter-1.0.0-py2.py3-none-any.whl (2.7 kB)
Collecting notebook
  Downloading notebook-7.0.6-py3-none-any.whl.metadata (10 kB)
Collecting ipykernel
  Downloading ipykernel-6.28.0-py3-none-any.whl.metadata (6.0 kB)
Collecting qtconsole (from jupyter)
  Downloading qtconsole-5.5.1-py3-none-any.whl.metadata (5.1 kB)

...  

 

④ 가상환경과 Jupyter Notebook 연결

❯ python -m ipykernel install --user --name python_39 --display-name python_39
Installed kernelspec python_39 in /home/chani22/.local/share/jupyter/kernels/python_39

 

⑤ Jupyter Notebook 실행

❯ jupyter notebook
[W 2024-01-11 00:29:46.408 ServerApp] A `_jupyter_server_extension_points` function was not found in jupyter_lsp. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[W 2024-01-11 00:29:46.429 ServerApp] A `_jupyter_server_extension_points` function was not found in notebook_shim. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[I 2024-01-11 00:29:46.429 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2024-01-11 00:29:46.432 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2024-01-11 00:29:46.435 ServerApp] jupyterlab | extension was successfully linked.
[I 2024-01-11 00:29:46.439 ServerApp] notebook | extension was successfully linked.
[I 2024-01-11 00:29:46.440 ServerApp] Writing Jupyter server cookie secret to /home/chani22/.local/share/jupyter/runtime/jupyter_cookie_secret
[I 2024-01-11 00:29:46.604 ServerApp] notebook_shim | extension was successfully linked.
[I 2024-01-11 00:29:46.618 ServerApp] notebook_shim | extension was successfully loaded.
[I 2024-01-11 00:29:46.619 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2024-01-11 00:29:46.620 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[I 2024-01-11 00:29:46.621 LabApp] JupyterLab extension loaded from /home/chani22/miniconda3/envs/python_39/lib/python3.9/site-packages/jupyterlab
[I 2024-01-11 00:29:46.621 LabApp] JupyterLab application directory is /home/chani22/miniconda3/envs/python_39/share/jupyter/lab
[I 2024-01-11 00:29:46.622 LabApp] Extension Manager is 'pypi'.
[I 2024-01-11 00:29:46.624 ServerApp] jupyterlab | extension was successfully loaded.
[I 2024-01-11 00:29:46.625 ServerApp] notebook | extension was successfully loaded.
[I 2024-01-11 00:29:46.626 ServerApp] Serving notebooks from local directory: /srv/workspace/python_39
[I 2024-01-11 00:29:46.626 ServerApp] Jupyter Server 2.12.3 is running at:
[I 2024-01-11 00:29:46.626 ServerApp] http://localhost:8888/tree?token=5ed486a3d676270879b3684991a11b4932c981c265dddef4
[I 2024-01-11 00:29:46.626 ServerApp]     http://127.0.0.1:8888/tree?token=5ed486a3d676270879b3684991a11b4932c981c265dddef4
[I 2024-01-11 00:29:46.626 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 2024-01-11 00:29:47.025 ServerApp] 
    
    To access the server, open this file in a browser:
        file:///home/chani22/.local/share/jupyter/runtime/jpserver-4428-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/tree?token=5ed486a3d676270879b3684991a11b4932c981c265dddef4
        http://127.0.0.1:8888/tree?token=5ed486a3d676270879b3684991a11b4932c981c265dddef4
[I 2024-01-11 00:29:47.041 ServerApp] Skipped non-installed server(s): bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server

 

웹브라우저가 실행되면서 Jupyrt Notebook이 등장한다!!!

Jupyter Notebook

 

새로운 파일을 하나 생성해보자.

New - Notebook

 

기본 kernel도 보이지만,

우리가 만들어낸 python_39 도 보인다.

Select Kernel

 

개발자라면 외쳐요. Hello ~ !!!

Hello

 

오른쪽 상단 즈음에 보이는 JupyterLab 버튼은 뭐지?

JupyrtLab

 

응?! 이건 Colab ???? ^^

 

 

즐거운 회사 생활 !!!

반응형

나름의 이유로 시스템에서 메일을 보내야할 일이 있는데,

이왕이면 Gmail을 이용해보고 싶어서 살펴보기로 했다.

 

일단 Gmail을 통해 이메일을 보내기 위해서

미리 셋팅을 해줘야 할 것이 있다.

 

 

Gmail의 설정 화면으로 이동한 뒤에

 

 

IMAP 사용 설정을 해주면 된다.

 

 

그런데, Python 코드에서 Gmail 인증 부분을 구현해야 이메일 발송을 할 수 있을텐데,

2가지 방법 중 하나를 선택해야 한다.

 

1. 로그인 PASSWORD
2. 앱 PASSWORD

 

로그인 PASSWORD를 사용하기에는 왠지 찝찝한 느낌이 들기에

앱 PASSWORD를 사용하도록 해보겠다. (보안은 중요하다!!! ^^)

 

 

Google 계정 관리 화면에 일단 들어가보자.

 

 

어?! 그런데, 찾고자 하는 "앱 비밀번호" 부분이 안보인다.

 

 

2단계 인증을 사용한다고 해야 원하는 항목이 등장한다.

2단계 인증을 사용하게 되면 조금 불편할 수도 있지만, 보안을 위한 일이니 감수하자!!! ^____^

 

 

전화 및 인증 기기 등을 잘 확인하면서 진행하면 되는데,

 

 

개인적으로 OTP 앱까지 추가해주는 것을 추천한다.

 

자~ 이제, "앱 비밀번호" 항목을 볼 수 있다.

 

 

우리 입맛에 맞게 생성 진행하면 된다.

 

 

그러면 16 digit을 만들어 준다.

 

 

저 비밀번호는 다시 안알려준다. 미리 잘 기억/기록 해야 한다.

 

 

자~ 이제 Gmail에서 준비할 것은 모두 끝났다.

이제 Python 코딩을 시작해보자.

 

 
  #!/usr/bin/env python3
  """
  Send email via Gmail SMTP
  """

  __author__ = "whatwant"
  __version__ = "0.1.0"
  __license__ = "BEER-WARE"

  import smtplib
  from email.mime.text import MIMEText
  from email.mime.multipart import MIMEMultipart

  def send_email(sender_email, receiver_email, app_password, subject, text, html):
      message = MIMEMultipart("alternative")
      message["Subject"] = subject
      message["From"] = sender_email
      message["To"] = receiver_email

      part1 = MIMEText(text, "plain")
      part2 = MIMEText(html, "html")

      message.attach(part1)
      message.attach(part2)

      with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
          server.login(sender_email, app_password)
          server.sendmail(sender_email, receiver_email, message.as_string())

  if __name__ == "__main__":
      sender_email = "whatwant@whatwant.com"
      receiver_email = "whatwant@gmail.com"
      app_password = "xxx"
 
      subject = "This is a lucky email from Python"
      text = "whatwant is a good man."
      html = f"<html><body><p>{text}</p></body></html>"
 
      send_email(sender_email, receiver_email, app_password, subject, text, html)

 

여전히 예쁘지 않은 코드이지만, 그래도 동작한다!

실행하면 된다.

 

 

메일이 잘 도착했다!!!

 

첨부파일까지 보내는 것까지 하려고 했는데, 지금 당장은 필요하지 않기에...^^

나중에 필요로 할 때 해보겠다! ^^

 

반응형

업무를 하면서 간단한 Python 코드를 작성하고

코드 리뷰를 받을 때면 종종 왠지 모르게 부끄러움을 느낄 때가 있다.

 

남들이 작성한 코드를 보면 왠지 멋져보이는데

내 코드는 왠지 모르게 초라해보이는 자격지심이..... ^^

 

예를 들어서 "현재 디렉토리의 파일 이름과 사이즈를 출력"해주는 프로그램을 작성해보자.

 

 

실행 결과도 잘 나온다.

 

 

원하는 결과를 잘 뽑아내고,

나름 함수로 잘 구분해서 잘 작성한 것 같은데..... 왠지 뭔가 부족한 듯 한 느낌이...

 

속된 말로 뭔가 "와꾸"가 있었으면 좋겠는데...

 

 

https://www.python-boilerplate.com/

 

이런 고마운 사이트가 있다니!!!

 

Parameter들을 사용하고 싶거나, Logging을 하고 싶거나 하면 "Options"에서 고르면 된다.

Unit-Test를 하고 싶은 경우에 입맛에 맞는 프레임워크를 고를 수도 있다.

 

이걸 이용해서 코드를 다시 작성해보면 다음과 같다.

 

 

뭔가 조금 더 있어보이게 된 것 같은 느낌적인 느낌이다.

 

 

별 것 아니게 느낄 수도 있겠지만,

Python과 같은 자유도가 과도하게 높은 언어로 개발을 할 때에는

이런 boilerplate 코드를 이용하는 것이 많은 도움이 된다고 생각한다!

여러분은?

 

반응형

+ Recent posts