2026.09.21 · Web Track 02

요청 뒤에서 일하는 백엔드

버튼을 누른 뒤 오래 걸리는 일은 누가 처리할까요? 이번에는 새 폴더에서 시작합니다. Cursor로 CSV 요약 작업을 접수하고, 뒤에서 일을 처리하는 worker.py를 만듭니다.

오늘의 도착점 — 작업 접수 → 대기 → Worker 처리 → 결과 JSON 확인. Python 기본 기능만 사용하므로 패키지 설치나 서버 설정 없이 실행할 수 있습니다.
연결이미 배운 개념
이해API와 Worker의 역할
실행Cursor에서 CSV 처리
확인결과와 실패 기록
CONNECT FIRST

새 용어 전에, 아는 것부터

복습 같은 개념확장 직접 만들어보기NEW 이번에 처음
기존 공부19주차에 연결할 것다시 보기
확장 · W3
API·요청·응답
웨이터는 주문을 접수하고 주방은 조리합니다. 이번에는 접수하는 프로그램과 실제 처리하는 Worker를 나눕니다. HTTP API 구현은 하지 않습니다.식당 비유 · REST
확장 · W8
무대·백스테이지·무전기
백스테이지 안에도 여러 담당자가 있습니다. Worker는 맡겨진 일을 처리하는 담당자입니다. API=무전기와 API=웨이터는 같은 개념을 다른 상황으로 설명한 것입니다.공연 속 통신
복습 · W9·W10
계획 → 실행 → 확인·수정
Cursor Agent에 계획을 요청하고 파일 역할을 읽은 뒤 구현합니다. 터미널 로그와 결과 파일로 동작을 확인합니다.Plan 모드 · 프롬프트
확장 · W17
반복 처리·Parse JSON·Run history
작업을 하나씩 처리하는 반복문, JSON 결과, 완료·실패 기록으로 연결합니다. Power Automate의 실행 이력과 같은 필요를 작은 파일로 구현합니다.자동화 개념 · Parse JSON
확장 · W18
상태와 저장
브라우저 배열은 새로고침하면 초기화됐습니다. 이번에는 작업과 결과를 파일에 저장하므로 프로그램 종료 후에도 남습니다.상태와 저장

이번 실습은 새 출발입니다. 18주차 문서 보관소나 React 프로젝트가 없어도 됩니다. 빈 csv-worker-lab 폴더에서 시작하세요.

01 · ACCEPT → PROCESS

“접수했어요”와 “끝났어요”는 다르다

확장 · W8 백엔드는 요청을 받아 업무 규칙을 적용하고 데이터를 처리하는 역할입니다. 서버는 HTML이나 JSON을 응답할 수 있지만, 오래 걸리는 처리를 요청을 받는 자리에서 전부 끝낼 필요는 없습니다.

큰 CSV를 집계하거나 리포트를 만들 때는 먼저 작업을 접수하고, 별도 프로그램인 백그라운드 Worker가 대기 중인 작업을 처리하게 할 수 있습니다. 이번에는 Worker의 로그를 보기 위해 터미널에서 직접 실행합니다. “백그라운드”는 접수 흐름과 처리를 나눈다는 뜻이지, 창을 닫아도 자동으로 실행된다는 뜻은 아닙니다.

① submit.py 접수② pending 대기③ worker.py 처리④ results 결과

접수 담당 · submit.py

CSV를 작업 전용 폴더에 복사하고 고유 작업 ID를 발급합니다. “대기 중”을 표시한 뒤 종료됩니다. 아직 집계 결과가 나온 것은 아닙니다.

처리 담당 · worker.py

대기 폴더를 확인하고 CSV를 하나씩 집계합니다. 일이 없어도 다음 작업을 기다립니다. 결과 또는 실패 이유를 파일로 남깁니다.

실제 서비스에서는 API가 접수 담당이 될 수 있습니다. 사용자 요청 → API 접수 → 작업 큐 → Worker → 결과 저장 순서입니다. 오늘은 HTTP 서버 대신 접수 스크립트, 운영용 큐 대신 로컬 폴더를 사용해 역할을 눈으로 확인합니다.
이 Worker는 Web Worker나 Cloudflare Workers와 같은 건가요?

이번 worker.py는 CSV를 처리하는 별도 Python 프로그램입니다. 브라우저 안에서 실행되는 Web Worker, Cloudflare 플랫폼에서 실행되는 Workers, 서버 실행 옵션의 worker 개수와는 실행 환경·용도가 다릅니다. “맡은 일을 처리한다”는 표현은 비슷하지만 같은 제품이나 기능은 아닙니다.

02 · LANGUAGE & RESPONSIBILITY

도구 이름보다, 맡은 일을 구분하기

NEW Python·Java·JavaScript는 언어, FastAPI·Spring·NestJS는 프레임워크입니다. Node.js는 JavaScript를 브라우저 밖에서 실행하는 런타임입니다. 18주차에서 보충한 구분을 그대로 씁니다.

이름역할이번 실습에서
Cursor코드를 작성하고 실행을 돕는 도구Agent 채팅, 파일 탐색기, 터미널 사용
Python처리 규칙을 쓰고 실행하는 언어작업 접수와 CSV 요약
csv·json·pathlibPython에 포함된 표준 라이브러리표 읽기, JSON 기록, 파일 경로 처리
worker.py우리가 만드는 파일 이름대기 작업을 처리하는 프로그램. 별도 설치 제품이 아님

Python은 이후 데이터·RAG 실습에도 이어 쓸 수 있습니다. 여러 언어는 공통 기초를 공유하지만 타입·성능·라이브러리·운영 방식에도 차이가 있습니다. 문법만 다른 방언으로 이해하지는 마세요.

CSV 집계를 다섯 가지 기초로 읽기

기초하는 일Worker에서
변수값에 이름 붙이기row_count에 데이터 행 수 기록
조건문조건에 따라 처리 선택셀이 비어 있으면 누락값 증가
반복문여러 값을 차례로 처리작업들을 하나씩, CSV 행들을 하나씩 읽기
함수일을 이름 붙여 묶기summarize_csv가 집계 담당
데이터 타입값의 종류 구분행 수는 정수, 열 이름은 문자열, columns는 목록

업무 규칙과 MVC

NEW “헤더는 행 수에서 뺀다”, “공백만 있는 셀도 누락으로 친다” 같은 기준이 비즈니스 로직입니다. 업무 담당자와 개발자가 함께 정하고 AI에게 구체적으로 전달합니다.

MVC는 Model(데이터·규칙), View(표현), Controller(요청 흐름)으로 책임을 나누는 설계 방식입니다. 웹 앱에서는 데이터 처리, 화면, 요청 처리의 역할을 나눠 생각할 수 있습니다. 이번 작은 Worker는 MVC 구조를 구현하지 않으며 Worker가 곧 Controller인 것도 아닙니다. 핵심은 “접수·처리·기록의 책임을 설명할 수 있는가”입니다.

03 · THE SHARED CONTRACT

API와 데이터 약속은 그대로

복습 · W3 API는 프로그램이 기능을 사용하는 접점, REST는 자원 중심의 아키텍처 스타일, JSON은 데이터 표현 형식입니다. REST와 JSON은 같은 말이 아니며, REST가 스마트폰 때문에 생긴 것도 아닙니다.

예를 들어 문서 API의 같은 주소라도 GET은 읽고 POST는 추가합니다. 메서드와 경로를 함께 적어야 동작이 분명해집니다. 아래는 개념 복습용이며 이번 Worker 실습에 구현하는 주소는 아닙니다.

CRUD메서드 + 경로 예시의미
Create · 생성POST /api/documents문서 추가
Read · 조회GET /api/documents문서 목록 조회
Update · 수정PATCH /api/documents/{id}문서 일부 수정
Delete · 삭제DELETE /api/documents/{id}문서 삭제

CRUD는 데이터 처리의 기본 묶음입니다. 작업 접수·취소처럼 다른 기능도 API로 제공할 수 있습니다. 오래 걸리는 작업을 HTTP로 접수한다면 202 Accepted와 작업 ID를 반환하고, 나중에 상태를 조회하는 방식도 가능합니다. “접수 성공”은 “처리 성공”과 다릅니다.

JSON은 API 밖에서도 쓴다

이번 실습의 대기 작업 JSON 예시 · ID와 시각은 실행마다 달라짐
{
  "job_id": "발급된작업ID",
  "status": "pending",
  "source_file": "sample.csv",
  "submitted_at": "2026-09-21T00:00:00+00:00"
}

중괄호는 객체 하나, 대괄호는 목록입니다. JSON은 데이터베이스도 화면도 아닙니다. 이번에는 API 통신이 아니라 프로그램끼리 전달할 작업 설명과 결과를 파일로 저장할 때 사용합니다.

확장 · W17 Parse JSON으로 필요한 필드를 꺼냈던 것처럼 이번에는 Python의 json 모듈로 읽습니다. title·tags 대신 job_id·status·row_count를 보지만 데이터 형식은 같습니다.
04 · START IN CURSOR

Cursor에서 빈 폴더 열기

새 csv-worker-lab 폴더를 만들고 Cursor의 File → Open Folder로 엽니다. Terminal → New Terminal을 선택해 아래 명령을 실행하세요. 안내는 Windows PowerShell 기준입니다.

Python 확인
py --version

Python 3.10 이상이면 준비 끝입니다. py를 찾지 못하면 python --version을 확인하고 아래 모든 명령의 py를 python으로 바꿉니다. 둘 다 없다면 Python 설치 후 Cursor를 다시 열어 확인하세요. 패키지 설치·가상환경·외부 계정은 필요 없습니다.

직접 만들어보기

아래 프롬프트를 Cursor Agent 채팅에 붙여 넣고 계획을 확인한 뒤 구현을 요청합니다. 코드를 외우는 대신 파일별 역할을 이해합니다.

참고 코드로 바로 실행

실습 파일 ZIP 다운로드 → 압축 해제 → submit.py와 worker.py가 보이는 폴더를 Cursor에서 엽니다. 같은 실행 단계로 따라갈 수 있습니다.

개별 다운로드: submit.py · worker.py · sample.csv · 실행 안내. 세 실행 파일은 같은 폴더에 둡니다. 파일명 뒤에 .txt가 붙지 않았는지 확인하세요.

파일 탐색기에서 보일 구조
csv-worker-lab/
├─ submit.py           ← 접수하고 종료
├─ worker.py           ← 대기하면서 처리
├─ sample.csv          ← 샘플 입력
└─ jobs/               ← 실행하면 자동 생성
   ├─ inputs/          ← 접수 당시 CSV 복사본
   ├─ pending/         ← 대기 작업 JSON
   ├─ processing/      ← 처리 중 작업 JSON
   ├─ completed/       ← 완료 작업 기록
   ├─ failed/          ← 실패 기록과 원인
   └─ results/         ← 요약 리포트 JSON

참고 코드의 jobs 폴더는 스크립트가 있는 폴더를 기준으로 만듭니다. 터미널의 현재 위치가 다르더라도 기록 위치는 같지만, 실행 명령은 파일이 있는 폴더에서 입력해야 편합니다.

05 · HANDS ON

터미널 하나는 접수, 하나는 처리

  1. Cursor Agent에 계획 요청하기

    복습 · W9·W10 새 폴더에서 아래 프롬프트를 보냅니다. submit.py와 worker.py의 역할을 확인한 뒤 “이 계획대로 만들어줘”라고 요청합니다. 참고 ZIP을 사용했다면 다음 단계로 넘어가세요.

    복사해서 Agent 채팅에 붙여넣기
    이 빈 csv-worker-lab 폴더에서 CSV 요약 작업을 처리하는 실습을 만들어줘.
    먼저 파일 구조와 처리 계획을 보여주고, 내가 승인하면 구현해줘.
    
    Python 3.10 이상 표준 라이브러리만 사용해. pip 설치, 웹 서버, UI, DB는 필요 없어.
    파일은 submit.py, worker.py, sample.csv, README.md, .gitignore로 구성해.
    
    submit.py:
    - py submit.py sample.csv로 접수하고 종료.
    - 존재하는 .csv 파일인지 확인하고 고유 작업 ID 발급.
    - CSV를 jobs/inputs/작업ID.csv로 복사한 다음 jobs/pending/작업ID.json을 게시.
    - 접수 JSON: job_id, status=pending, source_file, submitted_at.
    - JSON은 임시 파일에 다 쓴 뒤 이름을 바꿔 Worker가 미완성 파일을 읽지 않게 해줘.
    
    worker.py:
    - py worker.py로 실행. 단일 Worker가 pending 작업을 접수 시각 순으로 하나씩 처리.
    - 대기 폴더는 1초마다 확인. Ctrl+C로 종료.
    - pending → processing → completed 또는 failed로 작업 JSON 이동.
    - 결과는 jobs/results/작업ID.json에 기록.
    - UTF-8 BOM도 읽고 첫 번째 비어 있지 않은 행은 헤더로 사용.
    - 헤더 이름이 비어 있거나 중복이면 실패.
    - 헤더를 제외한 row_count, columns, 열별 missing_values 집계.
    - 실제 빈 줄은 제외. 빈 셀과 공백만 있는 셀은 누락으로 계산.
    - 헤더만 있는 CSV는 0행, 빈 파일·열 개수 불일치·깨진 CSV는 실패.
    - 실패 사유를 남기고 다음 작업은 계속 처리.
    - 파일 저장 자체가 불가능하면 오류를 알리고 중단.
    - 접수 후 원본이 바뀌어도 해당 작업은 복사본으로 처리.
    - 결과와 작업 기록은 종료 후에도 남김. 자동 재시도·병렬 처리는 제외.
    - 재시작 시 남아 있는 processing 기록을 안내하되 자동 재처리하지 마.
    - 경로는 스크립트 폴더 기준으로 만들고 jobs/·__pycache__/는 Git에서 제외.
    
    sample.csv는 다음과 같이 만들어줘:
    project,owner,status
    Survey A,Mina,done
    Survey B,,pending
    Survey C,Joon,
    Survey D,"   ",done
    
    정상 결과는 4행, 누락값 project=0, owner=2, status=1.
    Cursor의 두 터미널에서 접수와 Worker를 각각 실행하는 방법을 README에 적어줘.
  2. 터미널 1 · 작업 두 개 접수하기

    submit.py가 있는 폴더에서 아래 두 줄을 실행합니다. Worker는 아직 켜지 않습니다. 매번 다른 작업 ID가 출력되고, 파일 탐색기의 jobs/pending 안에 JSON 두 개가 생기면 성공입니다.

    터미널 1 · 입력 후 바로 명령줄로 돌아옴
    py submit.py sample.csv
    py submit.py sample.csv

    접수는 끝났지만 처리는 아직입니다. jobs/inputs에는 각 작업의 CSV 복사본이 있고, jobs/results는 비어 있어야 합니다.

  3. 터미널 2 · Worker 시작하기

    Terminal → New Terminal로 터미널을 하나 더 만듭니다. 같은 폴더인지 확인하고 아래 명령을 실행합니다. Worker는 하나만 실행하세요.

    터미널 2 · 다음 작업을 기다리며 계속 실행
    py worker.py
    터미널 로그 예시 · ID는 실행마다 다름
    [worker] 대기 중입니다. 다른 터미널에서 접수하세요. 종료: Ctrl+C
    [processing] 작업ID
    [completed] 작업ID -> jobs/results/작업ID.json

    대기했던 두 작업이 하나씩 처리됩니다. processing 폴더는 금방 비워질 수 있으므로 로그로도 확인하세요. 명령줄로 돌아오지 않고 멈춰 보이는 것은 다음 작업을 기다리는 정상 상태입니다.

  4. Cursor에서 결과 파일 열기

    왼쪽 파일 탐색기에서 jobs → results → 작업ID.json을 엽니다. completed에는 작업 완료 기록, results에는 실제 집계 결과가 있습니다. sample.csv의 핵심 결과는 다음과 같아야 합니다.

    요약 리포트의 핵심 필드
    {
      "row_count": 4,
      "columns": ["project", "owner", "status"],
      "missing_values": {
        "project": 0,
        "owner": 2,
        "status": 1
      }
    }

    실제 결과에는 job_id·status·source_file·completed_at도 들어갑니다. 헤더는 데이터 행 수에서 빼고, Survey D의 공백만 있는 owner도 누락으로 셉니다.

  5. Worker 실행 중에 새 작업 보내기

    터미널 목록에서 터미널 1로 돌아가 py submit.py sample.csv를 다시 실행합니다. 터미널 2에 새 처리 로그가 나오고 새 결과 파일이 생깁니다. 접수 프로그램을 실행할 때마다 Worker를 새로 켤 필요는 없습니다.

    종료는 터미널 2에서 Ctrl+C입니다. Worker를 끈 뒤 작업을 접수하면 pending에 남습니다. 다시 py worker.py를 실행하면 남아 있던 대기 작업을 처리하고 이전 결과도 유지됩니다.

06 · CHECK THE EVIDENCE

성공과 실패를 모두 확인하기

Cursor에서 invalid.csv를 새로 만들고 다음 내용을 넣습니다. 헤더는 3열인데 데이터는 2열이라 Worker가 실패로 기록해야 합니다.

invalid.csv에 저장할 내용
project,owner,status
Survey E,Mina
터미널 1 · 잘못된 작업 다음에 정상 작업 접수
py submit.py invalid.csv
py submit.py sample.csv

invalid.csv 작업은 jobs/failed에 error를 남기고, 다음 sample.csv 작업은 완료되어야 합니다. 실패한 작업을 성공한 것처럼 처리하지 않는 것도 백엔드의 역할입니다.

실행할 것정상 결과설명할 개념
Worker 시작 전 접수pending과 inputs에 파일, results는 아직 없음접수와 완료는 다름
Worker 실행completed 기록과 results 리포트 생성큐에서 꺼내 실제 처리
샘플 결과 확인4행, owner 누락 2, status 누락 1명시한 업무 규칙
원본 수정 전 작업 접수접수 당시 복사본 기준으로 집계입력 스냅샷
잘못된 CSV 다음 정상 CSV 접수failed 기록 후 다음 작업은 완료실패 격리
없는 경로를 접수접수 실패, pending 작업 생성 안 됨접수 단계의 입력 확인
종료 후 재실행이전 결과 유지, 남은 pending만 처리프로세스와 파일 수명은 다름

막히면 이 순서로

① Python 명령이 되는지 → ② 현재 폴더에 두 .py 파일이 있는지 → ③ 접수 ID가 나왔는지 → ④ Worker 터미널이 실행 중인지 → ⑤ failed 기록의 error가 무엇인지 확인합니다.

py 또는 python을 찾을 수 없어요

두 명령의 --version을 각각 확인하세요. Python 설치 후에도 안 되면 Cursor를 완전히 닫고 다시 열어 터미널에서 확인합니다. 설치 안내나 오류 내용을 Agent에 전달하세요. 참고 코드는 외부 패키지를 쓰지 않으므로 pip 설치로 해결할 문제는 아닙니다.

can't open file 또는 No module named worker가 나와요

Cursor 파일 탐색기에 submit.py와 worker.py가 같은 폴더에 있는지 확인합니다. 터미널에서 Get-Location과 Get-ChildItem으로 현재 폴더를 확인하고, 압축을 풀었을 때 바깥 폴더가 아닌 두 파일이 들어 있는 폴더를 여세요. 파일 뒤에 .txt가 붙어도 안 됩니다.

Worker를 켜니 다른 명령을 입력할 수 없어요

정상입니다. 그 터미널은 Worker가 사용 중입니다. Terminal → New Terminal로 추가한 다른 터미널에서 접수하세요. Worker 창을 닫으면 처리도 멈춥니다.

CSV 인코딩·열 수 오류가 나요

UTF-8 또는 UTF-8 BOM의 쉼표 구분 CSV를 사용합니다. Excel에서 저장했다면 CSV UTF-8 형식을 선택하세요. 참고 코드는 첫 번째 비어 있지 않은 행을 헤더로 취급하며, 열 이름이 비어 있거나 중복이면 거절합니다. 빈 물리적 줄은 제외하지만 쉼표로 구분된 빈 셀 행은 데이터로 집계합니다. 헤더만 있으면 0행 리포트, 완전히 빈 파일은 실패입니다.

재시작했는데 processing에 작업이 남았어요

작업 중 Ctrl+C 또는 강제 종료가 들어가면 처리 중 기록이 남을 수 있습니다. 자동으로 재처리하지 않습니다. 같은 ID의 results 파일과 processing 기록을 먼저 확인하고 새 결과가 필요하면 원본이나 jobs/inputs의 복사본을 다시 접수하세요. 새 접수에는 새 ID가 붙습니다. results가 이미 있으면 집계는 끝났지만 기록 이동 전 중단됐을 수도 있습니다.

교육용 파일 대기열의 범위 — Worker는 하나만 실행합니다. 파일 저장 자체가 안 되는 오류는 알리고 중단합니다. 운영 서비스에 필요한 병렬 처리·자동 재시도·중복 방지·접근 제어는 이번에 구현하지 않습니다. DB 없이도 파일은 남지만 여러 사용자의 검색·수정·권한을 관리하는 일은 별도 문제입니다.
07 · FROM WORK TO IDENTITY

다음 질문은 “누구의 작업인가?”

지금은 로컬 컴퓨터의 파일 접근 권한만 사용합니다. 앱의 로그인이나 작업 소유자 검사는 없습니다. 나중에 API로 접수와 결과 조회를 열면 누가 접수했는지, 누가 결과를 볼 수 있는지를 확인해야 합니다.

같은 Worker가 처리해도,
결과는 요청한 사람에게만 보여주려면?

HTTP 요청 자체가 이전 로그인 정보를 자동으로 이어주지는 않습니다. 20주차의 쿠키·세션·JWT는 요청에 사용자 정보를 연결하는 방법으로 이어집니다. 이번에 접수·조회 API를 이미 만들었다는 뜻은 아닙니다. API를 붙이는 단계가 먼저 필요합니다. 21주차에는 파일과 다른 DB의 검색·관리 방식을 다룹니다.

선택 과제

  1. Worker를 끈 상태에서 작업을 접수하고 원본 CSV를 수정한 뒤 실행합니다. 접수 당시 복사본과 결과가 일치하는지 확인합니다.
  2. 업무 규칙 하나를 추가해 보세요. 예: 전체 셀 중 누락값의 비율. 빈 데이터의 계산 기준도 먼저 정합니다.
  3. Agent에 “작업 접수·CSV 집계·결과 기록을 담당하는 함수를 각각 설명해줘”라고 요청합니다.
  4. 실습 코드는 개인 저장소에 기록하고 jobs/와 __pycache__/는 제외합니다. 교육자료 사이트에 파일을 올려도 Worker가 자동 실행되지는 않습니다.

공식 문서로 더 보기

← 18주차: 프론트엔드 뿌리 · 전체 학습 노트