<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Daily Develope</title>
    <link>https://noggame.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 02:26:24 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>noggame</managingEditor>
    <image>
      <title>Daily Develope</title>
      <url>https://tistory1.daumcdn.net/tistory/5081237/attach/cbafe7f0ee214fb8a433b3231a947f8d</url>
      <link>https://noggame.tistory.com</link>
    </image>
    <item>
      <title>[Ubuntu] 사용자 관리</title>
      <link>https://noggame.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;신규 사용자 추가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용자 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764640699508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 사용자 생성
useradd -m {사용자명}

// 사용자 생성 + 로그인 시 entrypoint 지정
useradd -m -s /bin/bash {사용자명}

// 사용자 생성 + 로그인 시 entrypoint 지정 + home dir 설정
useradd -m -d /home/{사용자명} -s /bin/bash {사용자명}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비밀번호 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764641526780&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;passwd {사용자명}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기존 사용자 변경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;권한 부여&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1764641538161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;usermod -aG sudo {사용자명}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- sudo 그룹 권한을 {사용자명} 에게 부여&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 부여된 권한 확인 : &amp;nbsp;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;$ groups {사용자명}&lt;/span&gt;&lt;/p&gt;</description>
      <category>OS/Linux</category>
      <category>Linux</category>
      <category>ubuntu</category>
      <category>user</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/125</guid>
      <comments>https://noggame.tistory.com/125#entry125comment</comments>
      <pubDate>Tue, 2 Dec 2025 11:13:58 +0900</pubDate>
    </item>
    <item>
      <title>[React] React 및 Next.js 기본 내용 정리</title>
      <link>https://noggame.tistory.com/124</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[React]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 (프론트엔드) 개발을 위한 JavaScript library로, 동적 웹앱 구성을 위한 SPA(Single Page Application)를 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;* SPA : 사용자와의 상호작용에서 신규 페이지를 로드하는 것이 아니라 단일 페이지에서 동적으로 처리하는 app.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 가상 DOM 을 사용해 상태(state) 변경에 따라 가상 DOM을 수정하고 실제 DOM으로 이식하는 과정을 통해 처리 속도를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;바인딩&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이벤트 핸들러 사용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;class 컴포넌트의 method&lt;/b&gt; : 바인딩 필요&lt;/p&gt;
&lt;pre id=&quot;code_1764406525363&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Button extends React.Component {
  constructor(props) {
    super(props);

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    console.log('Button clicked');
  }

  render() {
    return &amp;lt;button onClick={this.handleClick}&amp;gt;Click me&amp;lt;/button&amp;gt;;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;functional 컴포넌트의 함수&lt;/b&gt; : 자동 바인딩&lt;/p&gt;
&lt;pre id=&quot;code_1764406597840&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Button(props) {
  function handleClick(event) {
    console.log('Button clicked');
  }

  return &amp;lt;button onClick={handleClick}&amp;gt;Click me&amp;lt;/button&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Hooks&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;functional 컴포넌트에서도 상태(state) 관리와 생명주기(lifecycle) 기능을 사용할 수 있도록 해주는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;자주 사용되는 Hooks&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;useState&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764407922540&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const [count, setCount] = useState(0);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- useState로 count 값을 초기화하고, setCount를 사용해 count 값을 조정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;useEffect&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764407989803&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  console.log('컴포넌트 렌더링 후 실행');
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 랜더링 이후 정의된 function을 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- [] 목록에 특정 상태를 넣으면, 해당 상태가 변경될 때 마다 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;useContext&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 상태처럼 데이터를 공유할 수 있도록 하는 Hook입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764408392410&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &amp;lt;&amp;lt;ThemeContext.js&amp;gt;&amp;gt;
import React from &quot;react&quot;;

const ThemeContext = React.createContext(&quot;light&quot;); // Context 생성 (기본값: light)

export default ThemeContext;


// &amp;lt;&amp;lt;App.jsx&amp;gt;&amp;gt;
import React from &quot;react&quot;;
import ThemeContext from &quot;./ThemeContext&quot;;
import ThemeButton from &quot;./ThemeButton&quot;;

function App() {
  return (
    // Provider: value로 전달할 데이터 제공
    &amp;lt;ThemeContext.Provider value=&quot;dark&quot;&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Context Provider / Consumer Example&amp;lt;/h1&amp;gt;
        &amp;lt;ThemeButton /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/ThemeContext.Provider&amp;gt;
  );
}

export default App;


// &amp;lt;&amp;lt;ThemeButton.jsx&amp;gt;&amp;gt;
import React, { useContext } from &quot;react&quot;;
import ThemeContext from &quot;./ThemeContext&quot;;

function ThemeButton() {
  const theme = useContext(ThemeContext);
  return &amp;lt;button&amp;gt;Current Theme: {theme}&amp;lt;/button&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하위 어떠한 컴포넌트에서나, Provider를 통해 제공하는 값을 불러와 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값을 제공하기 위해서는, 초기 상태와 값을 지정하거나 {컴포넌트}.Provider를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값을 사용하기 위해서는, ThemeContext.Consumer로 직접 불러오거나, useContext hook을 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;useRef&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM에 직접 접근하거나, 랜더링 사이 값을 유지하기 위해 사용합니다. (상태값은 랜더링될 때 마다 변할 수 있음)&lt;/p&gt;
&lt;pre id=&quot;code_1764409025392&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { useRef, useState } from &quot;react&quot;;

function Count() {
  const [count, setCount] = useState(0);
  const renderCount = useRef(0);

  renderCount.current += 1; // 렌더될 때마다 증가

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;state count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;render count: {renderCount.current}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- renderCount 값은 랜더링 될 때 마다 1씩 증가한 값을 유지하지만, useState는 페이지 재로드 시 0 값으로 변경됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Functions&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;map&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리스트 순환하며 내부 로직 실행&lt;/p&gt;
&lt;pre id=&quot;code_1764410123256&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
  const list = [&quot;사과&quot;, &quot;바나나&quot;, &quot;포도&quot;];

  return (
    &amp;lt;ul&amp;gt;
      {list.map((item, index) =&amp;gt; (
        &amp;lt;li key={index}&amp;gt;{item}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- unordered list에 &quot;사과&quot;, &quot;바나나&quot;, &quot;포도&quot; list item 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PropTypes&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 properties의 타입을 지정하는데 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764479755017&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from &quot;react&quot;;
import PropTypes from &quot;prop-types&quot;;

function MyButton({ label, count, onClick }) {
  return (
    &amp;lt;button onClick={onClick}&amp;gt;
      {label} - {count}
    &amp;lt;/button&amp;gt;
  );
}

//   PropTypes 선언
MyButton.propTypes = {
  label: PropTypes.string.isRequired,   // 필수 문자열
  count: PropTypes.number,              // 숫자
  onClick: PropTypes.func,              // 함수
};

//   기본값 설정 (선택)
MyButton.defaultProps = {
  count: 0,
  onClick: () =&amp;gt; console.log(&quot;clicked&quot;),
};

export default MyButton;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MyButton은 label 문자열 속성을 반드시 입력받아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- number, func 속성은 선택적으로 입력할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패턴&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HOC (Higher-Order Component)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Componet를 입력받아 추가 로직 구현 후 해당 Component를 반환하는, Component 재사용을 위한 패턴입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플) withLoading HOC를 사용해 페이지 로딩에 대한 로직을 대상 Component에 적용&lt;/p&gt;
&lt;pre id=&quot;code_1764485211536&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &amp;lt;&amp;lt;withLoading.js&amp;gt;&amp;gt;
import React from &quot;react&quot;;

// HOC: WrappedComponent를 받아서 새 컴포넌트를 리턴
function withLoading(WrappedComponent) {
  return function EnhancedComponent({ isLoading, ...props }) {
    if (isLoading) {
      return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
    }

    // isLoading을 제외한 나머지 props 전달
    return &amp;lt;WrappedComponent {...props} /&amp;gt;;
  };
}

export default withLoading;


// &amp;lt;&amp;lt;UserInfo.jsx&amp;gt;&amp;gt;
function UserInfo({ name }) {
  return &amp;lt;div&amp;gt;User: {name}&amp;lt;/div&amp;gt;;
}

export default UserInfo;


// &amp;lt;&amp;lt;App.jsx&amp;gt;&amp;gt;
import React from &quot;react&quot;;
import withLoading from &quot;./withLoading&quot;;
import UserInfo from &quot;./UserInfo&quot;;

const UserInfoWithLoading = withLoading(UserInfo);  // UserInfo에 로딩 기능을 추가한 새 컴포넌트 생성

function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;HOC Example&amp;lt;/h1&amp;gt;

      &amp;lt;UserInfoWithLoading
        isLoading={true}
        name=&quot;Alice&quot;
      /&amp;gt;

      &amp;lt;UserInfoWithLoading
        isLoading={false}
        name=&quot;Bob&quot;
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- withLoading Componet에서는 어떠한 isLoading prop을 입력받아, 해당 상태가 true인 경우 &quot;Loading...&quot; text 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[Next.js]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 기반으로 한 프레임워크로, 풀스택(프론트엔드 &amp;amp; 백엔드) 웹 개발을 위한 솔루션을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 특성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Rendering&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CSR (Client-Side Rendering) : 사용자 브라우저에서 랜더링을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSR (Server-Side Rendering) : 서버에서 랜더링을 진행하고, 하이드레이션(Hydration)으로 클라이언트에 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSG (Static Site Generation) : 빌드 타임에 페이지를 생성해 로딩시간을 줄입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[참고]&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위키독스 : &lt;a href=&quot;https://wikidocs.net/197619&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/197619&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Develope/Web</category>
      <category>react</category>
      <category>TypeScript</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/124</guid>
      <comments>https://noggame.tistory.com/124#entry124comment</comments>
      <pubDate>Sat, 29 Nov 2025 18:43:15 +0900</pubDate>
    </item>
    <item>
      <title>[Pydantic] pydantic 샘플코드 및 설명</title>
      <link>https://noggame.tistory.com/123</link>
      <description>&lt;h1&gt;소개&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pydantic은 Python에서 데이터 유효성 검사와 타입 기반 모델링을 지원하는 라이브러리로, 주로 API 개발, 환경 변수 관리, 데이터 파이프라인 등 다양한 분야에서 사용됩니다. FastAPI와 같은 웹 프레임워크에서 입력 데이터를 자동으로 검증하는 데 매우 널리 활용됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 장점&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;자동 데이터 검증&lt;/b&gt;: 타입 힌트만으로 자동 검증&lt;/li&gt;
&lt;li&gt;&lt;b&gt;명확한 오류 메시지&lt;/b&gt;: 검증 실패 시 구체적인 오류 정보 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타입 안전성&lt;/b&gt;: IDE에서 자동완성과 타입 체크 지원&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JSON 호환성&lt;/b&gt;: 웹 API 개발에 최적화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;: 복잡한 비즈니스 로직도 쉽게 구현 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;샘플코드 및 설명&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 기본 BaseModel 예시 (&lt;code&gt;User&lt;/code&gt; 클래스)&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;class User(BaseModel):
    id: int
    name: str
    email: str
    age: int
    is_active: bool = True  # 기본값 설정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pydantic의 가장 기본적인 사용법입니다&lt;/li&gt;
&lt;li&gt;타입 힌트를 사용하여 각 필드의 데이터 타입을 정의합니다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;is_active&lt;/code&gt; 필드처럼 기본값을 설정할 수 있습니다&lt;/li&gt;
&lt;li&gt;자동으로 데이터 검증이 수행됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 필드 검증과 제약 조건 예시 (&lt;code&gt;Product&lt;/code&gt; 클래스)&lt;/h3&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;class Product(BaseModel):
    id: int = Field(gt=0, description=&quot;상품 ID는 양수여야 합니다&quot;)
    name: str = Field(min_length=1, max_length=100, description=&quot;상품명&quot;)
    price: float = Field(gt=0, description=&quot;가격은 양수여야 합니다&quot;)
    category: str = Field(pattern=r'^[A-Za-z\s]+$', description=&quot;카테고리는 영문자와 공백만 허용&quot;)
    tags: List[str] = Field(default_factory=list, description=&quot;상품 태그 목록&quot;)
    metadata: Dict[str, Any] = Field(default_factory=dict, description=&quot;추가 메타데이터&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Field()&lt;/code&gt; 함수를 사용하여 다양한 검증 규칙을 설정합니다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gt=0&lt;/code&gt;: greater than 0 (0보다 큰 값)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min_length&lt;/code&gt;, &lt;code&gt;max_length&lt;/code&gt;: 문자열 길이 제한&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pattern&lt;/code&gt;: 정규표현식을 사용한 문자열 패턴 검증&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default_factory&lt;/code&gt;: 복잡한 기본값 생성 (리스트, 딕셔너리 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 중첩 모델 예시 (&lt;code&gt;Address&lt;/code&gt;, &lt;code&gt;Customer&lt;/code&gt; 클래스)&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;class Address(BaseModel):
    street: str
    city: str
    country: str
    postal_code: str

class Customer(BaseModel):
    id: int
    name: str
    email: EmailStr  # 이메일 형식 자동 검증
    address: Address
    phone: Optional[str] = None  # 선택적 필드
    created_at: datetime = Field(default_factory=datetime.now)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 안에 다른 모델을 중첩하여 사용할 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EmailStr&lt;/code&gt;: 이메일 형식을 자동으로 검증하는 특수 타입&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Optional[str]&lt;/code&gt;: 선택적 필드 (None 값 허용)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;datetime.now&lt;/code&gt;: 현재 시간을 기본값으로 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 커스텀 검증자 예시 (&lt;code&gt;Order&lt;/code&gt; 클래스)&lt;/h3&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;class Order(BaseModel):
    @field_validator('status')
    @classmethod
    def validate_status(cls, v):
        allowed_statuses = ['pending', 'confirmed', 'shipped', 'delivered', 'cancelled']
        if v not in allowed_statuses:
            raise ValueError(f'상태는 {allowed_statuses} 중 하나여야 합니다')
        return v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;@field_validator&lt;/code&gt; 데코레이터를 사용하여 커스텀 검증 로직을 작성합니다&lt;/li&gt;
&lt;li&gt;복잡한 비즈니스 규칙을 구현할 수 있습니다&lt;/li&gt;
&lt;li&gt;검증 실패 시 &lt;code&gt;ValueError&lt;/code&gt;를 발생시킵니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 설정 클래스 예시 (&lt;code&gt;ConfigModel&lt;/code&gt; 클래스)&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;class ConfigModel(BaseModel):
    model_config = ConfigDict(
        env_file=&quot;.env&quot;,
        env_prefix=&quot;APP_&quot;,
        case_sensitive=False
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;ConfigDict&lt;/code&gt;를 사용하여 모델의 동작을 설정합니다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;env_file&lt;/code&gt;: 환경 변수를 파일에서 읽어옵니다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;env_prefix&lt;/code&gt;: 환경 변수 이름에 접두사를 추가합니다&lt;/li&gt;
&lt;li&gt;환경 변수와 모델 필드를 자동으로 연결합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. JSON 직렬화/역직렬화&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# 모델을 JSON으로 변환
user_json = user.model_dump_json()

# JSON에서 모델로 변환
user_dict = json.loads(user_json)
user_from_json = User(**user_dict)

# 딕셔너리로 변환
user_dict = user.model_dump()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;model_dump_json()&lt;/code&gt;: 모델을 JSON 문자열로 변환&lt;/li&gt;
&lt;li&gt;&lt;code&gt;model_dump()&lt;/code&gt;: 모델을 딕셔너리로 변환&lt;/li&gt;
&lt;li&gt;JSON이나 딕셔너리에서 모델을 생성할 수 있습니다&lt;/li&gt;
&lt;li&gt;API 통신이나 데이터 저장에 매우 유용합니다&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Develope/Python</category>
      <category>Pydantic</category>
      <category>Python</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/123</guid>
      <comments>https://noggame.tistory.com/123#entry123comment</comments>
      <pubDate>Tue, 14 Oct 2025 21:47:47 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Set, List</title>
      <link>https://noggame.tistory.com/122</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Set&lt;/h3&gt;
&lt;pre id=&quot;code_1753102947547&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 선언 (declaration)
set1 = set([1, 2, 3])
set2 = set(&quot;hello&quot;)
print(set1)		# {1, 2, 3}
print(set2)		# {'h', 'l', 'o', 'e'}

# 추가 (add)
set1.add(6)
print(set1)		# {1, 2, 3, 4, 5, 6}

# 변경 (update)
set1.update([5, 6, 7, 8])
print(set1)		# {1, 2, 3, 4, 5, 6, 7, 8}

# 삭제 (delete)
set1.remove(6)
print(set1)		# {1, 2, 3, 4, 5, 7, 8}

# 리스트 변환 (list to set)
list = [1, 2, 3, 4, 5]
set = set(list)
print(set)		# {1, 2, 3, 4, 5}


### 집합 ##########
set1 = set([1, 2, 3, 4, 5])
set2 = set([3, 4, 5, 6, 7])

# 합집합 (Union)
set_u = set1 | set2
print(set_u)		# {1, 2, 3, 4, 5, 6, 7}
set_u = set1.union(set2)
print(set_u)		# {1, 2, 3, 4, 5, 6, 7}

# 교집합 (Intersection)
set_i = set1 &amp;amp; set2
print(set_u)		# {3, 4, 5}
set_i = set1.intersection(set2)
print(set_u)		# {3, 4, 5}

# 차집합 (Difference)
set_d = set1 - set2
print(set_d)		# {1, 2}
set_d = set1.difference(set2)
print(set_d)		# {1, 2}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;List&lt;/h3&gt;
&lt;pre id=&quot;code_1753103034014&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### 삽입 ##########
# 값 삽입 (append)
list = [1, 2, 4, 5]
list.append(6)
print(list)		# [1, 2, 4, 5, 6]

# 값 삽입 - 특정 인덱스 (insert)
list = [1, 2, 4, 5]
list.insert(2, 3)
print(list)		# [1, 2, 3, 4, 5]

# 리스트 삽입 (extend)
lista = [1, 2, 3]
listb = [4, 5, 6]
lista.extend(listb)
print(lista)	# [1, 2, 3, 4, 5, 6]

### 삭제 ##########
# 삭제 - 특정 인덱스, 값 반환 (pop)
list = [1, 2, 3, 4 ,5]
p = list.pop(1)
print(p)		# 2

print(list)		# [1, 3, 4, 5]
p = list.pop()
print(p)		# 5
print(list)		# [1, 3, 4]

# 삭제 - 특정 인덱스 (del)
list = [1, 2, 3, 4 ,5]
list.del(2)
print(list)		# [1, 2, 4, 5]

# 삭제 - 특정 값 삭제 (remove) - 순차검색과정에서 우선 매칭되는 개체 하나만 삭제
list = [1, 2, 3, 4 ,5, 4]
list.remove(4)
print(list)		# [1, 2, 3, 5, 4]

### 정렬 ##########
# 오른차순 (Sort)
list = [3, 1, 2, 5, 4]
list.sort()
print(list)		# [1, 2, 3, 4, 5]

# 내림차순 (Reverse)
list = [1, 2, 3, 4, 5]
list.reverse()
print(list)		# [5, 4, 3, 2, 1]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Develope/Python</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/122</guid>
      <comments>https://noggame.tistory.com/122#entry122comment</comments>
      <pubDate>Mon, 21 Jul 2025 22:16:41 +0900</pubDate>
    </item>
    <item>
      <title>우연은 비켜 가지 않는다</title>
      <link>https://noggame.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ELIZABETH FINCH - Julian Barnes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삶은 아름답지만 슬픈가, 아니면 슬프지만 아름다운가? 어쩌면 그는 그 질문을 우회하는 답을 찾았는지도 모릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Mozart dilemma: is life beautiful, but sad; or sad, but beautiful?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정직성에는 정보 차이가 없다. 거짓에는 정도 차이가 있지만 그건 다른 문제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &quot;철학자들은 감정의 개수에 관해 합의를 보지 못했다.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패가 성공보다 우리에게 많은 것을 말해주고, 깨끗한 패배자보다 지고 나서 뒤끝이 있는 사람이 우리에게 많은 것을 말해준다.&lt;/p&gt;</description>
      <category>Favorite/책갈피</category>
      <category>책갈피</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/121</guid>
      <comments>https://noggame.tistory.com/121#entry121comment</comments>
      <pubDate>Sun, 22 Jun 2025 10:02:30 +0900</pubDate>
    </item>
    <item>
      <title>나인</title>
      <link>https://noggame.tistory.com/120</link>
      <description>&lt;ul style=&quot;list-style-type: disc; color: #5c5c5c; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;무언가를 감추려고 한 순간부터 이미 멀어진거구나.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;떨어져 있는 시간 동안 서로 다른 기억이 쌓여서 다시 만났을 때 도저히 넘나들 수 없을 높은 장벽이 생긴다면. 그것을 부술 생각도 하지 못하고, 어른이 됐다는 이유로 서로의 다름으로 인정하고는 그렇게 벽 너머에 있게 된다면&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;언제나 모든 사람이 괴로움을 이길 필요는 없으니까. 때로는 괴롭게 하는것으로부터 멀리 가는 것도 방법인 것 같았다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Favorite/책갈피</category>
      <category>책갈피</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/120</guid>
      <comments>https://noggame.tistory.com/120#entry120comment</comments>
      <pubDate>Sun, 22 Jun 2025 09:50:46 +0900</pubDate>
    </item>
    <item>
      <title>이중 하나는 거짓말</title>
      <link>https://noggame.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;나는 그녀와 산책합니다.&lt;br /&gt;그녀의 이름은 연미정입니다.&lt;br /&gt;내 '최고의 날', 내게 일어난 일은 이렇습니다.&lt;br /&gt;내가 말하면 그녀가 듣습니다. 그녀가 얘기하면 내가 듣습니다.&lt;br /&gt;우리는 함께 웃습니다.&lt;br /&gt;그곳에 큰 사건은 없습니다.&lt;br /&gt;대신 그녀가 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사랑하는 방법이 각자 달랐고 미워하는 게 이해하는 것보다 훨씬 쉬울 뿐이었다.&lt;/p&gt;</description>
      <category>Favorite/책갈피</category>
      <category>책갈피</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/119</guid>
      <comments>https://noggame.tistory.com/119#entry119comment</comments>
      <pubDate>Sun, 22 Jun 2025 09:49:23 +0900</pubDate>
    </item>
    <item>
      <title>[MongoDB] container 배포 및 python 샘플 코드</title>
      <link>https://noggame.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅇ docker-compose.yaml&lt;/p&gt;
&lt;pre id=&quot;code_1750081768841&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: '3.1'

services:

  mongo:
    image: mongodb/mongodb-community-server:${MONGO_VERSION}
    container_name: news_db
    restart: always
    ports:
      - 27017:27017
    volumes:
      - ./data/mongo/db:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
      - MONGO_HOST=${MONGO_HOST}
      - MONGO_PORT=${MONGO_PORT}
      - MONGO_DATABASE=${MONGO_DATABASE}
    env_file:
      - env/local.env&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅇ local.env&lt;/p&gt;
&lt;pre id=&quot;code_1750081804401&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PROJECT_NAME=NewsCollector

## Mongo Database
MONGO_VERSION=7.0-ubuntu2204
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=mypassword
MONGO_HOST=localhost
MONGO_PORT=27017
MONGO_DATABASE=news_db
MONGO_URL=mongodb://$(MONGO_INITDB_ROOT_USERNAME):$(MONGO_INITDB_ROOT_PASSWORD)@$(MONGO_HOST):$(MONGO_PORT)/$(MONGO_DATABASE)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅇ Async 접속&lt;/p&gt;
&lt;pre id=&quot;code_1750081973456&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import asyncio
from typing import TypedDict
from pymongo import AsyncMongoClient

async def main():
    # Initialize the MongoDB client
    client = AsyncMongoClient(&quot;mongodb://admin:mypassword@localhost:27017&quot;)

    try:
        database = client.get_database(&quot;my_db&quot;)			# 없는 경우 자동 생성
        collection = database.get_collection(&quot;my_collection&quot;)	# 없는 경우 자동 생성
    except Exception as e:
        print(f&quot;Error connecting to the database: {e}&quot;)
        
    await client.close()
        
asyncio.run(main())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅇ Insert&lt;/p&gt;
&lt;pre id=&quot;code_1750082028821&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;await collection.insert_one({&quot;title&quot;: &quot;test01&quot;, &quot;contents&quot;: &quot;empty contents&quot;})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅇ update&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- [주의] `$set` 을 사용하지 않으면 다른 key-value 값들도 모두 변경됨&lt;/p&gt;
&lt;pre id=&quot;code_1750082061294&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;collection.update({&quot;title&quot;: &quot;test01&quot;}, {&quot;$set&quot;: {&quot;contents&quot;: &quot;new contents&quot;}})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Develope/Python</category>
      <category>MongoDB</category>
      <category>Python</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/118</guid>
      <comments>https://noggame.tistory.com/118#entry118comment</comments>
      <pubDate>Mon, 16 Jun 2025 22:56:34 +0900</pubDate>
    </item>
    <item>
      <title>[Python] UV package management tool</title>
      <link>https://noggame.tistory.com/117</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치&lt;/h2&gt;
&lt;pre id=&quot;code_1745146659857&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# macOS or Linux
curl -LsSf https://astral.sh/uv/install.sh | sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 / 패키지&lt;/h2&gt;
&lt;pre id=&quot;code_1745146731416&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 프로젝트 생성
uv init

# 패키지 추가
uv add {package_name}

# 패키지 삭제
uv remove {package_name}

# 패키지 조회
uv tree&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;가상환경 생성 및 활성화&lt;/h2&gt;
&lt;pre id=&quot;code_1745148170151&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# python 3.12 가상환경 생성
uv venv --python 3.12

# 생성된 가상환경 shell 명령어에 추가 (macOS/Linux)
source .venv/bin/actiavte

# 가상환경 비활성화
deactivate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스크립트&lt;/h2&gt;
&lt;pre id=&quot;code_1745146761889&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 실행
uv run

# 의존성 추가
uv add --script

# 의존성 제거
uv remove --script&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Tools&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(ruff, black와 같은) Python 패키지 index에 다양한 도구를 설치하고 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1745146819901&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 실행
uvx / uv tool run

# 설치
uv tool install

# 삭제
uv tool uninstall

# 목록 확인
uv tool list

# (실행 가능한 도구를 포함하도록) shell update
uv tool update-shell&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;기타&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ㅇ uv 버전 업데이트&lt;/p&gt;
&lt;pre id=&quot;code_1745147958424&quot; class=&quot;armasm&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;uv self update&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ㅇ poetry pyproject.toml 파일을 uv로 변환&lt;/p&gt;
&lt;pre id=&quot;code_1752305007206&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;uvx migrate-to-uv&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참조&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://docs.astral.sh/uv/getting-started/installation/&quot;&gt;참고 - 설치&lt;/a&gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://docs.astral.sh/uv/getting-started/features/&quot;&gt;참고 - 명령어&lt;/a&gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://docs.astral.sh/uv/getting-started/features/#tools&quot;&gt;참고 - tools&lt;/a&gt;]&lt;/p&gt;</description>
      <category>Develope/Python</category>
      <category>Package</category>
      <category>Python</category>
      <category>UV</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/117</guid>
      <comments>https://noggame.tistory.com/117#entry117comment</comments>
      <pubDate>Sun, 20 Apr 2025 20:02:16 +0900</pubDate>
    </item>
    <item>
      <title>[Python] ML Flow 정리중</title>
      <link>https://noggame.tistory.com/115</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Hosting&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서빙&lt;/p&gt;
&lt;pre id=&quot;code_1741151637358&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mlflow server --host 127.0.0.1 --port 9090&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 추적 서버 설정&lt;/p&gt;
&lt;pre id=&quot;code_1741151738146&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import mlflow

# Set our tracking server uri for logging
mlflow.set_tracking_uri(uri=&quot;http://127.0.0.1:9090&quot;)

# Create a new MLflow Experiment
mlflow.set_experiment(&quot;MLflow Quickstart&quot;)

# with mlflow.start_run():
	# 내부 기입되는 mlflow에 대한 로깅
    
    # Log the hyperparameters
    mlflow.log_params(params)

    # Log the loss metric
    mlflow.log_metric(&quot;accuracy&quot;, accuracy)

    # Set a tag that we can use to remind ourselves what this run was for
    mlflow.set_tag(&quot;Training Info&quot;, &quot;Basic LR model for iris data&quot;)
    
    # ...&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Signature&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 모델의 입/출력 &amp;amp; 파라미터 정보 (template) 정의&lt;/p&gt;
&lt;pre id=&quot;code_1741150340392&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(function) def infer_signature(
    model_input: Any = None,
    model_output: Any = None,
    params: dict[str, Any] | None = None
) -&amp;gt; ModelSignature&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예시 (python 코드 및 정의된 템플릿)&lt;/p&gt;
&lt;pre id=&quot;code_1741150517736&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from mlflow.models import infer_signature

infer_signature(model_input={
	&quot;long_col&quot;: 1,
	&quot;str_col&quot;: &quot;a&quot;,
	&quot;bool_col&quot;: True
})&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1741150537656&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Template (Inferred Signature)

signature:
    input: '[
        {&quot;name&quot;: &quot;long_col&quot;, &quot;type&quot;: &quot;long&quot;,    &quot;required&quot;: &quot;true&quot;},
        {&quot;name&quot;: &quot;str_col&quot;,  &quot;type&quot;: &quot;string&quot;,  &quot;required&quot;: &quot;true&quot;},
        {&quot;name&quot;: &quot;bool_col&quot;, &quot;type&quot;: &quot;boolean&quot;, &quot;required&quot;: &quot;true&quot;}
    ]'
    output: null
    params: null&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Develope/Python</category>
      <category>MLFlow</category>
      <category>Python</category>
      <author>noggame</author>
      <guid isPermaLink="true">https://noggame.tistory.com/115</guid>
      <comments>https://noggame.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 5 Mar 2025 14:16:31 +0900</pubDate>
    </item>
  </channel>
</rss>