inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

4주 2회차 과제

해결됨

[매일 완독 챌린지] 저자와 함께하는 <FastAPI로 기획에서 출시까지>

안녕하세요. 과제를 잘 못 이해한건가 싶기도 하지만 아래와 같은 조건하에 구현을 해 봤습니다. 수업 과정에서 Front-end는 고정인 상황이기 때문에 기존 API는 변경이 없다는 가정하에 변경 해 봤습니다. 시간대1개와 요일n개의 설정이 하나의 row로 묶여있는 상태로는 요일별 시간대 변동에 대응하기 까다로운 것 같아 요일별 개별 row로 저장하도록 일부 수정 하였습니다. API endpoint 모델 변경을 피하기 위해서 내부적으로 여러개의 요일별 row로 나누어 저장하도록 했습니다. 고민중에 작가님께서 올려 놓으신 레퍼런스 코드를 봤는데, 책에서 언급하신 것 처럼 postgres 경우와 sqlite 경우로 코드가 분기 되는 것을 보았고, 지금은 교육 과정이기 때문이라고 생각 하지만 배포 코드와 개발 환경 코드가 다른것은 여러모로 좋지 않은 것 같아 현재는 sqlite 기준으로 개별 DB구현에서만 지원하는 것은 배제하는 방향으로 구현 했습니다. 1과 같이 변경 함으로써, 기 등록된 정보의 수정에서는 개별 날짜 별 시간대 설정 면에서 자유도가 생겼다고 생각 됩니다. 타임슬롯의 변경과 삭제에 관해서는 내부적으로는 time-slot으로 관리하지만, 외부공개 id는 아니므로, 키 로서 start-time, end-time, weekday (API형태로서는 리스트)조합으로 정의 해서 동작 하도록 구현했습니다. 특히 삭제의 경우는 부득이 delete method의 경우는 payload가 포함되는것이 받아들여지지 않는 경우도 있는것을 고려해서, 새 등록 값 두가지(new_start_time과, new_end_time) 값이 모두 제공되고 같은 경우를 특정하여 삭제 동작으로 정의하여 동작하도록 구현했습니다. class TimeSlotUpdateByGroupIn(SQLModel): start_time: time end_time: time weekdays: Weekdays new_start_time: time | None = None new_end_time: time | None = None new_weekdays: Weekdays | None = None @model_validator(mode="after") def check_update_fields(self): update_fields = { "new_start_time": self.new_start_time, "new_end_time": self.new_end_time, "new_weekdays": self.new_weekdays, } if not any(value is not None for value in update_fields.values()): raise ValueError("최소 하나의 수정 필드는 반드시 제공되어야 합니다.") return self @router.post("/time-slots", status_code=status.HTTP_201_CREATED, response_model=TimeSlotOut) async def create_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotCreateIn, ) -> TimeSlotOut: if not user.is_host: raise GuestPermissionError() weekdays = sorted(set(payload.weekdays)) # dup. check with already exist one stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(weekdays), TimeSlot.start_time < payload.end_time, TimeSlot.end_time > payload.start_time, ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=payload.start_time, end_time=payload.end_time, weekday=weekday, ) for weekday in weekdays ] session.add_all(time_slots) await session.commit() if not time_slots: raise TimeSlotOverlapError() return TimeSlotOut( start_time=time_slots[0].start_time, end_time=time_slots[0].end_time, weekdays=weekdays, created_at=time_slots[0].created_at, updated_at=time_slots[0].updated_at, ) @router.get( "/time-slots/{host_username}", status_code=status.HTTP_200_OK, response_model=list[TimeSlotOut], ) async def get_host_timeslots( host_username: str, session: DbSessionDep, ) -> list[TimeSlotOut]: stmt = ( select(User) .where(User.username == host_username) .where(User.is_host.is_(true())) ) result = await session.execute(stmt) host = result.scalar_one_or_none() if host is None or host.calendar is None: raise HostNotFoundError() stmt = select(TimeSlot).where(TimeSlot.calendar_id == host.calendar.id) result = await session.execute(stmt) time_slots = result.scalars().all() grouped: dict[tuple[time, time], TimeSlotOut] = {} for time_slot in time_slots: key = (time_slot.start_time, time_slot.end_time) if key not in grouped: grouped[key] = TimeSlotOut( start_time=time_slot.start_time, end_time=time_slot.end_time, weekdays=[time_slot.weekday], created_at=time_slot.created_at, updated_at=time_slot.updated_at, ) continue grouped[key].weekdays.append(time_slot.weekday) if time_slot.created_at < grouped[key].created_at: grouped[key].created_at = time_slot.created_at if time_slot.updated_at > grouped[key].updated_at: grouped[key].updated_at = time_slot.updated_at if not grouped: raise TimeSlotNotFoundError() for time_slot in grouped.values(): time_slot.weekdays = sorted(set(time_slot.weekdays)) return list(grouped.values()) @router.patch( "/time-slots", status_code=status.HTTP_200_OK, response_model=TimeSlotOut | None, ) async def update_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotUpdateByGroupIn, ) -> TimeSlotOut | None: if not user.is_host: raise GuestPermissionError() current_weekdays = sorted(set(payload.weekdays)) stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.start_time == payload.start_time, TimeSlot.end_time == payload.end_time, ) ) result = await session.execute(stmt) current_slots = result.scalars().all() if not current_slots: raise TimeSlotNotFoundError() existing_weekdays = sorted({slot.weekday for slot in current_slots}) if existing_weekdays != current_weekdays: raise TimeSlotNotFoundError() delete_only = ( payload.new_start_time is not None and payload.new_end_time is not None and payload.new_start_time == payload.new_end_time ) if delete_only: current_ids = [slot.id for slot in current_slots] await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) await session.commit() return None new_start_time = payload.new_start_time or payload.start_time new_end_time = payload.new_end_time or payload.end_time new_weekdays = sorted(set(payload.new_weekdays or payload.weekdays)) if new_start_time >= new_end_time: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="시작 시간은 종료 시간보다 빨라야 합니다.", ) current_ids = [slot.id for slot in current_slots] stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(new_weekdays), TimeSlot.start_time < new_end_time, TimeSlot.end_time > new_start_time, TimeSlot.id.not_in(current_ids), ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) new_time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=new_start_time, end_time=new_end_time, weekday=weekday, ) for weekday in new_weekdays ] session.add_all(new_time_slots) await session.commit() return TimeSlotOut( start_time=new_start_time, end_time=new_end_time, weekdays=new_weekdays, created_at=new_time_slots[0].created_at, updated_at=new_time_slots[0].updated_at, )

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
Green Lee 댓글 1 좋아요 0 조회수 65

IMG - JSON 병 및 ID추가에서 ID가 추가가 안됩니다.

해결됨

원클릭으로 AI가 생성해주는 Youtube 쇼츠 만들기 자동화(with n8n)

merged["ID"] = _('IMG - 시트 행 가져오기').first(). json.ID 이부분에서 = 뒤로 지우고 IMG 시트 행 가져오기에서 ID를 드래그엔 드롭했을때 강사님처럼 아이디가 입력이 안되는데 이유가 뭘까요? 일단은 복사 붙여넣기로 진행했는데 궁금해서 질문 남깁니다.

  • python
  • youtube-api
  • n8n
  • ai-활용-(ax)
적성비 댓글 2 좋아요 0 조회수 76

2.4 Self-RAG 결과가 달라요!

해결됨

LangGraph를 활용한 AI Agent 개발 (feat. MCP)

해당 강의 8:10처럼 동일하게 돌렸을 때 다음과 같이 출력이 찍힙니다. 624만원에 관한 정보는 나오지 않습니다. ㅠㅠ 여러번 돌려도 계속 그렇게 나오네요 .. 어떤 문제일까요?, 혹시나 DB에 문서를 적재하는 과정중에서 55조의 테이블이 씹힌건가? 해서 document_list 찍었을땐 (적재 전 txt 파일을 로딩하는과정에서) 또 624만원에 관련된 내용이 있습니다... 출력내용이 길어 10000자가 넘어 마지막 answer만 올려드립니다. document answer == {'answer': AIMessage(content='연봉 5천만 원인 거주자의 소득세는 근로소득공제를 적용하여 계산됩니다. 총급여액 5천만 원의 경우, 근로소득공제는 1천200만 원+(4천500만 원을 초과하는 금액의 100분의 5)입니다. 따라서, 소득세는 해당 공제를 적용한 과세표준에 세율을 적용하여 계산하게 됩니다. 하지만 세율 정보가 없으므로 정확한 소득세 금액을 계산할 수 없습니다. ++ 다른 테이블은 context로 찍히는데 55조 624만원 관련 테이블만 안찍힙니다..

  • 프롬프트엔지니어링
  • llm
  • ai-agent
  • langgraph
  • mcp
박수용 댓글 2 좋아요 0 조회수 105

강의 보다가 궁금한점 남깁니다.

해결됨

100% 비개발자 바이브 코딩: 앱 200개로 월 140만 수익 노하우

안녕하세요. 좋은 강의 감사합니다. 강의를 듣다 몇가지 의문이 있어 글을 작성합니다. 애드몹 광고는 비공개 테스트시에도 적용을 해야하나요. 비공개 테스트시에도 애드몹광고를 추가한 상태에서 진행해야하나요? 비공개 테스트가 완료된 상태에서 애드몹광고를 추가하고 출시가 가능한가요? 비공개 테스트시에는 애드몸광고를 넣지않고 앱을 개시할때 추가해도되나요 애드몹 공고로 등록한 모바일 폰은 비공개 테스트 시 12개중한개의 모바일폰에 포함되나요.

  • python
  • flutter
  • chatgpt
  • claude
  • 바이브코딩
이승섭 댓글 1 좋아요 2 조회수 142

patch 요청시 payload가 넘어가지 않습니다.

해결됨

[매일 완독 챌린지] 저자와 함께하는 <FastAPI로 기획에서 출시까지>

아래 두 요청 코드에서 patch 요청 시 payload가 엔드포인트 함수에서 None으로 잡혀 model_dump()에서 오류가 발생합니다. 원인을 잘 모르겠습니다. [오류] [요청 코드] @pytest.mark.parametrize("payload", [ {"display_name": "푸딩캠프"}, {"email": "hannal@example.com"}, {"display_name": "푸딩캠프", "email": "hannal@example.com"}, ]) async def test_사용자가_변경하는_항목만_변경되고_나머지는_기존_값을_유지한다( client_with_auth: TestClient, # 인증을 받은 클라이언트 payload: dict, # 클라이언트 요청 페이로드 host_user: User, # 클라이언트 사용자 ): # 현재 사용자 정보를 보관한다. before_data = host_user.model_dump() response = client_with_auth.patch("/account/@me", json=payload) # (...) async def test_비밀번호_변경_시_해싱_처리한_비밀번호가_저장되어야_한다( client_with_auth: TestClient, host_user: User, db_session: AsyncSession, ): before_data = host_user.hashed_password payload = { "password": "new_password", "password_again": "new_password", } response = client_with_auth.patch("/account/@me", json=payload) # (...) [엔드포인트] @router.patch("/@me", response_model=UserDetailOut) async def update_user( user: CurrentUserDep, session: DbSessionDep, payload: UpdateUserPayload = Body(...), ) -> User: updated_data = payload.model_dump(exclude_none=True, exclude={"password", "password_again"}) stmt = update(User).where(User.id == user.id).values(**updated_data) await session.execute(stmt) await session.commit() await session.refresh(user) return user [스키마] class UpdateUserPayload(SQLModel): display_name: str | None = Field(default=None, min_length=4, max_length=40) email: EmailStr | None = Field(default=None, max_length=128) password: str | None = Field(default=None, min_length=8, max_length=128) password_again: str | None = Field(default=None, min_length=8, max_length=128) @model_validator(mode="after") def check_all_fields_are_none(self) -> Self: if not self.model_dump(exclude_none=True): raise ValueError("최소 하나의 필드는 반드시 제공되어야 합니다.") return self @model_validator(mode="after") def verify_password(self) -> Self: if self.password is not None or self.password_again is not None: # 둘 중 하나라도 들어오면 둘 다 있어야 함 if not self.password or not self.password_again: raise ValueError("비밀번호 변경 시 password와 password_again을 모두 제공해야 합니다.") if self.password != self.password_again: raise ValueError("비밀번호가 일치하지 않습니다.") @computed_field @property def hashed_password(self) -> str | None: if self.password: return hash_password(self.password) return None [픽스처] @pytest.fixture(autouse=True) async def db_session(): dsn = "sqlite+aiosqlite:///:memory:" engine = create_async_engine(dsn) async with engine.begin() as conn: await conn.run_sync(SQLModel.metadata.drop_all) await conn.run_sync(SQLModel.metadata.create_all) session_factory = create_session(engine) async with session_factory() as session: yield session await conn.run_sync(SQLModel.metadata.drop_all) await engine.dispose() @pytest.fixture() def fastapi_app(db_session: AsyncSession): app = FastAPI() include_routers(app) async def override_use_session(): yield db_session app.dependency_overrides[use_session] = override_use_session return app @pytest.fixture() async def host_user(db_session: AsyncSession): user = account_models.User( username="puddingcamp", hashed_password=hash_password("testtest"), email="puddingcamp@example.com", display_name="푸딩캠프", is_host=True, ) db_session.add(user) await db_session.flush() await db_session.commit() return user @pytest.fixture() def client_with_auth(fastapi_app: FastAPI, host_user: account_models.User): payload = LoginPayload.model_validate({ "username": host_user.username, "password": "testtest", }) with TestClient(fastapi_app) as client: response = client.post("/account/login", json=payload.model_dump()) assert response.status_code == status.HTTP_200_OK auth_token = response.cookies.get("auth_token") assert auth_token is not None client.cookies.set("auth_token", auth_token) yield client

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
kyo lee 댓글 3 좋아요 0 조회수 79

run pod credit 관련 제보

미해결

[개정판] 딥러닝 컴퓨터 비전 완벽 가이드

저는 강사님의 refer & earn 주소로 runpod.io 사이트 열고, 영상에 나온 팝업창 누르고 구글 계정으로가입하고 10달러 결제까진 순조롭게 되었습니다....만 5달러는 안들어왔고 딱 결제한만큼 10달러만 있네요! 다른 분들은 어떻게... 추가로 5달러 받으셨는지 궁금합니다.

  • python
  • 머신러닝
  • 딥러닝
  • 컴퓨터-비전
limtony1 댓글 2 좋아요 0 조회수 156

강의 순서

해결됨

코딩 테스트 합격을 위한 리트코드 핵심 문제 풀이

강의 수강 방법에 대해서 질문이 있습니다. 저는 Blind75를 순서대로 풀고 있는데 강의 순서랑은 Blind75 순서랑 조금 다르더라구요 자료구조 알고리즘을 모르는 상태로 강의를 시작해도 되는지 1번과 연계되는 질문으로 일단 문제 풀이를 시도하되 한 문제당 어느정도의 시간을 두고 풀면 되는지 보통 10분 정도 고민해보고 정말 모르겠다면 문제풀이 강의를 바로 들어보는 편입니다. Blind75 순서대로 문제를 풀면서 풀지 못한 문제에 대해서만 강의를 시청하면 되는지 좋은 강의 만들어주셔서 감사합니다.

  • python
  • 코딩-테스트
  • 알고리즘
  • data-structure
shin jiun 댓글 1 좋아요 1 조회수 149

"pip install pykrx" 설치 내용 강의 누락

해결됨

챗GPT와 파이썬으로 주식 자동매매 앱 및 웹 투자 리포트 만들기

강의 내용 중에 "pip install pykrx" 이 부분에 대한 설명을 해 주신다고 했지만 나중에 VS CODE만 설명하시면서 실제로는 강의에서 빠져 있어서 기존 문의드린 오류가 난 게 아닌가 합니다. 느낌으로는 conda promp 상에서 실행하면 될 것 같은데 안되네요. "pip install pykrx" 를 어디에 설치해야 하나요? 아래 2곳에서는 안됩니다.

  • python
  • 재테크
  • streamlit
  • chatgpt
  • 프롬프트엔지니어링
xatron 댓글 2 좋아요 0 조회수 145

md vs txt 차이..

미해결

LangGraph를 활용한 AI Agent 개발 (feat. MCP)

안녕하세요. 강의 도중에 세법 pdf => 마크다운 변경후에 Spliiter로 분할하면, 표가 짤려서 답변이 생성이 잘 안될수도 있다고 하셔서 txt로 진행한다고 하셨는데.. 전 궁금한게 txt도 마차가지로 스플릿을 하더라도 짤리지 않나요..? text_spliters = RecursiveCharacterTextSplitter( chunk_size=1500, chunk_overlap = 100, separators=['\n\n','\n'] ) 청크사이즈가 1500 이니까 뭔가 표랑 경계선이 겹치게 되면 txt도 마찬가지 짤리는게 아닐까.. 생각이 들어서요

  • 프롬프트엔지니어링
  • llm
  • ai-agent
  • langgraph
  • mcp
km9311 댓글 2 좋아요 0 조회수 219

25강에서 items is not defined 오류가 납니다.

해결됨

원클릭으로 AI가 생성해주는 Youtube 쇼츠 만들기 자동화(with n8n)

25강에서 코드 실행할 때 items is not defined 오류가 발생합니다. 뭘 잘못 했을까요?

  • python
  • youtube-api
  • n8n
  • ai-활용-(ax)
윤종규 댓글 2 좋아요 0 조회수 99

OpenAI API 호출 때문에 발생하는 Error code: 429 문제

미해결

LangGraph를 활용한 AI Agent 개발 (feat. MCP)

gpt 유료 버전을 결제해야 하는 걸까요? 무료로는 불가능 할까요?

  • 프롬프트엔지니어링
  • llm
  • ai-agent
  • langgraph
  • mcp
댓글 2 좋아요 0 조회수 171

koa.exe 파일 부재

해결됨

챗GPT와 파이썬으로 주식 자동매매 앱 및 웹 투자 리포트 만들기

키움API 자료 받고 설치했는데 아래 이미지처럼 koastudios 파일 자체가 생성되질 않네요. 이 부분도 버전업에 따른 변경일까요?

  • python
  • 재테크
  • streamlit
  • chatgpt
  • 프롬프트엔지니어링
xatron 댓글 3 좋아요 0 조회수 129

19강에 있는 postgres account 계정 로그인이 안돼요

미해결

회사에서 바로 쓰는 업무자동화 AI 에이전트 (w. n8n, LangGraph)

비밀번호가 다른가.. 로그인이 안되네요

  • n8n
  • 인공지능(ai)
  • langchain
  • ai-활용-(ax)
  • langgraph
  • 카카오공채-개발
전민기 댓글 2 좋아요 0 조회수 107

20강 BGM 시트행추가하기 노드 만들때

해결됨

원클릭으로 AI가 생성해주는 Youtube 쇼츠 만들기 자동화(with n8n)

20강 BGM 시트행 추가하기 노드 만드는데 COLUMN 을 STATUS 로 VALUE 를 대기 OPTION 에서 return only first maching row를 선택했는데 첫번째 대기 외에도 나타나는거같습니다.. 왜그럴까요??

  • python
  • youtube-api
  • n8n
  • ai-활용-(ax)
깜자TV 댓글 3 좋아요 0 조회수 77

Creatomate에서 자동 캡션 질문입니다.

해결됨

원클릭으로 AI가 생성해주는 Youtube 쇼츠 만들기 자동화(with n8n)

자동 캡션에 쉼표, 물음표, 마침표 표시가 빠져있습니다. 첫번째 영상에는 있었습니다. 두번째는 없네요. 첫번째와 두번째는 다른 영상입니다. 어떻게 해야 쉼표, 물음표, 마침표를 붙일수 있나요?

  • python
  • youtube-api
  • n8n
  • ai-활용-(ax)
파란행복 댓글 1 좋아요 0 조회수 53

시간복잡도 개념문제 Deque질문

미해결

코딩 테스트 합격자 되기 - 4주완성

[ 질문 배경 ] Deque에 대한 자료를 보면 포인터를 사용한다고 나와있습니다. 따라서 popleft()시 맨 좌측부터 포인터가 가르키며 삭제하게 되는데, 이는 논리적으로 "삭제"라는 개념보다는 포인터가 가르키는 곳을 다음으로 이동시킨다는 의미를 가진다고 gpt를 통해 알게 되었습니다. [ 질문 ] 그렇다면, popleft()시 포인터가 다음으로 이동할 시 메모리에 적재되어 있던 이전 값은 그대로 남아있게 될텐데, 그렇다면 이것은 메모리 낭비로 이어질 수 있지 않나요? 자바의 경우 가비지 컬렉터가 알아서 메모리를 관리하죠. GPT에게 물어보니 메모리 슬롯은 유지하며 재사용할 수 있도록 대기상태에 들어간다고 합니다. 그렇다면 이 재사용을 할지 말지에 대한 것은 누가 결정하며 어떻게 처리되나요? 궁금합니다. C의 경우 malloc 으로 메모리 빌림 , 메모리 반납을 거치게 되는데, 이 경우도 궁금합니다.

  • python
  • 알고리즘
  • data-structure
  • 북-챌린지
태준 댓글 1 좋아요 0 조회수 78

Colab실습관련

미해결

파이썬을 활용한 머신러닝 딥러닝 입문

안녕하세요. 현재 회사 사무실에서 강의듣고 있는데, 일부 폐쇄망입니다. 그래서 Colab에서 실습 시 업로드 할 경우 아래 에러가 발생합니다. colab말고 다른방법은 없겟죠? A network error occurred and the request could not be completed. GapiError: A network error occurred and the request could not be completed.

  • python
  • 머신러닝
  • 딥러닝
  • pandas
  • numpy
  • keras
  • tensorflow
  • anaconda
  • matplotlib
  • cnn
최범준 댓글 2 좋아요 0 조회수 107

자료구조 구현에 관한 질문

미해결

코딩 테스트 합격자 되기 - 파이썬 편

안녕하세요 강의에서 스택 구현하기에서 직접 구현할 일은 없다고 말씀해주시는데 코딩인터뷰를 하게되면 보통 자료구조를 직접 구현하는 과정이 많더라구요 그런걸 생각했을때 자료구조를 구현해보는것도 필요하지 않을까요..?

  • python
  • 알고리즘
  • data-structure
chanwoo yang 댓글 2 좋아요 0 조회수 108

인기 태그

인프런 TOP Writers

주간 인기글