Java & Python

웹 클라이언트, 웹 서버 라이브러리

토끼퉁 2023. 9. 18. 16:03

웹 클라이언트 라이브러리

1. requests
파이썬에서 HTTP 요청을 보내고 응답을 처리하기 위한 라이브러리

+ 간결하고 사용하기 쉬운 API : HTTP 요청을 보내고 응답을 처리하는 것을 쉽게 만들어준다. GET, POST, PUT, DELETE 등의 다양한 메서드를 지원한다.
+ 파라미터 전달 : requests를 사용하여 URL에 쿼리 문자열 형태로 파라미터를 전달할 수 있다.
requests.get(url, params={'key':'value'})
+ 요청 헤더 설정 : requests를 사용하여 요청 헤더에 필요한 정보(인증, 권한, 사용자 에이전트(User-Agent))
+ 응답 처리 : requests로 받은 응답 객체(Response Object)에서 상태 코드(status code), 헤더(header), 본문(body) 등의 정보에 접근할 수 있다.
+ 세션 관리 : requests.Session 클래스를 사용하여 세션을 유지하고, 요청 간의 쿠키와 같은 정보를 공유할 수 있다.
+ 파일 업로드 및 다운로드 : multipart/form-data 형식으로 파일을 업로드하거나 바이너리 데이터를 다운로드하는 등의 작업을 할 수 있다.
+ HTTPS 지원과 SSL 인증서 검증 : requests는 HTTPS 프로토콜을 지원하며, SSL 인증서 검증 기능도 제공한다.

2. urllib
파이썬 표준 라이브러리, URL 작업과 관련된 다양한 모듈을 제공한다.
urllib.request 모듈은 HTTP 요청을 보내고 응답을 처리하는 기능을 제공한다.
urllib.parse 모듈은 URL 구문 분석 및 조작에 사용된다.

1) urllib.request
+ urlpoen() 함수를 사용하여 URL에 대한 GET 요청을 보낼 수 있다.
+ Request 클래스를 사용하여 더 많은 컨트롤, 구성 옵션 등을 설정할 수 있다.
+ 응답 객체는 파일 객체와 유사한 인터페이스를 가지며, 상태 코드, 헤더, 본문 등의 정보에 접근할 수 있다.

2) urllib.parse 모듈
+ urlparse() 함수를  사용하여 URL 문자열을 구성요소(호스트, 스킴, 경로 등)로 분석할 수 있다.
+ urlunparse() 함수를 사용하여 구성요소로부터 URL 문자열을 생성할 수 있다.
+ 쿼리 문자열 파싱 및 조작 기능(parse_qs(), urlencode()) 제공한다.

3. http.client
파이썬 표준 라이브러리에 포함된 HTTP 클라이언트 라이브러리

1) HTTP 요청 보내기
+ http.client.HTTPConnection 클래스 사용하여 서버와의 연결을 설정한다.
+ request() 메서드를 사용하여 GET, POST, PUT, DELETE  등의 메서드로 HTTP 요청을 보낼 수 있다.
+ 헤더와 본문 데이터를 설정할 수 있다.

2) 응답 처리하기
+ getresponse() 메소드를 호출하여 서버로부터 받은 응답 객체(Response Object)를 가져온다.

3) 세션 관리
+ http.client.HTTPSConnection 클래스는 HTTPS 프로토콜을 지원하는 버전
+ SSL/TLS 연결 시 서버의 인증서가 신뢰할 수 있는지 확인을 하거나 인증서 설정 등의 작업을 할 수 있다.

4) 예외처리
+ 네트워크 오류나 잘못된 요청 등이 발생 가능한 상황에서 예외처리를 할 수 있다.
+ 주요 예외로는 http.cilent..HTTPException

4. Django 내장 웹 클라이언트
django.test.Client 클래스를 사용하여 Django 어플리케이션 내에서 테스트 및 시뮬레이션 목적으로 HTTP 요청을 만들 수 있다.
주로 테스트 프레임워크에서 사용되지만, 일반적인 웹 클라이언트로서도 활용할 수 있다.

1) HTTP 요청 보내기
+ get(), post(), put(), patch(), delete() 등의 메서드를 사용하여 HTTP 요청을 보낼 수 있다.
+ 필요한 경우 URL, 데이터, 헤더 등을 지정할 수 있다.

2) 응답 처리
+ 해당하는 HTTP 응답 객체를 반환한다.

3) 세션 유지
+ 한번 연결된 세션을 유지하고 여러 요청에 대해 동일한 세션 상태를 유지할 수 있다.

4) 폼 처리
+ post() 메소드를 사용하여 데이터를 제출할 수 있다. 이는 실제 브라우저 제출과 비슷한 동작을 한다.

 

웹 서버 라이브러리

http.server 모듈에 포함되어 있는 클래스
1. HTTPSever
+ http.server.HTTPSever 클래스는 기본적인 HTTP 서버를 구현하는데 사용된다.
+ TCP 소켓을 생성하고 요청을 수신하기 위해 지정된 IP 주소와 포트에 대기한다.
+ 요청이 들어오면 해당 요청을 처리할 핸들로 객체(BaseHTTPRequestHandler의 인스턴스)를 생성하여 처리한다.

2. BaseHTTPRequestHandler
+ http.server.BaseHTTPRequestHandler 클래스는 HTTP 요청을 처리하는 핵심 로직을 구현하는 추상클래스다.
+ 실제로 사용하기 위해서는 해당 클래스를 상속 받아서 사용자의 정의 핸들러 클래스를 작성해야 한다.

3. 주요 메서드
+ do_GET(): GET 요청에 대한 처리 로직을 구현한다.
+ do_POST() : POST 요청에 대한 처리 로직을 구현한다.
+ send_response(): 응답 상태 코드와 헤더 정보를 전송한다.
+ send_header() : 응답 헤더 정보를 전송한다.
+ end_headers() : 응답 헤더의 끝임을 알리는 빈줄(CRLF)를 전송한다.

4. SimpleHTTPRequestHandler
정적 파일을 제공하기 위한 간단한 HTTP 요청 처리기다. (개발 및 테스트용)
SimpleHTTPRequestHandler 는 BaseHTTPRequestHandler를 상속하며, 메서드들을 상속받아 정적 파일 서비스를 처리하는 추가 로직을 구현한다.

1) 정적 파일 서비스
+ 현대 작업 디렉토리에서 정적 파일(HTML, CSS, JavaScript, 이미지 등)을 제공한다.
+ GET 요청에 대해 요청된 파일이 존재하는 경우 해당 파일을 응답으로 보낸다.

2) Content-Type 자동설정
+ 요청된 파일의 확장자를 기반으로 Content-Type의 헤더 값을 자동으로 설정한다.
+ 예) .html 파일 -> /text/html,  .jpg -> image/jpg

3) Range 지원
+ Range 요청 헤더가 있는 경우 해당 범위 만큼의 데이터만 응답으로 보낼 수 있다.
+ 예) 다운로드 중 일부만 필요한 경우 -> 대용량 파일 전송, 스트리밍과 같은 상황에서 유용하다.

5. CGIHTTPRequestHandler (Common Gateway Interface)
CGI는 웹 서버와 외부 프로그램 간의 표준 인터페이스를 제공하여 동적인 웹 콘텐츠가 생성하는데 사용되고,
CGIHTTPRequestHandler는 CGI 프로그램을 실행하고 처리하기 위해 사용된다.
CGIHTTPRequestHandler는 BaseHTTPRequestHandler를 상속하며, CGI 스크립트를 실행하기 위한 추가 로직을 작성한다.

1) CGI 스크립트 실행
+ CGIHTTPRequestHandler는 클라이언트가 요청한 CGI 스크립트를 실행한다.
+ GET, POST 요청에 대한 환경 변수와 데이터(payload)를 설정하여 스크립트를 호출한다.
+ 스크립트의 실행 결과가 HTTP 응답으로 반환된다.

2) 환경 변수
+ 요청 메소드, URL 경로, 쿼리 문자열 등과 같은 정보가 환경 변수로 설정되어 CGI 스크립트에서 참조할 수 있다.
+ 이러한 환경 변수들은 on.environ 딕셔너리에 저장되어 전달된다.

3) 보안 검사
+ 기본적으로 CGIHTTPRequestHandler는 보안 검사를 수행하여 악성코드나 디렉토리 트래버셜(directory traversal) 공격을 방지한다.
+ 경로 검사, 접근 제어 등의 보안 기능도 내장되어 있다.
+ 500 Internal Error 오류 발생 시 내장된 오류 페이지를 출력한다.

 



웹 서버와 클라이언트는 HTTP 프로토콜을 사용하여 통신한다.
HTTP 응답 - 상태 줄(status line), 헤더(header), 빈 줄(blank line), 본문(body)

상태줄 : HTTP 버전, 상태코드, 상태 메시지
헤더 : 응답에 대한 추가 정보, (key:value) 형태로 이루어져 있다.
빈 줄 : 헤더와 본문 사이에 위치하며, 이것이 HTTP 요청의 끝을 나타낸다. 즉, 빈 줄이 있어야 헤더의 끝과 본문의 시작을 알 수 있다.

string : 널문자('\0') 문자열의 끝
HTTP 통신 : 빈 줄('\n') 요청의 끝

 

Django : Python 기반 오픈 소스 웹 어플리케이션 프레임워크

+ 프레임워크 : 장고가 웹 어플리케이션 개발에 많은 기능을 제공하고, 만드는 것을 효율적으로 돕는다.

+ 장고 장점
소규모, 대규모 범위 관계없이 웹 어플리케이션 개발에 사용된다. 
관리자 패널, 데이터베이스, 인터페이스, 인증 및 권한 설정 등과 같은 다양한 기능들이 내장되어있다.

 

MVC와 MTV

MVC(Model-View-Controller) 소프트웨어 디자인 패턴
Model : 데이터베이스와 상호작용하는 부분, 데이터를 처리하고 검증한다.
View : 사용자에게 보여지는 부분 (UI 로직)
Controller : 모델과 뷰 사이에서 정보를 주고 받으며, 전체적인 흐름 제어 (백엔드 담당)

MVC 패턴 : 관심사 분리(Separation of Concerns)
세가지 역할로 구분한 이유는 어플리케이션의 로직을 명확히 구분함으로써 코드의 유지보수성, 가독성을 높일 수 있다. 
Model : 어플리케이션 데이터와 비즈니스 로직을 처리하는 부분, CRUD(Create, Read, Update, Delete) 작업 등을 수행한다.
View : User Interface, 모델에서 처리된 데이터를 사용자에게 보여준다.사용자의 입력을 받는다. (클라이언트와 공유하는 친구)
Controller : 사용자의 입력을 전달받아서 해당 작업에 맞는 모델 함수를 호출하고, 그 결과를 다시 뷰에 전달한다.

MTV(Model-Template-View) : Django에서 사용하는 디자인 패턴
Model : 데이터베이스와 상호작용하는 부분, 데이터를 처리하고 검증한다.
Template : 사용자에게 보여지는 부분, HTML, Django 템플릿 언어를 사용하여 만든다.
View : 컨트롤러 역할, 사용자의 요청을 받아 적절한 모델을 호출하고, 데이터, 값 들을 최종적으로 템플릿에 전달하여 페이지 생성한다.

- Model
장고에서 Model은 데이터베이스의 구조를 python코드로 표현한 것이다.
각 모델은 하나의 데이터 베이스 테이블 해당하며, 모델의 속성(attributes)은 테이블 필드(columns)를 나타낸다.

from django.db imports models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    data = models.DataTimeField('data published')

CREATE TABLE my_post {
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(200) NOT NULL,
    "content" varchar(30),
    "date" date
}

Post라는 이름의 테이블을 데이터베이스 내에 생성한다.
title, content, date는 각각 문자열 필드, 텍스트 필드, 날짜/시간 필드에 대응되며 테이블에 columns 생성한다.


+ ORM(Object Realtional Mapping)
객체지향프로그래밍 언어와 데이터베이스 사이에 관계를 매핑하기 위한 기술이다.
장고는 자체적인 ORM 시스템을 보유하고 있어서, SQL 쿼리 없이 데이터베이스 작업을 할 수 있다.

from django.utills from timezone

post = Post(title="첫 글", content="내가 일등", date=timezone.now())
post.save()


+ 마이그레이션(migrations)
장고 모델 변경사항을 추적하고 이러한 변경사항을 실제 데이터베이스 스키마에 반영하기 위한 시스템이다.
python manage.py makemigrations
python manage.py migrate

 

+ 새로운 마이그레이션 생성
python manage.py makemigrations 앱이름 --empty
python manage.py migrate
python manage.py runserver

+ 마이그레이션 파일을 만들고 migrate 실행 이후 왜 다시 수정이 안될까?
마이그레이션은 Django에서 데이터베이스 스키마를 변경하는 작업을 추적하는 방법이다.
모델에 대한 변경 사항을 마이그레이션 파일로 생성한 후, migrate 적용하여 스키마를 업데이트한다.
새로운 데이터 생성, 삭제 등의 단순 작업들은 python 코드 수준에서만 이루어진다.
이러한 작업들은 데이터베이스 스키마에 영향을 줄 수가 없다.

 

URLs와 뷰

+ URLconf(URL configuration)는 특정 URL이 뷰와 어떻게 연결되는지 장고에게 알려준느 매커니즘
장고가 웹 요청을 받으면 이를 처리하기 위해 URLconf를 사용하여 해당 요청 URL을 기반으로 적절한 뷰를 찾는다.
URLconf은 urls.py에 정의되며, 이 파일은 프로젝트의 각 폴더 안에 모두 있을 수 있다.
urls.py 파일 안에서는 urlpatterns이라는 이름의 리스트 변수를 정의하여 URL 패턴과 뷰 함수/클래스 간의 매핑을 나타낸다.

from hello.views import hello_world

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', hello_world),
]
path 함수는 (첫 번째 인자가 URL 패턴 문자열, 

두번째 인자가 해당 URL에 대응하는 뷰 함수/클래스)를 받아서 하나의 경로(route)를 생성한다.
이렇게 생성된 경로들은 urlpatterns에 추가된다.


path('post/<int:id>/', post_detail),
<int:id> 장고 URL 패턴에서 동적 URL 패턴을 정의하는 방법이다.
1) int : URL의 일부분을 정수로 매칭한다.
2) str : URL의 일부븐을 비어 있지 않은 문자열로 매칭한다. 슬래시(/)는 포함되지 않는다.
3) slug : ASCII 문자, 숫자, 하이픈 또는 밑줄만 포함하는 문자열에 매칭한다.
4) uuid : UUID 형식의 문자열과 매칭한다. (16진수, 네트워크 관련)
5) path : 슬래시를 포함한 모든 문자열에 매칭된다.

 

뷰와 함수/클래스 연결

View는 장고에서 웹 요청을 받아 처리하고 응답을 반환하는 컴포넌트다. 뷰는 함수 형태(function-base view)나 클래스 형태(class-base view)로 작성한다.

+ Function-based view

from django.http import HttpResponse

def hello_world(request):
    return HttpResponse("Hello, World")
가장 기본적인 형태의 뷰, 하나의 파이썬 함수가 하나의 웹페이지에 대응한다.



+ class-based view

from django.http import HttpResponse
from django.views import View

class helloWorldView(View):
    def get(self, request):
        return HttpResponse("Hello, World")
유지보수성과 코드 구조화 등 여러 면에서 이점이 있는 클래스 기반의 뷰


+ 템플릿 시스템
장고 템플릿 언어(DTL : Django Template Language)와 템플릿 상속
장고에서 템플릿 언어는 HTML 코드에 동적 데이터를 삽입하거나 제어 구조(if, for 등)을 사용할 수 있게 해주는 템플릿 엔진이다.

DTL
<h1>Hrllo, {{name}}</h1>

<ul>
{% for item in itemlst %}
    <li>{{item}}</li>
{% endfor %}
</ul>



+ 템플릿 상속
템플릿 시스템에 상속이 존재한다.
여러 페이지에서 공유하는 기본 레이아웃을 한 번만 작성하고 이를 상속받아 각각의 페이지에서 추가해서 사용할 수 있다.

* parent.html

<!DOCTYPE HTML>
<html>
    <head>
        <title>{% block title %}Title{% endblock %}</title>
    </head>
    <body>
        {% block content %}

        {% endblock %}
    </body>
</html>


* child.html

{% extends 'parent.html' %}

{% block title %}
Home
{% endblock %}

{% block content %}
<p> Hello my HOME</p>
{% endblock %}

child.html 파일은 parent.html 파일을 상속받는다. (extends)
부모 템플릿에서 정의한 title 및 content 블록을 재정의하여 자신만의 내용을 추가한다. (block)


프로젝트 설계 -> 모델 정의 -> URL conf 지정 -> 템플릿 정의 -> 뷰 정의

 

뷰 함수

+ index() : 전체 질문 목록을 보여주는 페이지 처리
+ detail() : 하나의 질문에 대한 세부 정보 처리
+ vote() : 사용자의 투표를 처리하는 로직
+ results() : 특정 질문에 대한 투표 결과를 보여주는  페이지 처리

from django.http import HttpResponse
from django.shrotcuts import get_object_or_404, render

from models import Question

def index(request):
    lastest_q_list = Question.objects.order_by('-date')
    context = {'last Q' : lastest_q_list}
    return render(request, 'index.html', context)

def detail(request, quest_id) :
    question = get_object_or_404(Question, pk=quest_id)
    return render(request, 'detail.html', {'question': question})

def results(request, quest_id):
    question = get_object_or_404(Question, pk=quest_id)
    return render(request, 'detail.html', {'question': question})

def vote(request, quest_id):
    #logic