제이미

@theeluwin@hackers.pub · 61 following · 53 followers

스콜라아이돌교수버튜버

CV
theeluwin.github.io

지난 한달간 열심히 개발한 실시간 퀴즈 사이트입니다. django, django drf, jwt 기반 인증, websocket, ticket으로 받아오는 jwt websocket 인증, celery, 등을 모두 사용한 예시이기도 합니다. 구경와주세요~

https://github.com/theeluwin/Qlickr

6

django에서 test를 할 때, async/await 처리를 성공적(?)으로 하려면 TransactionTestCase를 사용해야하는데 이러면 classmethod인 setUpTestData를 사용하지 못합니다. 그래서 매 테스트 함수마다 데이터를 넣어주는 setUp으로 도로 바꿔야했고... 2분 걸리던 테스트를 최적화해서 10초로 줄여놨다가 다시 30초로 늘어났네요 뭔가... 하루종일 뭐한거지 싶지만,,, 꼭 한번 알고 갔어야하는 느낌이기도 합니다. 요컨대, 추상화/최적화는 정말 해봐야만 보이는 문제점이라는게 있고 제가 아직 경험이 부족해서 예측이 잘 안되네요(

2
0

서비스 A를 개발하기 위해 boilerplate B를 만들기 위한 boilerplate C를 만들고 시작했더니 A에서 뭐 하나 바꾸면 B, C까지 전부 다 바꾸고 있는 상황... 이게 실제로 운영을 해봐야만 발견할수 있는게 너무 많네요 하 당연한 얘기긴 한데ㅠ

1
2
0
1

서버에서 도커 빌드가 안됨 (메모리 부족)

로컬과 서버 CPU 아키텍처가 다름 (호환 안됨)

쉬운 해결책: 메모리를 돈 주고 늘린다

귀찮은 해결책: 빌드용 서버를 잠시 빌려서... 하ㅠ...

2

서버에서 도커 빌드가 안됨 (메모리 부족)

로컬과 서버 CPU 아키텍처가 다름 (호환 안됨)

쉬운 해결책: 메모리를 돈 주고 늘린다

귀찮은 해결책: 빌드용 서버를 잠시 빌려서... 하ㅠ...

2

무겁고 큰 메인 기능 구현 착수하기가 겁나서 가볍고 작은 서브 기능부터 구현하면서 차일피일 미루다가 더이상 서브 기능 남은게 없어서 드디어 메인 기능 구현을 했는데, 소요된 노력이 서브와 유사한 수준이라 뭔가... 알 수 없는 불안감이 느껴지는 이 기분... 아시나요... 중요한걸 미루지 맙시다(?

4

@akastoot악하 어떤 링크로 갈 수 있는 버튼을 사용할수 있는 상태인지 아닌지 (사용할수 없는 상태면 링크로 들어가도 무효화 처리까지) 입니다. 사실 누가 요구한건 아니고 제가 이렇게 한번 구현해보고 싶어서... 입니다.

0

요즘 웹을 많이 하고 있는데 정말 단순한 기능 하나도 뭐 이리 구현할게 많은지요...

  1. 버튼 하나 누르면 어떠한 상태 변경이 전파 되는 기능임
  2. 버튼을 누르는 유저는 그걸 누를 수 있는 권한이 있는지 체크
  3. 모든 유저가 websocket으로 전파 받을 수 있도록 해야함
  4. 로그에 JWT가 남으면 싫으니까 ticket을 발행해서 연결
  5. 해주는 API를 짜고 ticket에서 user 알아내서 컨텍스트에 붙여주는 미들웨어 구현
  6. 을 하기 위해 이제 redis로 캐시를 붙이고
  7. 백엔드 다 했으면 프론트에서 이제 어떤 component가 websocket에 연결 되어 있을지
  8. 이걸 받아서 또 다른 component한테 어떻게 뿌리지 (event emit으로...
  9. 등등등...
  10. 따라서 일단 야크 털을 깎아야한다 라는
5

클로드 데스크탑에서 사용할 수 있는 알라딘 MCP 서버를 DXT 파일로 공유합니다. 베스트셀러나 신간 정보, 도서 정보를 조회할 수 있습니다. 알라딘 API만 발급 받으면 편하게 쓰실 수 있습니다.

https://github.com/TeeDDub/mcp-aladin-books-server

5
0
1
0

아마 다들 비슷한 경험이 있으실겁니다. 태어나서 처음으로 쌍방향 연결에 성공해서 두 클라이언트가 대화할 수 있게 했을때의 기쁨... 저는 딱 15년만에 하는거라(...) 처음 해본것처럼 기쁘네요

디버깅할게 정말 많고 복잡한 뭐시기인것 같습니다. 참고로 가장 마지막 실패 원인은 django가 ASGI로 실행되지 않았기 때문이었습니다. test 환경에서는 이런 문제가 발생하지 않죠...

0

아마 다들 비슷한 경험이 있으실겁니다. 태어나서 처음으로 쌍방향 연결에 성공해서 두 클라이언트가 대화할 수 있게 했을때의 기쁨... 저는 딱 15년만에 하는거라(...) 처음 해본것처럼 기쁘네요

8
2
3

(이미 저 멀리 와버린 야크 털 깎기 - 어디서 출발했는지도 이젠 잊어버림)

django에서 django rest framework에서 jwt로 authentication을 하기 위해 simple jwt를 쓸 때 (아이고 길다) access, refresh token을 cookie에 두고 사용하고 싶다면 약간의 수제(?) 코드가 필요합니다. 누군가 구현 해놨을까 싶었는데 있네요!

https://velog.io/@kimjihong/simple-jwt-login

https://velog.io/@kimjihong/issue-drf-jwt-header#solution---custom-middleware

하... 하려던건 이게 아닌데 이걸 적용 할지말지 또 고민... (결국 하겠죠

1
1

구체적으로 내가 원하는 스펙이 따로 있어서 직접 구현하기로 했습니다... 근데 이거를 다시 오픈소스로 만들면 또 관리 안되는 오픈소스C가 탄생하는 것일까요?

3

django channels에서 jwt authentication을 쓰고 싶은데

  1. 직접 만들긴 뭔가 싫다
  2. 오픈소스A는 5년 전에 마지막 커밋이 있다...
  3. 오픈소스B는 2년 전이 마지막이긴 한데 .DS_Store가 같이 커밋 되어있어서 불안하다...

어카지

1

야크 털 깎기 안하기가 쉽지 않습니다.

  • 지금 필요한것: 일정 시간 동안만 설문을 수집하여 결과 확인하기
  • 올바른 구현: 구글 폼
  • 실제로 하고 있는것: 일정 시간만 공개되는 설문을 실시간 퀴즈 풀기 사이트와 유사하므로 웹소켓으로 퀴즈 내용을 알려주는 풀스택 웹서비스를 구현하기 위한 boilerplate에 혹시 모를 task 관리를 위해 redis 붙이고 celery 붙이고 모니터링 붙일지 말지 고민하기
0

야크 털 깎기 안하기가 쉽지 않습니다.

  • 지금 필요한것: 일정 시간 동안만 설문을 수집하여 결과 확인하기
  • 올바른 구현: 구글 폼
  • 실제로 하고 있는것: 일정 시간만 공개되는 설문을 실시간 퀴즈 풀기 사이트와 유사하므로 웹소켓으로 퀴즈 내용을 알려주는 풀스택 웹서비스를 구현하기 위한 boilerplate에 혹시 모를 task 관리를 위해 redis 붙이고 celery 붙이고 모니터링 붙일지 말지 고민하기
6
0
1

Pelican을 기준으로,

  1. docker 개발(hot-reload), 프로덕션(nginx) 환경 구축
  2. jinja2 tag, filter, macro 사용하기 (+ context)
  3. GitHub Action으로 build 테스트 + PR merge시 GitHub Pages로 deploy하기

하는 내용이 동봉되어있습니다. 약간 튜토리얼을 겸한달까요...

이왕 이렇게 된거 후기 글도 쓰고 정말로 튜토리얼도 만들고 할까 싶었지만... 코딩 하느라 좀 지쳐버린ㅠ

1

대학원 연구실 홈페이지 생성기를 만들었습니다. Jekyll은 Ruby니까, 이번엔 Python을 좀 써보자 싶어서 Pelican으로 구현했습니다. Article을 일종의 DB처럼 사용해서 멤버나 논문, 뉴스, 강의 등의 데이터를 관리하는 방식입니다.

솔직히는 하루이틀이면 끝날줄 알았는데 만드는데 거의 full-time으로 일주일이 걸렸네요. macro에서 왜 context가 전달이 안되는지, filter에서는 왜 안되는지, GitHub Action은 왜 맨날 뻑이 나는지... branch 규칙도 여러번 수정하고 github pages로 내보낼때만 fork me 리본 달아주고 등등... 왤케 자잘하게 할게 많은지ㅠ

Pelican 자체는 쓸만하더라구요. 필요한 기능이 거의 다 있습니다. 근데 없는것처럼 보여요. 근데 다 있긴 합니다.

암튼... 구경와주세요

https://github.com/theeluwin/pelican-labsite

Pelican 기반 대학원 연구실 홈페이지 생성기로 만든 사이트 예시 스크린샷.
7
3

웹코딩 왤케 재밌는지, 약간 게임에 빠져있는것과 같은 경험임

  1. 현재 내게 중요하지 않은 작업 (즉, 딴짓)
  2. 책임을 지지 않아도 되는 서비스 (상업용이 아님)
  3. 오랜만에 함
  4. 원래 좀 재밌긴 함

이렇게 네가지가 겹침.

방금은 최적화도 좀 했다. 대충 O(n^3)쯤 되는 코드를 O(n)으로 바꿈. 근데 n은 대충 10쯤 되고, 기존 0.01초 걸리던게 이제는 0.01초 걸림.

4
1

연구실 홈페이지를 쉽게 만들고 관리 할 수 있는 pelican 기반 bolierplate를 만들고 있습니다...만, 이건 말이 bolierplate지 사실상 theme도 포함인거라 디자인이 좀 들어가있어야하는데... 여기서 막혔습니다,,, 다른 부분은 완전 완성인데ㅜㅜ

1

테스트 작성 할 때 마다 약간 테스트 자체를 자꾸 디버깅 하고 있느라 시간을 다 쓴다는 느낌이었는데... 오늘은 그래도 Cursor의 도움으로 94개나 되는 테스트를 순식간에 작성했고 (엄청난 디버깅이 있었지만) 그래도 딱 한개, 정말로 테스트에 의해서만 잡을 수 있는 문제를 발견해서 올바르게 수정 할 수 있었다.

3
4
1

오픈소스에서 아쉬운 점 발견 → 내가 기여해야지! → 혹시 모르니 issue, PR 확인해서 중복이 아닌지 체크 → 이미 해결된 문제였고 내가 사용법을 몰랐을 뿐 (그럼 접근성이 부족하니 문서라도 업데이트 할까? → 문서에도 적혀있었고 그저 내가 게을렀을 뿐)

9

jekyll 대신 pelican을 써보고 있습니다. Cursor에게 알아서 좀 짜라고 맡겨놨더니 링크가 모조리 깨지고 화면 템플릿도 제대로 안보이고 난리더라구요. 4시간동안 잡도리를 한 결과, 그냥 제가 처음부터 다시 다 짰습니다. 젠장... 암튼 pelican 쓸만 하네요. 어차피 대부분의 기능은 직접 구현해야해서, 최소한의 세팅만을 원했는데 충분히 제공하는것 같습니다. 공개할 수 있게되면 use case로써 공유해볼게요.

1
1
1
2

(user, quiz, option)을 response의 필드로 두고 (user, quiz)에 unique constraint를 걸면, option이 quiz 소속인지를 보장 할 수 없는데, 이거까지 보장하는건 쉽지 않습니다.

@theeluwin제이미 option 테이블의 기본 키를 (quiz_id, index) 정도의 복합 키로 만든 뒤에, response 테이블의 (quiz_id, option_index)option 키의 외래 키로 만들면 option이 어느 quiz의 소속인지 강제할 수 있지 않을까요?

1

퀴즈엔 여러개의 보기가 있습니다. 사용자는 퀴즈당 한개의 보기만 고를 수 있습니다. 이를 어떻게 강제 할 수 있을까요? Django ORM에서 말이죠.

답은, ‘쉽지 않다’ 입니다.

(user, quiz, option)을 response의 필드로 두고 (user, quiz)에 unique constraint를 걸면, option이 quiz 소속인지를 보장 할 수 없는데, 이거까지 보장하는건 쉽지 않습니다.

(user, option)만 필드로 둘 경우엔 (user, option__quiz)를 unique로 둬야하는데 이런 기능은 존재하지 않죠.

복합키, trigger 등을 사용하기엔 너무 복잡하고, 결국 어플리케이션 로직이 필요합니다.

그래서, 어떡하지 이제

0

퀴즈엔 여러개의 보기가 있습니다. 사용자는 퀴즈당 한개의 보기만 고를 수 있습니다. 이를 어떻게 강제 할 수 있을까요? Django ORM에서 말이죠.

답은, ‘쉽지 않다’ 입니다.

(user, quiz, option)을 response의 필드로 두고 (user, quiz)에 unique constraint를 걸면, option이 quiz 소속인지를 보장 할 수 없는데, 이거까지 보장하는건 쉽지 않습니다.

(user, option)만 필드로 둘 경우엔 (user, option__quiz)를 unique로 둬야하는데 이런 기능은 존재하지 않죠.

복합키, trigger 등을 사용하기엔 너무 복잡하고, 결국 어플리케이션 로직이 필요합니다.

그래서, 어떡하지 이제

1

새롭게 다시 태어난, 또 만들어버린 boilerplate. 이제는 진짜 monolithic 하고 Pocket Galaxy라는 이름에 걸맞는 boilerplate입니다.

Django + Vue(Vuetify) 조합이구요, nginx가 이것저것을 다 처리합니다.

백엔드는 /api에서 서빙하고, 기타 기본적인 static 캐싱이나 로깅 등 전부 기초적인건 제공합니다.

간단한 웹사이트 하나 만들겠다는게 어쩌다 여기까지 왔는지.... 암튼 이제는 진짜 최소한의 웹사이트 만들때 뚝딱 하면 만들수 있을것 같습니다 제발...

내부용 툴 만들때 애용해보세요.

https://github.com/theeluwin/pocket-galaxy

2
0
2

아 9월부터 강의를 합니다 (교수가 되었습니다). 무슨 과목을 맡게될지는 모르겠지만 꿈에 그리던 기깔난... 마치 IoT로 도배된 집과도 같은 강의를 해보겠습니다 기대해주세요. 그리고 언젠가 이 경험들이 쌓여서 파이콘에서라도 발표하면 좋겠네요.

14