워드프레스 REST API로 자동 발행할 때 인증과 레이트리밋 정리

워드프레스 REST API로 글을 자동 발행하는 스크립트를 돌렸는데 갑자기 401이나 403이 뜬다면 원인이 뭘까요? 대부분은 인증 방식이 애플리케이션 비밀번호로 넘어가지 않았거나, 짧은 시간에 요청을 반복해서 서버 쪽에서 요청을 막은 경우입니다. 이 글에서는 워드프레스 5.6 이상을 기준으로 REST API 인증을 세팅하는 방법과, 자동으로 발행할 때 429 응답을 받으면 어떻게 재시도해야 안전한지 정리합니다. XML-RPC 대신 REST API로 … Read more

LLM에게 SQL을 생성시켰다가 털린 사례, 인젝션 막는 실전 가드

LLM에게 SQL을 생성시켰다가 회사 데이터베이스가 통째로 털렸다는 이야기, 정말 가능한 일일까요? 네, 가능합니다. 자연어 질문을 SQL로 바꿔주는 text-to-SQL 기능을 앱에 붙이는 순간, 사용자 입력이 LLM을 거쳐 실행 가능한 쿼리로 둔갑하는 새로운 인젝션 경로가 하나 더 생기기 때문입니다. 이 글에서는 LLM이 만든 SQL을 검증 없이 실행했을 때 실제로 어떤 경로로 뚫리는지, 그리고 파라미터 바인딩·권한 최소화·화이트리스트 검증으로 … Read more

파이썬 로깅에 traceback이 안 찍힐 때, exc_info부터 확인해 보세요

파이썬 로깅에 traceback이 안 찍혀서 당황했던 코드를 그대로 재현해 보면 원인은 거의 항상 한 가지로 좁혀집니다. except 블록 안에서 logging.error()를 호출하면서 exc_info 인자를 빠뜨린 경우입니다. 아래 코드를 그대로 실행해 보면, 예외 메시지 한 줄만 로그에 찍히고 정작 어디서 터졌는지 알려주는 traceback은 통째로 사라진다는 걸 확인할 수 있습니다. 이 글은 파이썬 3.8~3.12, 표준 라이브러리 logging 모듈 … Read more

requests에서 httpx로 옮길 때 진짜 달라지는 것들

“requests에서 httpx로 옮기면 코드가 얼마나 바뀔까요?” 검색창에 이렇게 쳐보신 적 있으실 텐데요, 정답은 “API는 거의 그대로지만 기본 동작 몇 가지가 조용히 달라진다”예요. 특히 타임아웃 기본값과 리다이렉트 처리 방식을 모르고 옮기면, 멀쩡하게 돌던 코드가 운영 환경에서 갑자기 예외를 던지는 경우가 생겨요. 이 글에서는 실제로 코드 동작이 달라지는 지점만 골라서, 조건과 예외 상황까지 함께 짚어볼게요. 먼저 전체 … Read more

Playwright로 로그인 세션을 재사용할 때, 쿠키 저장과 만료 감지부터 챙기세요

Playwright로 로그인 세션을 재사용할 때 가장 먼저 부딪히는 문제는 storageState()로 저장한 쿠키 파일을 그대로 믿어버리는 것입니다. 쿠키에는 만료 시각이 분명히 남아있지만, Playwright는 그 세션이 서버 쪽에서 이미 무효화됐는지까지는 알려주지 않습니다. 이 글에서는 로그인 세션을 저장하고 재사용할 때 실제로 쓰는 코드와, 파일 안의 만료 시각을 직접 검사하는 방법, 그리고 검사를 건너뛰면 어떤 일이 생기는지를 순서대로 정리합니다. … Read more

LLM 스트리밍 응답에서 토큰 수를 실시간으로 세는 법

LLM 스트리밍 응답에서 토큰 수를 실시간으로 확인하려면 전체 답변이 끝날 때까지 기다렸다가 한 번에 세야 한다고 생각하시는 분이 많은데요, 실제로는 응답이 오는 도중에도 토큰 수를 계속 누적해서 셀 수 있습니다. 방법은 크게 두 가지로 나뉘는데요, 클라이언트에서 토크나이저로 직접 세는 방식과 API가 스트림 중간이나 마지막에 내려주는 사용량 필드를 그대로 읽는 방식입니다. 어떤 모델과 SDK를 쓰느냐에 따라 … Read more

정적 파일 CDN 캐시가 배포 후에도 안 바뀌는 이유와 헤더 해결법

결론부터 말씀드리면, 정적 파일 CDN 캐시가 배포 후에도 그대로 남아있는 문제는 대부분 응답 헤더의 max-age 값과 CDN 엣지 캐시가 아직 만료되지 않았기 때문에 생깁니다. 파일 성격에 맞춰 Cache-Control을 다르게 설정하고, 배포 스크립트에 CDN 캐시 무효화 호출을 넣으면 대부분 해결됩니다. 이 글에서는 캐시가 안 바뀌는 구조적 원인부터, 실제로 쓸 수 있는 헤더·무효화 설정, 그리고 설정을 고쳐도 … Read more

Alembic 마이그레이션이 프로덕션에서 실패했을 때, 되돌리는 순서

이 글에서는 Alembic 마이그레이션이 프로덕션에서 실패했을 때 무엇부터 확인하고 어떤 순서로 되돌려야 하는지를 정리합니다. 결론부터 말씀드리면, 스키마를 먼저 되돌리기 전에 애플리케이션 코드 롤백 여부와 alembic_version 테이블의 실제 상태부터 확인하는 게 순서입니다. 순서를 반대로 하면 스키마는 되돌렸는데 코드는 새 스키마를 기대하는 상태가 되어 장애가 더 커지는 경우가 많습니다. 이 내용은 Alembic 1.13 계열, SQLAlchemy 2.x, PostgreSQL … Read more

FastAPI 의존성 주입에서 DB 세션이 새는 이유, yield 패턴부터 점검하기

SQLAlchemy 커넥션 풀을 pool_size=5로 두고 운영하다가 로그에 QueuePool limit of size 5 overflow 10 reached, connection timed out이 찍히기 시작했다면, 원인은 거의 하나로 좁혀집니다. FastAPI 의존성 주입에서 만든 DB 세션이 요청이 끝난 뒤에도 반납되지 않고 계속 쌓이는 경우입니다. 이 글은 yield 패턴을 어떻게 써야 세션이 새지 않는지, 어떤 조건에서 그 원칙이 깨지는지를 실제 코드로 짚어 … Read more

LLM 응답을 임베딩과 함께 저장할 때 자주 나오는 스키마 실수

결론부터 말씀드리면, LLM 응답을 임베딩과 함께 저장할 때 나는 대부분의 문제는 임베딩 차원을 고정하지 않은 테이블 설계, 원본 응답과 임베딩 대상 텍스트를 한 컬럼에 몰아넣는 구조, 그리고 모델 버전 기록 누락에서 시작됩니다. 이 세 가지만 스키마 단계에서 잡아도 나중에 벡터 차원 불일치 에러나 검색 품질 저하로 테이블을 갈아엎는 일을 피할 수 있습니다. 아래에서는 PostgreSQL과 pgvector … Read more