글

라벨이 API·운영인 게시물 표시

파이썬 JSON 설정 읽기: 중복 키와 NaN을 조용히 허용하지 않는 방법

JSON 설정의 중복 키는 object_pairs_hook으로, NaN·Infinity는 parse_constant로 거부하고 자료형 검증은 별도로 수행하세요. 확인일: 2026-10-24. Python 3.14 표준 라이브러리 예제입니다. Windows Python 3.14.4에서 합성 입력으로 로컬 실행과 assert 검사를 통과했습니다. 문법이 맞는데 설정값이 달라지는 이유는 무엇인가요? 같은 JSON 객체에 retry가 두 번 있으면 Python의 기본 디코더는 마지막 값을 남길 수 있습니다. 작성자가 의도하지 않은 값으로 설정이 바뀌어도 파싱 자체는 성공합니다. 이 글은 이미 읽은 사전에서 누락 키를 찾는 문제가 아니라, 사전으로 만들기 전에 중복 이름을 발견하는 문제를 다룹니다. 두 가지 훅은 각각 무엇을 검사하나요? object_pairs_hook은 각 JSON 객체의 이름·값 쌍 목록을 받아 객체로 바꿉니다. unique_object에서 이미 본 이름이 나오면 고정 메시지의 ValueError를 냅니다. 중첩 객체에도 적용됩니다. parse_constant는 NaN, Infinity, -Infinity 같은 비표준 숫자 표기를 만났을 때 거부하도록 설정합니다. 따옴표로 감싼 "NaN"은 평범한 문자열이므로 이 예제에서는 허용합니다. 합성 입력으로 정상과 오류를 나눕니다 아래 read_config는 최상위 값이 객체인지도 확인합니다. 정상 설정과 중첩 true 값을 읽은 뒤, 같은 객체의 중복 이름·중첩 중복·비표준 숫자 상수·최상위 배열·마지막 쉼표를 검사합니다. 일반 문법 오류의 JSONDecodeError도 ValueError의 하위 클래스라 같은 테스트에서 잡힙니다. 실제 회사 설정이나 외부 API는 읽지 않습니다. import json def unique_object(pairs): result = {} for key, value in pairs: if key in result: ...

파이썬 실행 로그에 비밀값을 넣지 않기: 허용 필드형 JSON 이벤트 만들기

원본 응답을 로거에 넘기지 말고, 허용한 작업명·실행 ID·상태·처리 건수만 검증해 기록하세요. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-23 확인. Windows Python 3.14.4에서 아래 합성 예제를 임시 작업 폴더로 실행해 assert와 예상 예외 검사를 통과했습니다. 실제 회사 파일·API·GUI는 실행하지 않았습니다. 문자열에서 비밀값을 지우기 전에 입력을 줄이세요 자동화 결과를 확인하려고 headers, 요청 URL, 응답 본문이나 설정 사전 전체를 출력하면 토큰·개인정보가 함께 기록될 수 있습니다. 이 글은 모든 패턴을 마스킹하는 필터 대신 기록할 데이터 자체를 적게 만드는 예제입니다. 원본 응답 객체를 함수가 받지 않게 하고, 결과 요약 이벤트만 새로 구성합니다. 이것만으로 프로그램의 모든 로그 경로가 안전해지는 것은 아닙니다. 허용 이벤트의 계약을 정의합니다 가상 작업명은 inventory_sync 또는 daily_report, 상태는 completed 또는 failed 중 하나입니다. processed는 bool이 아닌 0~1000000 정수이며, run_id는 영문 소문자·숫자·하이픈으로 된 1~40자 문자열입니다. 이 범위는 예제에서 정한 계약입니다. 정규식이 문자열의 비밀 여부를 판단하지는 못하므로 실행 ID에는 이메일·토큰을 재사용하지 말고 별도로 생성한 비민감 식별자를 넣어야 합니다. 직접 실행하는 최소 예제 import io import json import logging import re def make_event(*, job, run_id, status, processed): if job not in {"inventory_sync", "daily_report"}: raise ValueError("허용되지 않은 작업") if not isinstance(run_id, str) or re.fullmatch(r"...

파이썬 API 페이지 수집 종료 조건: 빈 페이지와 반복 커서 검사

API 문서가 정한 다음 페이지 신호로 종료를 판단하고, 이미 사용한 커서와 최대 페이지 수를 함께 검사해야 합니다. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-21 확인. Windows의 Python 3.14.4에서 아래 합성 예제를 임시 작업 폴더로 실행하고 assert 검사를 통과했습니다. 외부 서비스 호출이나 실제 회사 파일 처리는 실행하지 않았습니다. 적은 결과 수는 종료 신호와 같지 않습니다 업무용 API에서 페이지당 100개를 요청했는데 3개만 왔다고 반드시 마지막 페이지인 것은 아닙니다. Google의 AIP-158은 요청 수보다 적은 결과, 심지어 0개를 반환해도 후속 페이지가 있을 수 있다고 설명합니다. 따라서 해당 규약에서는 다음 페이지 토큰을 봐야 합니다. 모든 API가 이 규약을 쓰는 것은 아니며, 실제 엔드포인트 문서가 우선입니다. 가상 응답의 계약을 먼저 고정합니다 이 예제의 fetch_page(token)은 items 목록과 next_token 필드를 가진 사전을 반환합니다. 첫 요청은 None, 종료 신호도 next_token의 None으로 정했습니다. 비어 있지 않은 문자열은 다음 커서입니다. 이는 테스트용 내부 형식이며 Google이나 GitHub의 원래 응답 형식이 아닙니다. 실제 API의 누락 필드·빈 문자열 종료 규칙을 확인한 어댑터에서 이 형식으로 바꿔야 합니다. 직접 실행할 최소 예제 def collect_pages(fetch_page, max_pages=10): if type(max_pages) is not int or max_pages < 1: raise ValueError("max_pages는 양의 정수여야 합니다") token = None seen = set() result = [] for _ in range(max_pages): if token in seen: raise Runt...

API 키 저장 방법: 해싱과 암호화의 차이, Fernet 예제

외부 서비스 호출에 다시 사용할 API 키는 해시만 저장하면 안 됩니다. 원문이 필요한 키는 비밀 관리 서비스나 복호화 가능한 저장 방식을 사용하고, 들어온 키가 맞는지만 확인하는 서버 발급 키는 검증용 저장 방식을 설계해야 합니다. 먼저 API 키의 용도를 나누세요 용도 원문 복구 검토할 방식 외부 API에 인증 헤더로 전송 필요 비밀 관리 서비스 또는 키를 분리한 인증된 암호화 내 서비스가 발급한 키의 일치 여부 확인 보통 불필요 충분한 무작위성의 키 발급과 해시·HMAC 검증 설계 개발용 임시 키 필요 환경변수 등으로 코드에서 분리하고 저장소에 포함하지 않기 해싱은 암호화의 다른 이름이 아닙니다. 해시값을 외부 서비스의 원래 API 키 자리에 넣으면 인증되지 않습니다. 비밀번호용 반복 해시 설정을 API 키 전체에 일률적으로 적용하는 것도 적절하지 않습니다. 비밀번호와 고엔트로피 무작위 토큰은 위협 모델이 다릅니다. Fernet으로 암호화와 복호화 흐름 확인하기 다음은 Python 3 환경과 cryptography 패키지에서 흐름을 이해하기 위한 로컬 예제입니다. 설치는 python -m pip install cryptography 로 진행합니다. 예제는 실제 서비스 키를 사용하지 않으며, 운영용 키 보관 시스템 전체를 구현한 코드는 아닙니다. from cryptography.fernet import Fernet encryption_key = Fernet.generate_key() cipher = Fernet(encryption_key) sample_key = b"demo-key-not-for-production" ciphertext = cipher.encrypt(sample_key) restored = cipher.decrypt(ciphertext) assert restored == sample_key print("roundtrip ok") 출력은 roundtrip ok 입니다. 암호문은 생성할 때마다...

파이썬 Google Sheets API 연동: 서비스 계정 권한과 읽기·쓰기

파이썬에서 Google 스프레드시트를 읽고 쓰려면 사용할 인증 주체에 시트 접근 권한을 주고, 필요한 API와 범위를 설정해야 합니다. 서비스 계정을 생성했다는 사실만으로 개인 시트를 읽을 수 있는 것은 아닙니다. 서비스 계정과 사용자 OAuth 선택 서버에서 정해진 시트만 처리하는 작업에는 서비스 계정을 검토할 수 있습니다. 사용자가 직접 자신의 자료 접근을 승인하는 앱에는 사용자 OAuth가 적합할 수 있습니다. 조직 정책에 따라 키 파일 발급이나 외부 공유가 제한될 수 있으므로 관리자 정책도 확인하세요. 연결 전에 확인할 항목 Google Cloud 프로젝트에서 사용하려는 Sheets API를 활성화합니다. 사용하는 기능에 따라 Drive API도 필요할 수 있습니다. 서비스 계정 인증 정보를 안전한 위치에 준비합니다. 대상 시트를 서비스 계정 이메일과 공유하고 필요한 최소 권한만 부여합니다. 시트 URL의 문서 ID와 워크시트 이름을 확인합니다. 정해진 범위만 읽고 쓰는 예제 python -m pip install gspread google-auth 로 설치합니다. 다음 코드는 실제 API를 사용하며, 지정된 워크시트의 A1:B2를 덮어씁니다. 반드시 복사한 테스트 시트에서 실행하세요. 아래 외부 연동 예제는 이 사이트의 로컬 코드 검증 대상에 포함하지 않았습니다. import os import gspread key_file = os.environ["GOOGLE_SERVICE_ACCOUNT_FILE"] sheet_id = os.environ["GOOGLE_SHEET_ID"] client = gspread.service_account(filename=key_file) worksheet = client.open_by_key(sheet_id).worksheet("테스트") worksheet.update( range_name="A1:B2", values=[[...

파이썬 PostgreSQL 원격 접속: psycopg2와 TLS 검증

PostgreSQL 원격 접속은 서버 접근 경로, DB 인증, TLS 인증서 검증을 차례로 확인해야 합니다. psycopg2 연결 코드가 맞더라도 서버 정책과 인증서 설정이 맞지 않으면 접속되지 않습니다. 연결 정보와 네트워크 경로 확인 관리자에게 받은 호스트, 포트, DB명, 계정과 허용된 접속 경로를 확인하세요. 기본 포트는 5432이지만 운영 환경에서는 다른 포트를 사용할 수 있습니다. 접속 오류를 해결하려고 방화벽을 전체 공개하거나 TLS 검증을 끄지 말고, 승인된 네트워크와 인증서를 사용해야 합니다. 인증서를 검증하는 읽기 전용 연결 예제 Python 3와 psycopg2가 필요합니다. 설치 방법은 사용하는 운영체제와 배포 환경의 Psycopg 문서를 따르세요. 아래 코드는 실제 DB 접근 정보가 필요하므로 이 사이트의 로컬 실행 검증 대상에는 포함하지 않았습니다. import os import psycopg2 conn = psycopg2.connect( host=os.environ["PGHOST"], port=os.environ.get("PGPORT", "5432"), dbname=os.environ["PGDATABASE"], user=os.environ["PGUSER"], password=os.environ["PGPASSWORD"], sslmode="verify-full", sslrootcert=os.environ["PGSSLROOTCERT"], connect_timeout=10, ) try: with conn: with conn.cursor() as cur: cur.execute("SELECT current_database(), current_user") p...

여러 서비스 계정의 작업 큐 관리: 중복 실행 방지

여러 계정의 작업은 계정별 권한과 작업 식별자를 분리하고, 성공 여부를 기록한 다음 다음 항목으로 넘어가야 합니다. 어떤 상황에서 적용하나요? 아래는 소유한 계정에 보낼 작업을 검증하는 로컬 예제입니다. 실제 계정에 게시하지 않으며 토큰 대신 비밀값 참조 이름만 다룹니다. 여러 계정을 사용하는 목적이 제공자의 호출 제한 우회가 되어서는 안 됩니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 jobs = [ {"account": "team-a", "item": "report-01", "secret_ref": "TEAM_A_TOKEN"}, {"account": "team-b", "item": "report-01", "secret_ref": "TEAM_B_TOKEN"}, {"account": "team-a", "item": "report-01", "secret_ref": "TEAM_A_TOKEN"}, ] seen = set() ready = [] for job in jobs: identity = (job["account"], job["item"]) if identity in seen: continue seen.add(identity) ready.append(job) assert len(ready) == 2 print([(j["account"], j["item"]) for j in ready]) 결과는 어떻게 확...

이미지 API 업로드 전 파일 크기와 형식 검증하기

이미지 전송 전에는 경로, 파일 크기, 실제 이미지 형식을 확인하고 서비스가 요구하는 업로드 규격에 맞춰야 합니다. 어떤 상황에서 적용하나요? 확장자만 jpg로 바꾸어도 실제 파일이 JPEG가 되는 것은 아닙니다. 아래는 Pillow로 임시 PNG를 만들고 이미지 형식을 읽는 예제입니다. python -m pip install Pillow가 필요하며 외부 업로드는 하지 않습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from pathlib import Path from tempfile import TemporaryDirectory from PIL import Image with TemporaryDirectory() as folder: path = Path(folder) / "sample.png" Image.new("RGB", (32, 24), "navy").save(path) if path.stat().st_size > 1024 * 1024: raise ValueError("예제의 파일 크기 제한 초과") with Image.open(path) as image: image.verify() with Image.open(path) as image: assert image.format == "PNG" assert image.size == (32, 24) print(image.format, image.size) 결과는 어떻게 확인하나요? PNG와 32×24 크기가 출력됩니다. verify 뒤에 파일을 다시 여는 것은 검증과 이미지 데이터 사용을 분리하기 위해서입니다. 예제의 1MiB는 설명용 제한이며 실제 업로드 한도는 제공자의 문서를 따라야 합니다. 실...

API 요청 간격 설계: Retry-After와 재시도 한도

요청 사이에 sleep을 넣는 것만으로 계정 정지나 호출 제한을 피할 수는 없습니다. 제공자의 한도와 재시도 안내를 따라야 합니다. 어떤 상황에서 적용하나요? 429 응답의 Retry-After는 초 단위 숫자 또는 HTTP 날짜일 수 있습니다. 아래 예제는 숫자 형태만 처리하고 최대 대기 시간을 제한합니다. 실제로 대기하거나 외부 요청을 보내지 않습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def retry_delay(header, maximum=120): try: seconds = int(header) except (TypeError, ValueError): return None if seconds < 0: return None return min(seconds, maximum) assert retry_delay("30") == 30 assert retry_delay("999") == 120 assert retry_delay("not-a-number") is None print(retry_delay("30")) 결과는 어떻게 확인하나요? 출력은 30입니다. None은 곧바로 재전송하라는 뜻이 아니라, 다른 날짜 형식인지 확인하거나 작업을 중단해 운영 정책에 따라 판단해야 한다는 뜻입니다. 실제 업무에 적용할 때 확인할 점 POST 같은 쓰기 요청은 응답이 끊겼더라도 서버에서 이미 처리됐을 수 있습니다. 멱등성 키나 결과 조회 없이 무조건 반복하면 중복 게시가 생깁니다. 재시도 횟수, 총 대기 시간, 취소 조건을 함께 정하세요. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: API·운영 가이드 · 인증 오류 확인 작성: 로그 · 2026...

Slack 알림 연동 전 메시지와 비밀값 분리하기

Slack 실행 알림은 작업 식별자와 결과만 전달하고, 웹훅 URL·API 키·고객 원문은 메시지와 로그에서 제외해야 합니다. 어떤 상황에서 적용하나요? Incoming Webhook URL은 메시지를 보낼 수 있는 비밀값입니다. 아래는 외부 전송 전에 알림 본문을 만드는 부분만 검증하는 예제입니다. 실제 채널에 메시지를 보내지 않습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 import json def make_notice(job_id, succeeded, count): if not job_id or count < 0: raise ValueError("작업 ID와 처리 건수를 확인하세요") state = "완료" if succeeded else "실패" return {"text": f"작업 {job_id}: {state}, 처리 {count}건"} payload = make_notice("daily-report", True, 3) assert payload == {"text": "작업 daily-report: 완료, 처리 3건"} print(json.dumps(payload, ensure_ascii=False)) 결과는 어떻게 확인하나요? 출력 JSON에는 작업 상태만 들어가고 인증 정보는 없습니다. 실제 전송은 별도 함수에서 환경변수나 비밀 저장소로 URL을 읽고, 요청 시간 제한과 응답 확인을 추가해 구현합니다. 실제 업무에 적용할 때 확인할 점 알림 전송 실패와 본 작업 실패는 구분하세요. 보고서 저장은 성공했는데 Slack만 실패한 경우 전체 작업을 다시 실행하면 파일이나 게시물이 중복될 수 있습니다. 알림에는 원인 추적용 ID를 넣고 세부 로그의 접근 ...

OAuth 토큰 갱신 판단: 만료 시간과 동시 요청 처리

OAuth 갱신은 토큰 만료 시각과 제공자의 갱신 정책에 따라 수행하며, refresh token이 항상 발급되는 것은 아닙니다. 어떤 상황에서 적용하나요? 아래는 만료 직전의 토큰을 미리 갱신할지 판단하는 순수 함수입니다. 로그인 화면이나 토큰 서버를 호출하지 않습니다. 실제 인가 흐름은 제공자의 SDK와 공식 문서를 따르세요. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def should_refresh(expires_at, now, margin=60): if expires_at is None: return False return now + margin >= expires_at assert should_refresh(1000, 950) assert not should_refresh(1000, 800) assert not should_refresh(None, 800) print(should_refresh(1000, 950)) 결과는 어떻게 확인하나요? 예제의 60초 여유는 로컬 정책이며 모든 제공자의 권장값은 아닙니다. 만료 시각이 없는 토큰은 유효하다고 단정하지 말고 제공자의 토큰 유형과 응답 필드를 확인해야 합니다. 실제 업무에 적용할 때 확인할 점 여러 프로세스가 같은 refresh token을 동시에 쓰면 토큰 교체 정책과 충돌할 수 있습니다. 갱신 작업을 직렬화하고 새 토큰을 원자적으로 보관하세요. 인증 코드·토큰·클라이언트 비밀을 URL, 화면 캡처나 로그에 노출하지 않습니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: API·운영 가이드 · 인증 오류 확인 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고 예제·적용 조건·공식 근거를 보완했습니다.

Tumblr API 게시 요청 전 초안 데이터 검증하기

Tumblr 연동은 계정과 블로그 권한을 확인하고, 초안 상태의 요청을 검증한 뒤 실제 발행을 결정하는 순서로 구현합니다. 어떤 상황에서 적용하나요? 아래는 게시물 본문 블록을 만드는 로컬 예제입니다. 인증·업로드·외부 게시를 실행하지 않으므로 요청 데이터와 검증 부분을 독립적으로 시험할 수 있습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def draft_post(text, tags): if not text.strip(): raise ValueError("본문이 비어 있습니다") return { "state": "draft", "content": [{"type": "text", "text": text.strip()}], "tags": list(dict.fromkeys(tags)), } payload = draft_post("파일 정리 도구의 사용법을 설명합니다.", ["Python", "Python"]) assert payload["state"] == "draft" assert payload["tags"] == ["Python"] print(payload) 결과는 어떻게 확인하나요? 본문은 텍스트 블록으로 정리되고 태그 중복이 제거됩니다. 예제의 구조를 실제 API에 사용할 때는 사용 중인 엔드포인트와 NPF 문서의 필수 필드·인코딩을 확인해야 합니다. 실제 업무에 적용할 때 확인할 점 초안 생성과 공개 발행은 별도 단계로 관리하세요. 자동으로 타인의 글을 복제하거나 링크 획득을 위해 여러 블로그에 같은...

Search Console API 집계 조건: 기간과 검색 유형 맞추기

Search Console API 결과를 비교하려면 대상 속성·기간·검색 유형·집계 기준을 먼저 맞춰야 합니다. 어떤 상황에서 적용하나요? 다음은 Search Analytics 요청 본문을 로컬에서 만드는 예제입니다. 인증이나 API 전송은 하지 않습니다. 실제 연결에는 대상 속성의 접근 권한과 적절한 OAuth 인증이 필요합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from datetime import date def search_body(start, end): if date.fromisoformat(start) > date.fromisoformat(end): raise ValueError("시작일이 종료일보다 늦습니다") return {"startDate": start, "endDate": end, "dimensions": ["date"], "type": "web", "rowLimit": 1000} body = search_body("2026-10-01", "2026-10-07") assert body["dimensions"] == ["date"] print(body) 결과는 어떻게 확인하나요? 날짜별 웹 검색 지표를 요청하는 본문이 출력됩니다. URL 접두어 속성과 도메인 속성은 식별자 형식이 다릅니다. API의 siteUrl에는 등록된 속성과 일치하는 값을 전달해야 합니다. 실제 업무에 적용할 때 확인할 점 반환된 행을 모든 검색어의 완전한 목록으로 간주하지 마세요. 익명화·집계·행 수 제한 때문에 얻을 수 없는 정보가 있습니다. 검색어별 자료와 날짜별 자료의 합계를 무...

IndexNow 로그 설계: 전송 상태와 색인 상태를 구분하기

검색엔진 알림 로그에는 전송 상태와 실제 색인 상태를 별도 필드로 기록해야 합니다. HTTP 응답만으로 “색인 성공”이라고 기록하면 나중에 문제를 진단할 수 없습니다. 기록할 최소 필드 실행 시각, 대상 URL, 응답 코드, 전송 시도 횟수와 확인된 오류 사유를 남기세요. 응답 본문 전체에 민감한 정보가 포함되는지 확인하고 인증 키·토큰은 로그에서 제외합니다. 시간대도 명시해 여러 실행 환경의 기록을 비교할 수 있게 합니다. JSON Lines 형태의 로그 예제 아래 Python 3 코드는 외부 API를 호출하지 않습니다. 관찰한 응답이 202인 상황을 가정해 로그 한 줄을 출력합니다. from datetime import datetime, timezone import json event = { "at": datetime.now(timezone.utc).isoformat(), "url": "https://www.goodkyoungs.com/p/api.html", "http_status": 202, "notification_state": "pending_validation", "index_state": "unknown", "attempt": 1, } assert event["index_state"] == "unknown" print(json.dumps(event, ensure_ascii=False)) 실제 프로그램에서는 이 구조를 로그 파일이나 관찰 도구에 남길 수 있습니다. 요청 재시도가 있었다면 매번 별도 이벤트를 기록하고 동일한 작업 식별자로 묶어 추적하세요. 결과를 확인하는 후속 절차 알림 접수 이후 참여 검색엔진의 웹마스터 도구에서 URL 상태를 확인하고, 확인 일시와 근거를 별도로 기록합니다. 상태를...

API 403 Forbidden 오류: 권한과 사용 정책 점검 순서

403 Forbidden은 서버가 요청을 이해했지만 접근을 허용하지 않았다는 뜻입니다. 토큰 권한, 대상 리소스 소유권, API 활성화와 서비스 정책을 확인해야 하며, 무조건 IP나 계정을 바꾸는 것은 해결책이 아닙니다. 재시도 전에 확인할 항목 응답 본문의 공식 오류 코드와 요청 식별자를 기록합니다. 인증 토큰의 만료와 필요한 범위를 확인합니다. 프로젝트의 API 활성화 상태와 대상 문서·사이트 권한을 확인합니다. 사용 중인 API가 해당 콘텐츠와 계정에 허용되는지 확인합니다. 조직 정책·요청 제한·지원 문의 절차를 확인합니다. 로그에 비밀값을 남기지 않는 예제 다음은 네트워크를 호출하지 않고, 애플리케이션에서 상태 코드를 분류하는 Python 3 예제입니다. def classify_status(status): if status == 403: return "권한과 사용 정책 확인: 자동 반복 중단" if status == 429: return "제공자 안내에 따라 대기" if 500 <= status < 600: return "멱등성과 재시도 제한 확인" return "응답 본문과 작업 결과 확인" assert "자동 반복 중단" in classify_status(403) print(classify_status(403)) 401·403·429는 서비스마다 세부 의미와 오류 본문이 다를 수 있습니다. 숫자만 보고 모든 실패를 같은 재시도로 처리하지 마세요. 로그에는 인증 헤더, 키 파일 본문, 고객 정보가 들어가지 않아야 합니다. Indexing API의 403이라면 권한 문제 외에 API의 적용 대상도 확인해야 합니다. 일반 블로그 글을 Google Indexing API로 대량 제출하는 설계부터 재검토해야 할 수 있습니다. 해당 API의 적격 콘텐츠와 계정 소유권 조건을 ...

여러 사이트 API 인증 설정: 자격 증명 참조 분리

여러 사이트의 인증 설정은 사이트 주소와 비밀값 참조를 분리하고, 실행 전에 허용된 호스트인지 검증합니다. 어떤 상황에서 적용하나요? JSON 키 파일을 여러 도메인에 재사용한다고 모든 사이트 권한이 생기지는 않습니다. 다음 예제는 토큰 없이 설정 구조만 검사합니다. 실제 인증 권한은 각 서비스에서 별도로 부여해야 합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from urllib.parse import urlparse allowed = {"www.example.com", "docs.example.com"} configs = [{"url": "https://docs.example.com/", "credential_ref": "DOCS_TOKEN"}] for config in configs: parsed = urlparse(config["url"]) if parsed.scheme != "https" or parsed.hostname not in allowed: raise ValueError("허용되지 않은 사이트") if not config.get("credential_ref"): raise ValueError("인증 정보 참조가 없습니다") assert len(configs) == 1 print("설정 검증 완료") 결과는 어떻게 확인하나요? 설정 검증 완료가 출력됩니다. 이는 인증 성공이 아니라 로컬 설정의 필수 조건을 통과했다는 뜻입니다. 참조 이름은 실행 시 환경변수나 비밀 저장소에서 실제 자격 증명을 찾는 데 사용합니다. 실제 업무에 적용할 때 확인할 점 일반 블로그 글은 Goo...

IndexNow 202 Accepted 의미: 키 검증과 후속 확인 절차

IndexNow의 202 Accepted 응답은 색인이 끝났다는 뜻이 아닙니다. 알림이 접수됐고 키 검증 등 후속 처리가 필요할 수 있으므로, 요청 조건과 이후 상태를 확인해야 합니다. 202를 받았다면 무엇을 확인하나요? 제출한 호스트가 자신이 소유한 사이트인지 확인합니다. 키 파일이 비로그인 상태에서 열리는지 확인합니다. 파일 내용과 요청에 사용한 키가 정확히 같은지 비교합니다. 제출 URL과 키 위치가 공식 문서의 호스트·경로 조건을 만족하는지 확인합니다. 웹마스터 도구에서 나중에 발견·수집·색인 상태를 확인합니다. Blogger에서 특히 확인할 점 Blogger는 임의의 루트 파일 업로드를 일반적인 정적 호스팅처럼 지원하지 않습니다. 페이지 본문에 키를 적거나 HTML 템플릿에 키 문자열을 넣는 방식이 IndexNow 키 파일의 응답 형식과 같은지는 별도로 검증해야 합니다. 키 제공 조건을 충족하지 못하면 무작정 알림을 반복하지 마세요. 재전송 횟수보다 요청의 정확성이 중요합니다 오류 코드와 공식 응답 설명을 기록하고 원인을 먼저 해결하세요. 429 응답에서 여러 계정이나 IP로 요청을 분산하는 방식은 적절한 해결책이 아닙니다. 변경되지 않은 URL을 반복 제출하는 운영도 줄이는 편이 좋습니다. 로그에 구분해 남기기 접수 시각과 HTTP 상태, 키 검증 상태, 실제 색인 확인 시각을 다른 항목으로 관리하세요. 확인하지 못한 상태는 “미확인”으로 표시합니다. 성공 응답 개수를 색인 페이지 수로 세면 보고서가 부정확해집니다. 공식 기준: IndexNow 문서 . 관련 글: 알림과 색인의 차이 , 로그 상태 설계 , API·운영 가이드 . 작성: 로그 · 2026-10-17 정정: 202를 색인 성공으로 해석할 수 있던 설명을 수정했습니다.

IndexNow는 무엇을 알리나요? 알림 접수와 색인 완료 구분

IndexNow는 사이트의 새 URL이나 변경 사실을 참여 검색엔진에 알리는 프로토콜입니다. 알림 접수는 크롤링·색인·검색 순위 상승을 보장하지 않습니다. 먼저 소유권과 공개 URL 확인 소유한 호스트에서 키 파일을 제공하는 등 공식 소유권 확인 요건을 충족해야 합니다. Blogger처럼 루트의 임의 텍스트 파일 제공이 제한되는 환경에서는 구현 가능 여부부터 확인하세요. 일반 게시물에 키 문자열을 적는 것만으로 키 파일 요건을 충족한다고 가정하면 안 됩니다. 응답을 어떻게 읽나요? 응답 해석 200 요청을 성공적으로 접수한 응답. 색인 완료와는 다름 202 키 검증 등을 위해 접수된 상태. 후속 결과 확인 필요 400·403·422 요청 형식, 키, 호스트 및 URL 조건 점검 429 요청 빈도를 줄이고 서비스 안내 확인 외부 호출 없는 응답 분류 예제 def notification_state(status): if status == 200: return "submitted" if status == 202: return "pending_validation" if status == 429: return "throttled" return "needs_review" assert notification_state(202) == "pending_validation" assert notification_state(200) != "indexed" print(notification_state(202)) 변수 이름도 indexed 가 아니라 submitted 또는 pending처럼 실제로 관찰한 상태를 표현해야 합니다. 최종 색인 여부는 참여 검색엔진의 도구에서 별도로 확인합니다. Google 색인과 구분하기 Google 일반 블로그 글의 색인 점검은 Search Console, 사이...

회사 프록시를 사용하는 파이썬 요청 설정 점검

프록시는 승인된 네트워크 경로를 설정하는 도구이며, 차단된 서비스의 접근 권한을 얻거나 정책을 우회하는 수단이 아닙니다. 어떤 상황에서 적용하나요? 아래는 프록시 주소 형식을 검사하는 로컬 코드입니다. 외부 서버에 연결하지 않습니다. 실제 프록시 서버와 인증 방식은 회사의 네트워크 관리자 안내에 맞춰야 합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from urllib.parse import urlparse def validate_proxy(url): parsed = urlparse(url) if parsed.scheme not in {"http", "https"} or not parsed.hostname: raise ValueError("프록시 주소 형식 오류") if parsed.username or parsed.password: raise ValueError("예제 설정에 자격 증명을 직접 넣지 마세요") return parsed.hostname, parsed.port assert validate_proxy("http://proxy.example.com:8080") == ("proxy.example.com", 8080) print("프록시 주소 형식 확인") 결과는 어떻게 확인하나요? 주소 형식 확인 메시지는 프록시 사용 가능 여부와 다릅니다. 실제 연결에는 방화벽·인증·인증서 정책이 추가로 영향을 줍니다. HTTPS 목적지에 사용하는 프록시 URL이 반드시 https 스킴이라는 뜻도 아닙니다. 실제 업무에 적용할 때 확인할 점 Requests의 명시적 proxies 인자와 환경변수 설정이 어떻게 적용되는지 확인하세요. 인증서 검증을 끄는 verify=Fals...

API 일일 한도 관리: 시도 횟수와 성공 횟수 나누기

API 한도 카운터는 제공자의 계산 기준에 맞춰야 하며, 실패 요청도 한도에 포함될 수 있습니다. 어떤 상황에서 적용하나요? 아래는 실행 전에 남은 요청 수를 확인하는 로컬 예제입니다. 예제의 limit=3은 설명용이며 실제 서비스의 일일 한도를 뜻하지 않습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 class Budget: def __init__(self, limit): self.limit = limit self.attempted = 0 def reserve(self): if self.attempted >= self.limit: return False self.attempted += 1 return True budget = Budget(3) results = [budget.reserve() for _ in range(4)] assert results == [True, True, True, False] print(results) 결과는 어떻게 확인하나요? 네 번째 시도는 허용되지 않습니다. 요청이 실제로 성공했는지는 별도로 기록하세요. 재시도를 추가한다면 재시도도 reserve를 거쳐야 시도 수가 누락되지 않습니다. 실제 업무에 적용할 때 확인할 점 프로세스가 여러 개면 메모리 카운터만으로 일관성을 보장할 수 없습니다. 영속 저장소와 원자적 차감을 사용하고, 일일 한도가 초기화되는 시간대를 확인하세요. 분당·계정별·프로젝트별 한도가 동시에 있을 수 있으므로 하나의 sleep 값으로 모두 대체하지 않습니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: API·운영 가이드 · 인증 오류 확인 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제...