[TOOL/CURL] curl 명령 : HTTP POST 요청에서 신규 사용자 추가 요청하기
■ curl 명령을 사용해 HTTP POST 요청에서 신규 사용자 추가를 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을
■ curl 명령을 사용해 HTTP POST 요청에서 신규 사용자 추가를 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을
■ get 함수의 data 인자를 사용해 폼 URL 인코딩 방식으로 데이터를 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() dataDictionary = {"key1" : "value1", "key2" : "value2"} response = httpx.post("https://httpbin.org/post", data = dataDictionary) printResponse("FORM URL 인코딩 데이터 전달", response) """ FORM URL 인코딩 데이터 전달 response : <Response [200 OK]> response.url : https://httpbin.org/post response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 """ |
■ langserve 모듈을 사용해 langchain 모듈의 체인을 REST API 서버로 배포하는 방법을 보여준다. ▶ server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import os import uvicorn from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_openai import ChatOpenAI from fastapi import FastAPI from langserve import add_routes os.environ["OPENAI_API_KEY"] = "<OPENAI_API_KEY>" promptTemplate = ChatPromptTemplate.from_messages( [ ("system", "Translate the following into {language} : "), ("user" , "{text}" ) ] ) chatOpenAI = ChatOpenAI(model = "gpt-4") strOutputParser = StrOutputParser() runnableSequence = promptTemplate | chatOpenAI | strOutputParser fastAPI = FastAPI( title = "LangChain Server", version = "1.0", description = "A simple API server using LangChain's Runnable interfaces", ) add_routes( fastAPI, runnableSequence, path = "/chain", ) if __name__ == "__main__": uvicorn.run(fastAPI, host = "0.0.0.0", port = 8000) |
▶ client.py
1 2 3 4 5 6 7 8 9 |
from langserve import RemoteRunnable remoteRunnable = RemoteRunnable("http://localhost:8000/chain/") resultString = remoteRunnable.invoke({"language" : "korean", "text" : "hi"}) print(resultString) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
aiohttp==3.9.5 aiosignal==1.3.1 annotated-types==0.7.0 anyio==4.4.0 async-timeout==4.0.3 attrs==23.2.0 certifi==2024.6.2 charset-normalizer==3.3.2 distro==1.9.0 exceptiongroup==1.2.1 frozenlist==1.4.1 greenlet==3.0.3 h11==0.14.0 httpcore==1.0.5 httpx==0.27.0 idna==3.7 jsonpatch==1.33 jsonpointer==2.4 langchain==0.2.3 langchain-core==0.2.5 langchain-openai==0.1.8 langchain-text-splitters==0.2.1 langsmith==0.1.75 multidict==6.0.5 numpy==1.26.4 openai==1.33.0 orjson==3.10.3 packaging==23.2 pydantic==2.7.3 pydantic_core==2.18.4 PyYAML==6.0.1 regex==2024.5.15 requests==2.32.3 sniffio==1.3.1 SQLAlchemy==2.0.30 tenacity==8.3.0 tiktoken==0.7.0 tqdm==4.66.4 typing_extensions==4.12.2 urllib3==2.2.1 yarl==1.9.4 |
■ FastAPI 클래스의 add_middleware 메소드를 사용해 GZIP 압축 전송을 설정하는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import uvicorn from fastapi import FastAPI from fastapi.middleware.gzip import GZipMiddleware fastAPI = FastAPI() fastAPI.add_middleware(GZipMiddleware, minimum_size = 1000, compresslevel = 9) # compressionlevel 인자의 디폴트 값은 9로, 이를 낮출 경우 압축 효율은 떨어지지만 압축 속도는 빨라지게 된다. @fastAPI.get("/") async def getHelloWorld(): return {"message" : "Hello, World!"} if __name__ == "__main__": uvicorn.run("main:fastAPI", host = "0.0.0.1", port = 8000, reload = True) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
annotated-types==0.7.0 anyio==4.4.0 certifi==2024.6.2 click==8.1.7 dnspython==2.6.1 email_validator==2.1.1 exceptiongroup==1.2.1 fastapi==0.111.0 fastapi-cli==0.0.4 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 httpx==0.27.0 idna==3.7 Jinja2==3.1.4 markdown-it-py==3.0.0 MarkupSafe==2.1.5 mdurl==0.1.2 orjson==3.10.3 pydantic==2.7.3 pydantic_core==2.18.4 Pygments==2.18.0 python-dotenv==1.0.1 python-multipart==0.0.9 PyYAML==6.0.1 rich==13.7.1 shellingham==1.5.4 sniffio==1.3.1 starlette==0.37.2 typer==0.12.3 typing_extensions==4.12.1 ujson==5.10.0 uvicorn==0.30.1 uvloop==0.19.0 watchfiles==0.22.0 websockets==12.0 |
■ get 함수의 timeout 인자를 사용해 타임아웃 시간 설정하는 방법으로 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import requests def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = requests.get(url = "http://google.com", timeout = 1) # 1초 후 타임아웃 에러가 발생한다. printResponse("requests.get 호출 결과", response) """ requests.get 호출 결과 response : <Response [200]> response.url : http://www.google.com/ response.headers['content-type'] : text/html; charset=ISO-8859-1 response.encoding : ISO-8859-1 response.status_code : 200 """ |
▶ requirements.txt
1 2 3 4 5 6 7 |
certifi==2024.6.2 charset-normalizer==3.3.2 idna==3.7 requests==2.32.3 urllib3==2.2.1 |
■ get 함수를 사용해 HTTP GET 요청을 처리하는 방법으로 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import requests def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = requests.get(url = "http://google.com") printResponse("requests.get 호출 결과", response) """ requests.get 호출 결과 response : <Response [200]> response.url : http://www.google.com/ response.headers['content-type'] : text/html; charset=ISO-8859-1 response.encoding : ISO-8859-1 response.status_code : 200 """ |
▶ requirements.txt
1 2 3 4 5 6 7 |
certifi==2024.6.2 charset-normalizer==3.3.2 idna==3.7 requests==2.32.3 urllib3==2.2.1 |
■ FastAPI 클래스에서 JINJA 템플리트를 사용하는 방법을 보여준다. ▶ template/home.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta content="IE=edge" http-equiv="X-UA-Compatible" /> <meta content="width=device-width, initial-scale=1.0" name="viewport" /> <title>Packt Todo Application</title> <link crossorigin="anonymous" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" rel="stylesheet" /> <link crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" rel="stylesheet" /> </head> <body> <header> <nav class="navar"> <div class="container-fluid"> <center> <h1>Packt Todo Application</h1> </center> </div> </nav> </header> <body> <div class="container-fluid"> {% block todo_container %}{% endblock %} </div> </body> </html> |
▶ template/todo.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
{% extends "home.html" %} {% block todo_container %} <main class="container"> <hr> <section class="container-fluid"> <form method="post"> <div class="col-auto"> <div class="input-group mb-3"> <input name="item" class="form-control" type="text" aria-describedby="button-addon2" aria-label="Add a todo" placeholder="Purchase Packt's Python workshop course" value="{{ item }}" /> <button id="button-addon2" class="btn btn-outline-primary" type="submit" data-mdb-ripple-color="dark"> Add Todo </button> </div> </div> </form> </section> {% if todo %} <article class="card container-fluid"> <br/> <h4>Todo ID : {{ todo.id }} </h4> <p> <strong> Item : {{ todo.item }} </strong> </p> </article> {% else %} <section class="container-fluid"> <h2 align="center">Todos</h2> <br> <div class="card"> <ul class="list-group list-group-flush"> {% for todo in todoList %} <li class="list-group-item"> {{ loop.index }}. <a href="/todo/{{ loop.index }}"> {{ todo.item }} </a> </li> {% endfor %} </ul> </div> {% endif %} </section> </main> {% endblock %} |
▶ model.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
from typing import Optional, List from fastapi import Form from pydantic import BaseModel class Todo(BaseModel): id : Optional[int] item : str @classmethod def as_form(cls, item : str = Form(...)): return cls(item = item) class Config: json_schema_extra = { "example" : { "id" : 1, "item": "Example schema!" } } class TodoItem(BaseModel): item : str class Config: json_schema_extra = { "example" : { "item" : "Read the next chapter of the book" } } class TodoItemList(BaseModel): todoList : List[TodoItem] class Config: json_schema_extra = { "example" : { "todoList" : [ { "item" : "Example schema 1!" }, { "item" : "Example schema 2!" } ] } } |
▶ todo_router.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
from fastapi import APIRouter, Path, HTTPException, status, Request, Depends from fastapi.templating import Jinja2Templates from model import Todo, TodoItem, TodoItemList todoList = [] todoAPIRouter = APIRouter() jinja2Templates = Jinja2Templates(directory = "template/") @todoAPIRouter.post("/todo") async def addTodo(request : Request, todo : Todo = Depends(Todo.as_form)): todo.id = len(todoList) + 1 todoList.append(todo) return jinja2Templates.TemplateResponse( "todo.html", { "request" : request, "todoList" : todoList } ) @todoAPIRouter.get("/todo", response_model = TodoItemList) async def getTodo(request : Request): return jinja2Templates.TemplateResponse( "todo.html", { "request" : request, "todoList" : todoList } ) @todoAPIRouter.get("/todo/{todoID}") async def get_single_todo(request : Request, todoID : int = Path(..., title = "The ID of the todo to retrieve.")): for todo in todoList: if todo.id == todoID: return jinja2Templates.TemplateResponse( "todo.html", { "request" : request, "todo" : todo } ) raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, detail = "Todo with supplied ID doesn't exist") @todoAPIRouter.put("/todo/{todoID}") async def update_todo(request : Request, todoItem : TodoItem, todoID : int = Path(..., title="The ID of the todo to be updated.")) -> dict: for todo in todoList: if todo.id == todoID: todo.item = todoItem.item return {"message" : "Todo updated successfully."} raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, detail = "Todo with supplied ID doesn't exist") @todoAPIRouter.delete("/todo/{todoID}") async def delete_single_todo(request : Request, todoID : int) -> dict: for index in range(len(todoList)): todo = todoList[index] if todo.id == todoID: todoList.pop(index) return {"message" : "Todo deleted successfully."} raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, detail = "Todo with supplied ID doesn't exist") @todoAPIRouter.delete("/todo") async def deleteTodoList() -> dict: todoList.clear() return {"message" : "Todos deleted successfully."} |
▶ main.py
■ python-multipart 패키지를 설치하는 방법을 보여준다. 1. 명령 프롬프트를 실행한다. 2. 명령 프롬프트에서 아래 명령을 실행한다. ▶ 실행 명령
1 2 3 |
pip install python-multipart |
■ get 함수의 auth 인자를 사용해 다이제스트 인증 자격 증명을 제공하는 방법을 보여준다. (DigestAuth 객체 전달) ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() digestAuth = httpx.DigestAuth("user1", "1234") response = httpx.get("https://example.com", auth = digestAuth) printResponse("다이제스트 인증 자격 증명 제공하기", response) """ 다이제스트 인증 자격 증명 제공하기 response : <Response [200 OK]> response.url : https://example.com response.headers['content-type'] : text/html; charset=UTF-8 response.encoding : UTF-8 response.status_code : 200 """ |
■ get 함수의 auth 인자를 사용해 기본 인증 자격 증명을 제공하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = httpx.get("https://example.com", auth = ("user1", "1234")) printResponse("기본 인증 자격 증명 제공하기", response) """ 기본 인증 자격 증명 제공하기 response : <Response [200 OK]> response.url : https://example.com response.headers['content-type'] : text/html; charset=UTF-8 response.encoding : UTF-8 response.status_code : 200 """ |
■ Cookies 함수를 사용해 Cookies 객체를 HTTP 호출시 쿠키 값으로 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() cookies = httpx.Cookies() cookies.set("cookie_on_domain" , "hello, there!", domain = "httpbin.org") cookies.set("cookie_off_domain", "nope" , domain = "example.org") response = httpx.get('http://httpbin.org/cookies', cookies = cookies) printResponse("HTTP 호출시 Cookies 객체를 쿠키 값으로 전달하기", response) print(f" response.json() : {response.json()}") """ HTTP 호출시 Cookies 객체를 쿠키 값으로 전달하기 response : <Response [200 OK]> response.url : http://httpbin.org/cookies response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 response.json() : {'cookies': {'cookie_on_domain': 'hello, there!'}} """ |
■ get 함수의 cookies 인자를 사용해 HTTP 호출시 쿠키 값을 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() cookieDictionary = {"cookie1" : "value1"} response = httpx.get('https://httpbin.org/cookies', cookies = cookieDictionary) printResponse("HTTP 호출시 쿠키 값 전달하기", response) print(f" response.json() : {response.json()}") """ HTTP 호출시 쿠키 값 전달하기 response : <Response [200 OK]> response.url : https://httpbin.org/cookies response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 response.json() : {'cookies': {'cookie1': 'value1'}} """ |
■ Response 클래스의 cookies 변수를 사용해 HTTP 응답시 쿠키 값을 구하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = httpx.get('https://httpbin.org/cookies/set?chocolate=chip') printResponse("응답시 쿠키 값 구하기", response) print(f" response.cookies['chocolate'] : {response.cookies['chocolate']}") """ 응답시 쿠키 값 구하기 response : <Response [302 FOUND]> response.url : https://httpbin.org/cookies/set?chocolate=chip response.headers['content-type'] : text/html; charset=utf-8 response.encoding : utf-8 response.status_code : 302 response.cookies['chocolate'] : chip """ |
■ Response 클래스의 raise_for_status 메소드를 사용해 에러를 발생시키는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
from httpx import get, codes def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = get("https://httpbin.org/status/404") printResponse("404 에러 수신시 에러 발생시키기", response) if(response.status_code == codes.NOT_FOUND): response.raise_for_status() """ 404 에러 수신시 에러 발생시키기 response : <Response [404 NOT FOUND]> response.url : https://httpbin.org/status/404 response.headers['content-type'] : text/html; charset=utf-8 response.encoding : utf-8 response.status_code : 404 Traceback (most recent call last): File "/home/king/testproject/main2.py", line 18, in <module> response.raise_for_status() File "/home/king/testproject/env/lib/python3.10/site-packages/httpx/_models.py", line 1510, in raise_for_status raise HTTPStatusError(message, request=request, response=self) httpx.HTTPStatusError: Client error '404 NOT FOUND' for url 'https://httpbin.org/status/404' For more information check: https://httpstatuses.com/404 """ |
■ Response 클래스의 status_code 변수 전체 값을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
from httpx import codes # codes 클래스는 IntEnum 클래스를 상속받았다. print(codes.OK) """ 200 """ # informational CONTINUE = 100, #Continue SWITCHING_PROTOCOLS = 101, #Switching Protocols PROCESSING = 102, #Processing EARLY_HINTS = 103, #Early Hints # succes# OK = 200, #OK CREATED = 201, #Created ACCEPTED = 202, #Accepted NON_AUTHORITATIVE_INFORMATION = 203, #Non-Authoritative Information NO_CONTENT = 204, #No Content RESET_CONTENT = 205, #Reset Content PARTIAL_CONTENT = 206, #Partial Content MULTI_STATUS = 207, #Multi-Status ALREADY_REPORTED = 208, #Already Reported IM_USED = 226, #IM Used # redirection MULTIPLE_CHOICES = 300, #Multiple Choices MOVED_PERMANENTLY = 301, #Moved Permanently FOUND = 302, #Found SEE_OTHER = 303, #See Other NOT_MODIFIED = 304, #Not Modified USE_PROXY = 305, #Use Proxy TEMPORARY_REDIRECT = 307, #Temporary Redirect PERMANENT_REDIRECT = 308, #Permanent Redirect # client error BAD_REQUEST = 400, #Bad Request UNAUTHORIZED = 401, #Unauthorized PAYMENT_REQUIRED = 402, #Payment Required FORBIDDEN = 403, #Forbidden NOT_FOUND = 404, #Not Found METHOD_NOT_ALLOWED = 405, #Method Not Allowed NOT_ACCEPTABLE = 406, #Not Acceptable PROXY_AUTHENTICATION_REQUIRED = 407, #Proxy Authentication Required REQUEST_TIMEOUT = 408, #Request Timeout CONFLICT = 409, #Conflict GONE = 410, #Gone LENGTH_REQUIRED = 411, #Length Required PRECONDITION_FAILED = 412, #Precondition Failed REQUEST_ENTITY_TOO_LARGE = 413, #Request Entity Too Large REQUEST_URI_TOO_LONG = 414, #Request-URI Too Long UNSUPPORTED_MEDIA_TYPE = 415, #Unsupported Media Type REQUESTED_RANGE_NOT_SATISFIABLE = 416, #Requested Range Not Satisfiable EXPECTATION_FAILED = 417, #Expectation Failed IM_A_TEAPOT = 418, #I'm a teapot MISDIRECTED_REQUEST = 421, #Misdirected Request UNPROCESSABLE_ENTITY = 422, #Unprocessable Entity LOCKED = 423, #Locked FAILED_DEPENDENCY = 424, #Failed Dependency TOO_EARLY = 425, #Too Early UPGRADE_REQUIRED = 426, #Upgrade Required PRECONDITION_REQUIRED = 428, #Precondition Required TOO_MANY_REQUESTS = 429, #Too Many Requests REQUEST_HEADER_FIELDS_TOO_LARGE = 431, #Request Header Fields Too Large UNAVAILABLE_FOR_LEGAL_REASONS = 451, #Unavailable For Legal Reasons # server errors INTERNAL_SERVER_ERROR = 500, #Internal Server Error NOT_IMPLEMENTED = 501, #Not Implemented BAD_GATEWAY = 502, #Bad Gateway SERVICE_UNAVAILABLE = 503, #Service Unavailable GATEWAY_TIMEOUT = 504, #Gateway Timeout HTTP_VERSION_NOT_SUPPORTED = 505, #HTTP Version Not Supported VARIANT_ALSO_NEGOTIATES = 506, #Variant Also Negotiates INSUFFICIENT_STORAGE = 507, #Insufficient Storage LOOP_DETECTED = 508, #Loop Detected NOT_EXTENDED = 510, #Not Extended NETWORK_AUTHENTICATION_REQUIRED = 511, #Network Authentication Required |
■ post 함수의 files 인자를 사용해 MULTIPART 방식으로 파일을 업로드하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() fileDictionary = {"upload-file" : open("./main.py", "rb")} response = httpx.post("https://httpbin.org/post", files = fileDictionary) printResponse("MULTIPART 인코딩 방식으로 파일 업로드", response) """ MULTIPART 인코딩 방식으로 파일 업로드 response : <Response [200 OK]> response.url : https://httpbin.org/post response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 """ |
■ post 함수의 json 인자를 사용해 JSON 데이터를 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() jsonDictionary = { "value1" : 123, "value2" : True, "value3" : ["a", "b", "c"] } response = httpx.post("https://httpbin.org/post", json = jsonDictionary) printResponse("JSON 데이터 전달", response) """ JSON 데이터 전달 response : <Response [200 OK]> response.url : https://httpbin.org/post response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 """ |
■ get 함수에서 headers 인자를 사용해 커스텀 헤더를 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() headerDictionary = { "user-agent" : "my-app/0.0.1", "accept" : "application/json", "content-type" : "text/html; charset=utf-8" } response = httpx.get("https://httpbin.org/headers", headers = headerDictionary) printResponse("사용자 정의 헤더 전달", response) import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() headerDictionary = { "user-agent" : "my-app/0.0.1", "accept" : "application/json", "content-type" : "text/html; charset=utf-8" } response = httpx.get("https://httpbin.org/headers", headers = headerDictionary) printResponse("사용자 정의 헤더 전달", response) """ 사용자 정의 헤더 전달 response : <Response [200 OK]> response.url : https://httpbin.org/headers response.headers['content-type'] : application/json response.encoding : utf_8 response.status_code : 200 """ |
■ get 함수의 params 인자에서 리스트 값을 쿼리 문자열로 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() parameterDictionary = {"key1" : "value1", "key2" : ["value2", "value3"]} response = httpx.get("https://httpbin.org/get", params = parameterDictionary) printResponse("쿼리 문자열에서 리스트 값 전달", response) """ 쿼리 문자열에서 리스트 값 전달 response : <Response [200 OK]> response.url : https://httpbin.org/get?key1=value1&key2=value2&key2=value3 response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 """ |
■ get 함수에서 params 인자를 사용해 쿼리 문자열 전달하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() parameterDictonary = {"key1" : "value1", "key2" : "value2"} response = httpx.get("https://httpbin.org/get", params = parameterDictonary) printResponse("쿼리 문자열 전달", response) """ 쿼리 문자열 전달 response : <Response [200 OK]> response.url : https://httpbin.org/get?key1=value1&key2=value2 response.headers['content-type'] : application/json response.encoding : ascii response.status_code : 200 """ |
■ get/put/delete/head/options 함수를 사용해 GET/PUT/DELETE/HEAD/OPTIONS 방식으로 HTTP 호출하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import httpx def printResponse(title, response): print(title ) print(f" response : {response}" ) print(f" response.url : {response.url}" ) print(f" response.headers['content-type'] : {response.headers['content-type']}") print(f" response.encoding : {response.encoding}" ) print(f" response.status_code : {response.status_code}" ) #print(f" response.text : {response.text}" ) print() response = httpx.get("https://httpbin.org/get") printResponse("GET https://httpbin.org/get", response) response = httpx.put("https://httpbin.org/put", data = {"key" : "value"}) printResponse("PUT https://httpbin.org/put", response) response = httpx.delete("https://httpbin.org/delete") printResponse("DELETE https://httpbin.org/delete", response) response = httpx.head("https://httpbin.org/get") printResponse("HEAD https://httpbin.org/get", response) response = httpx.options("https://httpbin.org/get") printResponse("OPTIONS https://httpbin.org/get", response) |
▶ 실행 결과
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
GET https://httpbin.org/get response : <Response [200 OK]> response.url : https://httpbin.org/get response.status_code : 200 response.encoding : ascii response.headers['content-type'] : application/json PUT https://httpbin.org/put response : <Response [200 OK]> response.url : https://httpbin.org/put response.status_code : 200 response.encoding : ascii response.headers['content-type'] : application/json DELETE https://httpbin.org/delete response : <Response [200 OK]> response.url : https://httpbin.org/delete response.status_code : 200 response.encoding : ascii response.headers['content-type'] : application/json HEAD https://httpbin.org/get response : <Response [200 OK]> response.url : https://httpbin.org/get response.status_code : 200 response.encoding : None response.headers['content-type'] : application/json OPTIONS https://httpbin.org/get response : <Response [200 OK]> response.url : https://httpbin.org/get response.status_code : 200 response.encoding : utf-8 response.headers['content-type'] : text/html; charset=utf-8 |
■ httpx 패키지를 설치하는 방법을 보여준다. 1. 명령 프롬프트를 실행한다. 2. 명령 프롬프트에서 아래 명령을 실행한다. ▶ 실행 명령
1 2 3 4 5 6 7 8 9 |
pip install httpx # HTTP/2 지원시 pip install httpx[http2] # Brotli Decoder 지원시 pip install httpx[brotli] |
■ FastAPI 클래스의 add_middleware 메소드를 사용해 CORS 미들웨어를 추가하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware fastAPI = FastAPI() fastAPI.add_middleware( CORSMiddleware, allow_origins = ["*"], allow_credentials = True, allow_methods = ["*"], allow_headers = ["*"], ) |
■ FastAPI 클래스를 사용해 JWT 인증 애플리케이션을 만드는 방법을 보여준다. (MongoDB 연동) ▶ .env
1 2 3 4 |
DATABASE_URL=mongodb://localhost:27017/testdb SECRET_KEY=pass1234567 |
※ testdb : MongoDB 데이터베이스명 ※ pass1234567
■ RedirectResponse 클래스를 사용해 리다이렉션을 설정하는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from fastapi import FastAPI from fastapi.responses import RedirectResponse import uvicorn fastAPI = FastAPI() @fastAPI.get("/") async def home(): return RedirectResponse(url = "/home/") @fastAPI.get("/home") def home(): return {"message" : "home"} if __name__ == "__main__": uvicorn.run("main:fastAPI", host = "0.0.0.0", port = 8000, reload = True) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
annotated-types==0.7.0 anyio==4.3.0 certifi==2024.2.2 click==8.1.7 dnspython==2.6.1 email_validator==2.1.1 exceptiongroup==1.2.1 fastapi==0.111.0 fastapi-cli==0.0.4 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 httpx==0.27.0 idna==3.7 Jinja2==3.1.4 markdown-it-py==3.0.0 MarkupSafe==2.1.5 mdurl==0.1.2 orjson==3.10.3 pydantic==2.7.1 pydantic_core==2.18.2 Pygments==2.18.0 python-dotenv==1.0.1 python-multipart==0.0.9 PyYAML==6.0.1 rich==13.7.1 shellingham==1.5.4 sniffio==1.3.1 starlette==0.37.2 typer==0.12.3 typing_extensions==4.11.0 ujson==5.10.0 uvicorn==0.29.0 uvloop==0.19.0 watchfiles==0.21.0 websockets==12.0 |