Github Profile에 사용하는 Badge API 만들기 (Kaggle Badge)
Learn by Doing으로 Kaggle Badge 만들기
깃헙에서 프로필 기능이 생긴 이후, 최근 (주니어) 개발자들의 깃헙 프로필은 다양한 배지와 html 스킬들로 화려하게 꾸며져있습니다. 일반적으로 사용하는 배지는 다음과 같습니다.
- 깃헙 통계 : 커밋수, 스타수, 팔로워수, 사용언어 수 등 다양한 통계
- 개발 스택 : 각자의 개발 스택에 맞는 이미지와 스티커
- 알고리즘 사이트 통계 : BOJ + Solved AC, LeetCode 등
물론 일부 개발자는 "개발은 열심히 안하고, 쓸데없이 꾸미기만 한다."라고 생각하고는 할 수 있습니다. 다음 이유로 이러한 프로필 꾸미기 문화가 좋다고 생각합니다.
- 자기를 어필하는 방법에 대한 고민. 개발자에게 자기PR는 필수입니다. 자기PR은 단순히 자랑이 아닌 본인 이미지의 설계입니다. 이런 자기 PR을 연습하기에 깃헙 프로필은 이력서보다 쉽고, 시각적으로 확인과 수정을 반복하며 지나친 자랑과 이미지 설계 사이의 느낌을 잡을 수 있습니다.
- 강점 등을 만들기 위한 동기부여. 저는 종종 비기너분들에게 이력서를 작성을 추천합니다. 이력서를 작성해보면 본인이 무엇이 부족한지 느낄 수 있습니다. 그 과정에서 이력서를 채우기 위해 노력하는 선순환 구조를 만들면 지속적인 성장을 할 수 있기 때문입니다.
그럼 우리는 깃헙 프로필에서 어떤 것을 보이고 싶어하는가? 저는 크게 3가지 정도라고 생각합니다.
- 관심사와 목표
- 강점
- 꾸준함과 노력의 증거
캐글(Kaggle)은 이런 부분을 모두 표현해줄 수 있습니다. 데이터 사이언스 대회 플랫폼인 캐글은 분야별 티어/메달이 존재하고 배지로 만들었을 때 관심이 있을 사용자가 많다고 판단하였습니다.
참고로 캐글은 분야는 4가지, 티어는 5단계, 메달은 3종류가 있습니다.
- 분야 : 티어 및 메달을 받을 수 있는 분야로 대회(competition), 데이터셋(dataset), 코드(notebook), 토론(discussion)이 있습니다.
- 메달 : 조건에 따라 각 분야별로 금, 은, 동이 있습니다.
- 티어 : 메달의 개수 요건에 따라 novice, contributor, expert, master, grandmaster가 됩니다.
캐글 배지를 만들면 분명 만들어야겠다는 생각을 지난 몇 개월간 하고 있었고, api 구조를 공부할 겸 주말 프로젝트로 시작해보았습니다.
깃헙 프로필 배지 사용 방법
일반적으로 깃헙 프로필에 사용하는 배지는 대부분 이런 형식으로 사용합니다.
![kaggle badge](https://url.com/?user={user id})
여기서 알 수 있는 것은 다음과 같습니다.
- 배지 정보는 링크로 불러온다. 링크를 들어가보면 <svg>로 구성된 html로 연결됩니다. 저희는 특정 링크를 접속하면 <svg>가 생성되도록 해야합니다. (저희는 이런걸 API라고 부르기라 했어요.)
- 유저 별로 정보를 가져와야 한다. 사이트에서 제공하는 api가 있다면 사용하면 되지만, 안된다면 크롤링이 필요하다.
저는 백엔드나 서버에 대한 지식이 매우 부족하기 때문에 이를 해결해줄 서비스가 필요했습니다. 이제 이런 부분들을 어떻게 해결했는지 가볍게 아래 개발 디테일을 설명하도록 하겠습니다.
개발 디테일
Vercel, 토이프로젝트용 서버 1분만에 클리어
서버를 구성한다는 것은 저같은 반쪽자리 개발자들에게 매우 어려운 일입니다. 서버 하나 사고, https 붙이고, CI/CD 붙이고....
토이프로젝트를 너무 많은 노력을 들이고 싶지는 않았습니다. 이런 서버를 제공하는 서비스는 몇 가지가 있습니다. 우선 많은 파이썬 백엔드 입문서 책에서 사용하는 heroku나 PythonAnywhere 등이 있습니다.
하지만 최근에는 vercel이 대세라고 합니다. 개인 사용자에 대해서는 금액도 무료고, https 붙여주고, github과 자동연동과 전체적인 구조에 대한 파이프라인 등 UX도 훌륭하고 전체적으로 백엔드 고민을 없애줍니다.
저는 road-to-kaggle-grandmaster라는 이름으로 레포를 만들었고, 자동으로 https://road-to-kaggle-grandmaster.vercel.app/ 라는 이름으로 사이트를 사용할 수 있습니다. 현재 api 작업만 하여 웹페이지는 default 상태이며 조금 더 코드를 개선한 후에는 소개 페이지 형식으로 변환할 예정입니다.
Next.js, 핫한 Framework 선택
vercel에서는 다양한 프레임워크를 제공하는데 저는 Next.Js를 사용했습니다. 별다른 이유는 없고 vercel에서 만든 framework이자 js로 api를 만들 수 있고, 속도가 빠르다고 하여 사용했습니다.
axios + cheerio, javascript 크롤링
캐글에서 제공하는 API는 따로 없기 때문에 크롤링을 직접해서 얻어야 했습니다. 기존에는 python으로만 크롤링하다 js로 크롤링하기 위해 검색해보니 axios와 cheerio를 사용하면 되었습니다. 각각 파이썬의 requests와 beautifulsoup와 같은 역할이라 크게 어렵지는 않았습니다.
- axios : 웹 페이지 정보를 html로 가져옴
- cheerio : html정보를 쉽게 처리할 수 있음 (parsing)
이 과정에서 API를 만들기 위해서는 비동기처리를 알아야 하고, async/await 정도는 알아야 합니다.
정보가 쉽게 가져올 수 있는 구조는 아니었고, html 코드를 뜯어보니 script 태그에서 정보들을 확인할 수 있었습니다. 사용자의 정보를 object로 받아 이를 파싱해서 다시 웹에 붙이는 구조였고, 약간의 텍스트 전처리와 json 파싱을 통해 string을 object로 뽑아서 사용할 수 있었습니다.
뽑은 정보는 각 분야별로 티어, highest rank/current rank, 메달 등의 정보를 쉽게 얻을 수 있는 구조입니다. 예시로 notebook 분야의 정보는 다음과 같이 추출됩니다.
scriptsSummary: {
tier: 'grandmaster',
totalResults: 85,
rankPercentage: 0.00005611157,
rankOutOf: 196038,
rankCurrent: 11,
rankHighest: 11,
totalGoldMedals: 21,
totalSilverMedals: 10,
totalBronzeMedals: 44,
highlights: [ [Object], [Object], [Object] ],
summaryType: 'notebooks'
}
Figma+Sketch, 초안 구상과 필요 디자인 설계
이제 뽑을 수 있는 정보가 있으니 디자인 초안 설계 단계로 넘어왔습니다. 이번 기회에 Figma를 써보고 싶어서 Figma로 초안을 만들었습니다. 디자인은 2가지를 생각하고 초안을 만들었습니다.
- 캐글에는 다양한 분야에 따른 분야별 배지
- 조회수 같이 간단한게 캐글 티어를 표현해줄 수 있는 배지
분야별 배지 디자인은 기본적인 정보만 담을 수 있게 만들어보았고, 심플한 티어 배지는 shield.io 등의 배지 디자인을 참고했습니다. 색이나 아이콘은 기존 캐글 시스템에서 사용하는 아이콘과 색상을 사용했습니다.
초안 설계 후, 캐글에서 제공하는 티어 아이콘과 메달 아이콘의 해상도가 낮아 마음에 들지 않아 Sketch로 티어 svg 파일을 새롭게 만들었습니다. (원래도 Sketch를 사용해서 디테일한 디자인 작업은 쓰던게 편하더라구요.😀)
이런 아이콘 작업은 figma, adobe xd, 포토샵, 일러스트레이터부터 심지어 파워포인트나 키노트에서도 가능하니 편하신 환경에서 작업하시면 됩니다.
JS + SVG + HTML로 재구성
Next.Js에서 svg를 export하는 api를 만들기 위한 기초 구조는 다음과 같습니다.
사용자의 id를 url로 받기 위해 dynamic api route와 관련하여 참고했으며, svg를 export하기 위해 header정보를 바꿔주는 정도의 테크닉이 필요했습니다. svg로 export하면 api를 사용하여 불러오면 image로 변환됩니다.
export default async function handler(req, res) {
const { userId } = req.query;
const result = await get_info(userId[0]); // 사용자 정보
const userName = result["userName"];
res.status(200);
res.setHeader("Content-Type", "image/svg+xml");
res.send(`<svg></svg>`) // svg 코드
}
그 외에 svg 코드는 텍스트로 만들어야 하는데, 이렇게 api를 만들면 아이콘 이미지를 불러오는 시간이 오래걸려 배지가 만들어지지 않았습니다. 그래서 좀 더 정보를 쉽게 가져오기 위해 svg/png 형태의 icon을 base64로 인코딩하여 text 정보로 불러와 사용했습니다. 그 외에는 html/css의 휴리스틱한 거리계산을 통해 디자인 개선 작업의 반복이었습니다.
완성본
최종적으로 크게는 2개의 유형의 배지를 완성했고, 결과물 예시는 다음과 같습니다.
처음에는 다크모드만 만들려했으나, 이슈로 요청이 있어 라이트모드도 만들었습니다.
홍보
저는 토이프로젝트의 끝은 적합한 홍보라고 생각합니다. 총 4군데에 홍보하였습니다.
- 캐글(Kaggle) : 일차적으로 국내에는 액티브한 캐글 사용자가 많이 없기 때문에
- 레딧(Reddit) : 캐글 디스커션은 불충분할 것 같아 해외 커뮤니티인 레딧에도 올렸습니다. 생각보다 캐글 채널이 작아 큰 홍보효과는 얻지 못했으나 그랜드마스터의 댓글과 좋아요로 나름의 홍보 효과를 얻긴 했습니다.
- 캐글코리아 페이스북 커뮤니티 / 오픈카카오톡방 : 국내에서 가장 큰 캐글 커뮤니티이자, 제가 운영진으로도 있기에 홍보 했습니다.
- 트위터(Twitter) : 제가 직접 홍보한 내용은 아니고, 다른 네임드 캐글 유저가 어딘가에서 제 레포를 보고 홍보를 해주셨습니다. 80여개의 좋아요를 받은 것을 보아 매우 큰 홍보효과가 아니었나 싶습니다.
마치며...
코드가 완성형이 아니기에 사용방법만 따로 레포를 만들어 공개했고, 3번의 주말동안 작업한 내용과 홍보로 100 stars를 달성할 수 있었습니다. 현재 모바일에서 원하는대로 배지가 나오지 않아 조금의 수정이 더 필요하긴 하여 다음 주에도 추가적으로 더 작업할 예정입니다.
시작하는 방법이 소개된 글들이 없어서 그렇지, 배지는 가장 쉬운 웹 토이프로젝트입니다. 이 글을 통해 많은 초심자분들이 재미있는 배지 프로젝트를 시작해보시면 좋겠습니다.
다음 토이프로젝트는 어떤 걸로 할지 또 고민해봐야겠습니다. 🤔