네이버 클라우드 활동 [o]
3주 1일차 강의 [o]
네이버 클라우드 사수 도움 요청 업무 [o]
팀장님 지시 업무 [o]
중간/일일 업무 보고 작성 [o]
정기 팀/동기 스터디 모임 참석 및 성실도 [o]
컴퓨터의 뇌로, 중앙 처리 장치입니다.
CPU 클록 주파수
: CPU의 작업 처리 속도를 나타내며, 헤르츠(Hz) 단위로 측정됩니다. 클록이 높을수록 처리 속도가 빠릅니다.
멀티 코어
: 하나의 CPU 내에 여러 개의 처리 코어가 존재하여 동시에 여러 작업을 처리할 수 있습니다.
주 기억 장치로, 프라이머리 메모리라고도 합니다.
RAM 데이터 전송 속도
: RAM의 작업 처리 속도를 나타내며, CPU와 마찬가지로 Hz 단위로 측정됩니다.
SRAM
(Static RAM): 속도가 매우 빠르고, 비휘발성입니다. 주로 CPU 내부의 캐시 메모리로 사용됩니다.
DRAM
(Dynamic RAM): SRAM보다는 느리지만, 휘발성이며, 주로 메인 메모리로 사용됩니다.
하드웨어와 응용 프로그램 사이에서 중재자 역할을 하는 컴퓨터 시스템의 핵심 요소입니다.
예: macOS, Windows, Android, Linux 등
사용자가 특정 작업을 수행하기 위해 사용하는 소프트웨어 프로그램입니다.
예: 인스타그램, 파워포인트, 엑셀, 카카오톡 등
시스템 자원 관리
: CPU
, RAM
, DISK
등의 하드웨어 자원을 관리합니다.
응용 프로그램 관리
: 응용 프로그램의 실행과 권한을 관리합니다.
커뮤니케이션 지원
: 사용자 인터페이스(GUI)를 관리하여 사용자와 시스템 간의 상호작용을 돕습니다.
프로세스 내에서 동시에 진행되는 작업의 갈래로, 하나의 프로세스는 최소 하나 이상의 스레드(메인 스레드)를 가집니다.
싱글 스레드
: 하나의 메인 스레드만을 가지고 있습니다.
멀티 스레드
: 메인 스레드 외에 여러 개의 차일드 스레드를 가지고 있어, 복잡한 작업을 효율적으로 처리할 수 있습니다.
프로세스
: 실행 중인 프로그램으로, 운영체제로부터 자원을 할당받은 작업의 단위입니다.
스레드
: 프로세스가 할당받은 자원을 이용하여 실행되는 작업의 흐름입니다. 프로세스 내에서 여러 스레드가 메모리를 공유하며 동작할 수 있습니다.
부족한 점 : CORS 설정에 대해서 아직 부족한 지식
스스로 시도해본 것들 : wordSearch라는 웹 퍼즐게임의 서버단을 구성해봤다.
(주차별 과제로 주어졌고 Svelte를 사용해 클라이언트 부분도 작성)
과제를 위한 간단한 DB 작성
회원가입 페이지 작성
로그인 페이지 작성
Game 정보를 전송하는 페이지 작성
from fastapi import FastAPI, Request, WebSocket
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, EmailStr
from typing import List
import mysql.connector
import hashlib
import jwt
import datetime
secret_key = "mysecretkey"
# MySQL 연결 설정
db = mysql.connector.connect(
host="localhost", user="root", password="1111", database="word_search"
)
class Signup(BaseModel):
nickname: str
email: EmailStr
password: str
class Login(BaseModel):
email: EmailStr
password: str
class Signin(BaseModel):
email: EmailStr
password: str
class GameInfo(BaseModel):
title: str
description: str
words: List[str]
accessToken: str
class UpdateGameInfo(BaseModel):
url: str
gameId: int
class VerifyWord(BaseModel):
gameId: int
word: str
app = FastAPI()
# CORS 설정
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["GET", "POST", "DELETE", "PUT"],
allow_headers=["*"],
)
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
# 클라이언트로부터 메시지 수신
data = await websocket.receive_text()
print(f"Received message from client: {data}")
# 메시지를 다시 클라이언트에게 전송
await websocket.send_text(f"Message received: {data}")
async def generateJWT(email, user_id):
# 현재 시간을 UTC 기준으로 가져오기
now_utc = datetime.datetime.now(datetime.timezone.utc)
# 만료 시간 설정 (현재 시간에서 1주일 후로 설정)
expiration_time = now_utc + datetime.timedelta(weeks=1)
payload = {"email": email, "user_id": user_id, "exp": expiration_time}
token = jwt.encode(payload, secret_key, algorithm="HS256")
print("token", token)
return token
def is_email_duplicate(email: str) -> bool:
cursor = db.cursor()
cursor.execute("SELECT COUNT(*) FROM users WHERE email = %s", (email,))
count = cursor.fetchone()[0]
return count > 0
async def find_users_by_email(email: str):
cursor = db.cursor()
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
result = cursor.fetchone()
if result:
user_info = {
"id": result[0],
"email": result[1],
"password": result[2],
"nickname": result[3],
}
return user_info
else:
return None
async def hash_password(password: str):
return hashlib.sha256(password.encode()).hexdigest()
async def verify_token(token: str):
decode_token = jwt.decode(token, secret_key, algorithms=["HS256"])
return decode_token["user_id"]
@app.get("/ping")
async def ping():
return {"message": "pong"}
@app.post("/signup")
async def signup(request: Request, user: Signup):
if is_email_duplicate(user.email):
return JSONResponse(content={"detail": "Email already exists"}, status_code=400)
hashed_password = await hash_password(user.password)
cursor = db.cursor()
try:
cursor.execute(
"INSERT INTO users (email, password, nickname) VALUES (%s, %s, %s)",
(user.email, hashed_password, user.nickname),
)
db.commit()
return JSONResponse(
content={"message": "User created successfully"}, status_code=201
)
except mysql.connector.Error as err:
return JSONResponse(content={"error": str(err)}, status_code=500)
@app.post("/signin")
async def signin(request: Request, user: Signin):
try:
hashed_password = await hash_password(user.password)
find_users = await find_users_by_email(user.email)
if find_users and hashed_password == find_users["password"]:
access_token = await generateJWT(find_users["email"], find_users["id"])
return JSONResponse(
content={
"message": "User Login successfully",
"access_token": access_token,
},
status_code=200,
)
else:
return JSONResponse(
content={"error": "Invalid email or password"}, status_code=401
)
except mysql.connector.Error as err:
return JSONResponse(content={"error": str(err)}, status_code=500)
@app.post("/save_game_info")
async def save_game_info(game_info: GameInfo):
cursor = db.cursor()
try:
user_id = await verify_token(game_info.accessToken)
# 게임 정보를 games 테이블에 저장
cursor.execute(
"INSERT INTO games (title, description ,create_user_id) VALUES (%s, %s ,%s)",
(game_info.title, game_info.description, user_id),
)
db.commit()
# 새로 생성된 게임의 id 가져오기
game_id = cursor.lastrowid
# 게임의 단어들을 words 테이블에 저장
for word in game_info.words:
cursor.execute(
"INSERT INTO words (word, game_id) VALUES (%s, %s)", (word, game_id)
)
db.commit()
game_url = f"http://localhost:5173/#/game/{game_id}"
return JSONResponse(
content={
"message": "Game information saved successfully",
"game_url": game_url,
},
status_code=200,
)
except mysql.connector.Error as err:
db.rollback()
return JSONResponse(content={"error": str(err)}, status_code=500)
@app.put("/update_game_info_for_url")
async def update_game_info_for_url(update_game_info: UpdateGameInfo):
cursor = db.cursor()
try:
cursor.execute(
"UPDATE games SET url = %s WHERE id = %s",
(update_game_info.url, update_game_info.gameId),
)
db.commit()
return JSONResponse(content={"message": "Updated game URL"}, status_code=201)
except mysql.connector.Error as err:
return JSONResponse(content={"error": str(err)}, status_code=500)
@app.get("/get_game_info/{gameId}")
async def get_game_info(gameId: int):
cursor = db.cursor(dictionary=True)
try:
# Fetch game info and related words using a JOIN query
cursor.execute(
"""
SELECT games.id, games.title, games.description, games.create_user_id, games.url,
games.created_at, words.id as word_id, words.word
FROM games
LEFT JOIN words ON games.id = words.game_id
WHERE games.id = %s
""",
(gameId,),
)
# Extract game information and words from the result set
game_info = {}
for row in cursor.fetchall():
if not game_info:
game_info = {
"id": row["id"],
"title": row["title"],
"description": row["description"],
"create_user_id": row["create_user_id"],
"url": row["url"],
"created_at": str(row["created_at"]),
"words": [],
}
if row["word_id"] is not None:
game_info["words"].append({"id": row["word_id"], "word": row["word"]})
# Return JSON response
if game_info:
return JSONResponse(
content={
"message": "Game information is available",
"game_info": game_info,
},
status_code=200,
)
else:
return JSONResponse(
content={"message": "Game information is not available"},
status_code=404,
)
except mysql.connector.Error as err:
return JSONResponse(content={"error": str(err)}, status_code=500)
해결 내용 : python에서 CORS 설정에 대해서 구글링 후 설정하는 법 학습 후 구현
알게된 점 : FastAPI에서 지원하는 다양한 라이브러리에 대해 알게 됨(EmailStr , JSONResponse 등)
헷갈리거나 실수한 점 : python을 사용해보면서 제일 많이 실수하는 부분은 아무래도 들여쓰기가 아닌가 싶다..
회고 : 이제 슈퍼코딩에서 진행하는 3주차에 들어섰는데,
주특기에 관련되어 백엔드에 대해 깊게 알 수 있을거 같아 기대된다.
내일은 과제에서 구글 소셜 로그인을 진행해보려 한다.