728x90

패키지 업그레이드 및 업데이트

sudo apt-get update
sudo apt-get upgrade

 

vsftpd 설치

sudo apt-get install vsftpd

 

설정 변경

sudo vim /etc/vsftpd.conf
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES

utf8_filesystem=YES

# port 변경
listen_port=45620  
pasv_min_port=45621
pasv_max_port=45622

 

 

SSL/TLS

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem



ssl_enable=YES
ssl_tlsv1=YES
implicit_ssl=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
728x90

'모음집 > Linux' 카테고리의 다른 글

[Ubuntu 20.04] MariaDB 11.3.2 설치  (4) 2024.03.12
[Linux] 리눅스 명령어 모음집 #1 / 우분투 /  (0) 2022.01.20
728x90

FastAPI ResponseBody Model 만들기


https://fastapi.tiangolo.com/ko/tutorial/response-model/

 

응답 모델 - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

 

 

1. ResponseModel

 

from typing import Optional, List

from pydantic import Field, BaseModel


class ResponseModel(BaseModel):
    msg:str = Field("", description="응답메세지")
    isOk:bool =  Field(True, description="응답 성공 여부")
    items:Optional[List[dict] | dict] = Field(None, description="응답 데이터")

 

 

2. ReponseModelPaging

 

class Paging(BaseModel):
    totalSize: int = Field(0, description="전체 갯수")
    totalPage: int = Field(0, description="전체 페이지 수")
    page: int = Field(1, description="현재 페이지")
    size: int = Field(10, description="출력 갯수")


class ResponseModelPaging(ResponseModel):
    paging: Paging = Field(Paging(), description="페이지 정보")

 

 

3. Genric Type

from typing import TypeVar, Generic
T = TypeVar("T")

class ResponseModel(BaseModel,Generic[T]):

 

 

4. Main

"""
main.py
@제목: 메인 실행 파일
@설명: 메인 실행 파일

    작성일자        작성자
-----------------------
    2024.03.14    hiio420

"""
import math
import os.path

from fastapi import FastAPI
from pydantic import BaseModel
from starlette.middleware.cors import CORSMiddleware

from libs import ExcelUtils
from models import ResponseModel, ResponseModelPaging, Paging

# 엑셀 파일 불러오기

CUR_DIR = os.path.abspath(os.path.dirname(__file__))
UPLOAD_DIR = os.path.join(CUR_DIR, 'upload')
file_path = os.path.join(UPLOAD_DIR, '(붙임)공공데이터 공통표준용어(2022.7월).xlsx')

excel_utils = ExcelUtils()
df_dict = excel_utils.read_excel(file_path)

app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


class Item(BaseModel):
    data_id: int = 0
    page: int = 1
    limit: int = 10


@app.get("/",response_model=ResponseModelPaging[dict])
def read_root(dataId: int = 0, page: int = 1, limit: int = 10, srchTxt: str = ""):
    if page < 1:
        page = 0
    if limit < 10:
        limit = 10
    df = df_dict[dataId]
    df = df[df.apply(lambda row: row.astype(str).str.contains(srchTxt, case=False).any(), axis=1)]

    first_idx = (page - 1) * limit
    last_idx = first_idx + limit - 1
    total_size = df.shape[0]
    last_page = math.ceil(total_size / limit)

    df_sliced = df[first_idx:last_idx + 1].copy()

    df_sliced["번호"] = [i for i in
                       range(total_size - (page - 1) * limit, total_size - (page - 1) * limit - df_sliced.shape[0], -1)]
    data = []
    if df_sliced.shape[0] != 0:
        data = df_sliced.to_dict("records")
    paging = Paging(page=page, size=limit, totalPage=last_page,totalSize=total_size)
    resp = ResponseModelPaging(items=data,paging=paging)
    print(resp)
    return resp
728x90
728x90

화면 만들어보기 #3 fetch 로 데이터 불러와서 뿌려주기


이제 이전에 만들었던 FastAPI 서버와 통신해 데이터를 가져와보자.

 

NextJs 는 13버전 에서 부터 SSG, SSR, ISR의 Data Fetching 을 fetch api 를 통해 사용 할 수 있게 되었다.

 

https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating

 

Data Fetching: Fetching, Caching, and Revalidating | Next.js

Learn how to fetch, cache, and revalidate data in your Next.js application.

nextjs.org

 

 

그렇다고 합니다.

 

우선은 깊게 알아보지는 않고 fetch 함수를 이용해 데이터를 불러옵니다.

 

export default async function Home() {

    const response =await fetch("http://localhost:4882");
    const data =await response.json();
    const items = data.data;
    console.info(items.length)
    
    ...

 

데이터가 잘 들어오는 것을 볼 수 있습니다.

 

이제 이 데이터를 가지고 이전에 그렸던 Data Table 부분을 처리해봅니다.

 

 

{items?.map((item:{[key:string]:string})=> {
    return <tr className="border-b border-neutral-200 dark:border-white/10" key={Math.random()}>
        <td className="whitespace-nowrap px-6 py-4 font-medium">{item["번호"]}</td>
        <td className="whitespace-nowrap px-6 py-4">{item[Object.keys(item)[1]]}</td>
        <td className="whitespace-nowrap px-6 py-4">{item[Object.keys(item)[2]]}</td>
        <td className="whitespace-nowrap px-6 py-4">{item[Object.keys(item)[3]]}</td>
    </tr>
})}

 

데이터가 잘 나오기는 하지만 아직 어영부영 어수선 해 보이네요 무엇을 중점적으로 볼지도 모르고 아직은 많이 부족합니다.

 

우선은 스타일 조정 부터 해줍니다.

 

form의 width 부터 main 태그에 맞춰 추기 위해 className 에 w-full을 주었습니다.

 

<form className={"w-full"}>
...

 

 

돋보기 아이콘이 search box 안에 있어야하는데 searchbox를 감사는 div의 너비가 form에 맞춰지면서 범위를 벗어나 버렸습니다.

 

div 너비를 width:max-content 값을 줘서 맞춰줍니다.

<div className="pt-2 relative mx-auto text-gray-600 w-px245 w-max">
...

 

 

 

가운데 있는 것보다는 왼쪽으로 정렬된 것이 보기 좋을 거 같아서 mx-auto는 지워버립니다.

 

<div className="pt-2 relative text-gray-600 w-px245 w-max">
...

 

얼추 만들어져 가는 모습이네요 

 

 

728x90

+ Recent posts