Python 16

curl_cffi 도입기: 웹 스크래핑 문제 해결하기

웹 검색 AI 에이전트 개발하면서 검색 데이터 수집할 때 자주 마주치는 문제가 있다. 사이트들이 점점 더 스크래핑을 막는 기술을 도입하면서 requests, aiohttp 같은 기본 HTTP 클라이언트로는 자꾸 403, 429 에러가 뜨는 상황.문제 상황기존에 써오던 HTTP 클라이언트들로는 이런 문제가 생겼다:403 Forbidden, 429 Too Many Requests 같은 오류 계속 발생Cloudflare 같은 보안 솔루션이 적용된 사이트에서 CAPTCHA가 뜸User-Agent 설정해도 스크래핑 방지 우회 안 됨자바스크립트로 동적 생성되는 콘텐츠는 아예 접근 불가이런 문제는 AI 에이전트가 정확한 정보를 제공하는 능력에 직접적인 영향을 줬다.브라우저 지문(Browser Fingerprintin..

Python 2025.05.11

Python asyncio와 anyio 비교

Python asyncio와 anyio 비교asyncio란?asyncio는 Python 3.4부터 표준 라이브러리에 포함된 비동기 프로그래밍을 위한 라이브러리. async/await 구문을 사용하여 I/O 작업이 많은 코드를 효율적으로 실행할 수 있게 해줌.간단히 말해, asyncio는 한 작업이 I/O(네트워크 요청, 파일 읽기/쓰기 등)를 기다리는 동안 다른 작업을 수행할 수 있게 해주는 도구.anyio란?anyio는 asyncio나 trio 위에서 동작하는 호환성 라이브러리. 이는 동일한 코드가 어떤 비동기 백엔드(asyncio 또는 trio)를 사용하든 작동할 수 있게 해줌. anyio는 trio에서 영감을 받은 사용하기 쉬운 API를 제공하면서도 asyncio와의 호환성을 유지.쉽게 말해, an..

Python/etc 2025.04.26

Python - 이벤트 루프

Python Asyncio의 이벤트 루프 이해하기Python에서 비동기 프로그래밍을 구현할 때 핵심이 되는 이벤트 루프(Event Loop)에 대하여 설명한다. 이벤트 루프는 모든 asyncio 응용 프로그램의 중심 메커니즘으로, 비동기 태스크들을 효율적으로 관리하고 실행하는 역할을 한다.개요: 이벤트 루프가 필요한 이유파이썬으로 개발 시 웹 페이지 여러 개를 다운로드하거나, API 요청을 동시에 보내야 하는 경우가 발생한다. 이러한 I/O 작업은 대기 시간이 길어서 순차적으로 처리하면 시간이 과도하게 소요된다. 이벤트 루프는 이런 작업들을 효율적으로, 마치 동시에 처리하는 것처럼 관리해준다.1. 이벤트 루프의 개념과 동작 원리개념이벤트 루프는 간단히 말해 실행할 작업들을 관리하는 관리자라고 볼 수 있다..

Python 2025.04.20

Python thread

Python의 Threading과 ThreadPoolExecutor 비교Python에서 동시성 구현할 때 필요한 두 가지 중요한 도구인 threading 모듈과 concurrent.futures 모듈의 ThreadPoolExecutor 클래스에 대하여 설명한다. 이 두 도구는 각각 다른 특징과 사용 목적을 가지고 있으며, 적절한 상황에서 활용할 때 최적의 성능을 얻을 수 있다.개요: 스레드가 필요한 이유파이썬으로 개발 시 웹 페이지 여러 개 다운로드하거나, 여러 파일 동시 처리하거나, API 요청 동시에 보내야 하는 경우가 발생한다. 이러한 I/O 작업은 대기 시간이 길어서 순차적으로 처리하면 시간이 과도하게 소요된다. 이러한 경우 동시성(Concurrency) 구현이 필요하며, 본 문서에서는 그 방법 ..

Python 2025.04.20

Pytest 기본 사용법

Pytest 기본 사용법1. 테스트 실행 기본 명령어기본 실행pytest tests상세 출력 옵션pytest -v # 상세한 테스트 결과 출력pytest -s # print 문 출력 보기pytest -sv # 상세 결과 + print 문 출력pytest -k "test_name" # 특정 이름을 포함한 테스트만 실행2. 테스트 순서 관리 (pytest-order)설치pip install pytest-order사용법import pytest@pytest.mark.order(1) # 첫 번째로 실행def test_first(): pass@pytest.mark.order(-1) # 마지막으로 실..

Python/FastAPI 2025.03.02

FastAPI 문제 해결 - BaseModel

문제: pydantic - BaseModel 사용 시 int로 설정 후 큰값을 넣으면 ex)660273741208465277 JSON으로 변환하는 과정에서 660273741208465300으로 반올림되면서 들어가짐원인: Pydantic의 BaseModel은 기본적으로 Python의 int 타입을 사용하지만, JSON으로 변환할 때 JavaScript의 Number 타입으로 변환되며, 이 타입은 2^53 - 1 (즉, 9007199254740991) 이상의 정수를 정확하게 표현할 수 없기 때문에 큰 정수가 손실되거나 반올림되는 문제가 발생함.해결 방법: 큰 정수를 처리하기 위해 Pydantic의 BaseModel에서 Decimal 타입을 사용하거나, JSON 변환 시 json.dumps()의 default..

Python/FastAPI 2025.03.02

Django FBV vs CBV

Django FBV vs CBVFBV CBV 차이FBV(Function Based View)장점구현이 간단함읽기 편함직관적인 코드데코레이터 사용이 간단함단점확장 / 재사용이 힘듬CBV(Class Based View)장점확장에 용의(재사용)다중 상속 Mixin등 사용 가능HTTP Method가 클래스 안에서 나누어 처리강력한 Generic Class View 가 있음단점읽기 어려움(코드 흐름이 암시적)상속되고 믹스되면서 코드 이해를 위해 찾아다녀야함데코레이터 사용시 별로도 import 하거나 Method 생성

Django Image Upload

Django에서 Image UploadPOST요청을 통해 Vue.js에서 Django로 이미지 전송.기본 세팅settings.py에서 아래 추가MEDIA_URL = '/api/' # 기본 api url을 통일 시켜 번거로움을 줄이기 위해 /api/로 설정했음MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 이미지 파일이 저장되는 기본 위치를 media폴더로 설정이미지 url도 다른 application과 같이 api로 시작하게 만들기 위해 MEDIA_URL을 /api/로 설정urls.pyfrom django.contrib import adminfrom django.urls import path, includefrom django.conf.urls.static import..

Django REST Framework

Django Rest Framework(DRF)1. REST API(DRF: Django Rest Framework)REST API를 활용하면 백 엔드와 프론트 엔드 분리가 쉽고 코드의 재활용성이 좋다.REST API를 사용하기 위해서 먼저 설치가 필요$ pip install djangorestframeworksettings.py에서 INSTALLED_APPS에 'rest_framework'추가app 폴더에 serializers.py 파일을 만들고 내용 추가# serializers.pyfrom rest_framework import serializersfrom .models import * #필요한 모델이름 넣어주기class Serializer(serializers.ModelSerializer): ..

Django M:N

Django M:N modelDjango에서 좋아요 기능이나 팔로우 기능처럼 M:N 관계 만들기ManyToManyField 이용좋아요 기능을 위한 model 추가(게시글 모델) # 좋아요 기능을 위한 article_like_users 테이블 생성class 좋아요 기능을 추가할 클래스 명: like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_articles') # 팔로우 기능을 위한 팔로우 기능을 위한 model 추가(User 모델을 Customizing)class User(AbstractUser): followers = models.ManyToManyField(settings.AUTH_USER_MODE..