Usage: uv [OPTIONS] <COMMAND>
Commands:
run Run a command or script
init Create a new project
add Add dependencies to the project
remove Remove dependencies from the project
sync Update the project's environment
lock Update the project's lockfile
export Export the project's lockfile to an alternate format
tree Display the project's dependency tree
tool Run and install commands provided by Python packages
python Manage Python versions and installations
pip Manage Python packages with a pip-compatible interface
venv Create a virtual environment
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uv executable
version Display uv's version
help Display documentation for a command
Cache options:
-n, --no-cache Avoid reading from or writing to the cache, instead using a temporary directory for the
duration of the operation [env: UV_NO_CACHE=]
--cache-dir <CACHE_DIR> Path to the cache directory [env: UV_CACHE_DIR=]
Python options:
--python-preference <PYTHON_PREFERENCE> Whether to prefer uv-managed or system Python installations [env:
UV_PYTHON_PREFERENCE=] [possible values: only-managed, managed, system,
only-system]
--no-python-downloads Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"]
Global options:
-q, --quiet
Do not print any output
-v, --verbose...
Use verbose output
--color <COLOR_CHOICE>
Control the use of color in output [possible values: auto, always, never]
--native-tls
Whether to load TLS certificates from the platform's native certificate store [env: UV_NATIVE_TLS=]
--offline
Disable network access [env: UV_OFFLINE=]
--allow-insecure-host <ALLOW_INSECURE_HOST>
Allow insecure connections to a host [env: UV_INSECURE_HOST=]
--no-progress
Hide all progress outputs [env: UV_NO_PROGRESS=]
--directory <DIRECTORY>
Change to the given directory prior to running the command
--project <PROJECT>
Run the command within the given project directory
--config-file <CONFIG_FILE>
The path to a `uv.toml` file to use for configuration [env: UV_CONFIG_FILE=]
--no-config
Avoid discovering configuration files (`pyproject.toml`, `uv.toml`) [env: UV_NO_CONFIG=]
-h, --help
Display the concise help for this command
-V, --version
Display the uv version
> npx create-nx-workspace
✔ Where would you like to create your workspace? · aip
✔ Which stack do you want to use? · none
✔ Would you like to use Prettier for code formatting? · Yes
✔ Which CI provider would you like to use? · azure
NX Creating your v20.5.0 workspace.
✔ Installing dependencies with npm
[2] NX 전용 파이썬 플러그인을 설치한다. @nxlv/python 은 build, publish 등 uv 패키지 메니져 사용시, poetry 의 장점을 보완한다.
NX의 모노레포 아키텍쳐에서는 Shell Library Pattern 방식을 지향한다. 이는 다양한 애플리케이션(서비스)안에서 사용하는 패키지(라이브러리)를 분리 관리하는 방식으로 확장성과 유지보수성을 높혀준다.
프로젝트에서 애플리케이션의 모든 페이지와 컴포넌트를 패키지에 담고, 애플리케이션은 이들의 조합하고 설정하는 역할만 수행한다. 이때 패키지는 Nexus Registry에 배포하여 버전관리를 하게되면 유지보수성이 좋아진다.
실 프로젝트에서 Frontend 파트를 보면 Micro Applications들은 각가의 Micro Frontend 로 구성하고, Portal 이 라는 곳에서 Module Federation을 통해 각 micro frontend를 통합하여 표현한다. Micro Frontend에는 비즈니스 로직이 없고, 애플리케이션 구성 환경설정만 존재한다. libs 폴더안에 있는 것이 패키지로 각 패키지는 NPM Registry에 배포되어 버전 관리를 하고, 애플리케이션은 libs에 있는 패키지를 통해 화면 및 비지니스 로직을 구현한다.
Peter real project folder structure
NX의 Shell Library Pattern도 유사하게 Feature Shell 이라는 Integrated Application을 제공한다.
Figure 1
A domain-wise application is the composition of every application that has the same routes, behavior, and functionalities. In the example in Figure 1, the Booking Application is the union of the Booking Web Application, the Booking Desktop Application, and the Booking Mobile Application.
UV 기반의 python 애플리케이션 또는 패키지를 생성(Generate)하기 위한 명령어.
npx nx g @nxlv/python:uv-project src --projectType=library --directory=packages/embedding --packageName=aip-embedding --publishable
- src 폴더 밑으로 템플릿 기반 소스 생성
- pyproject.toml 파일 생성
- project.json NX 환경파일 생성
- 그외 Unit test 용 tests 폴더 생성
▶ npx nx g @nxlv/python:uv-project src --projectType=library --directory=packages/embedding --packageName=aip-embedding --publishable
NX Generating @nxlv/python:uv-project
CREATE packages/embedding/project.json
CREATE packages/embedding/README.md
CREATE packages/embedding/.python-version
CREATE packages/embedding/src/__init__.py
CREATE packages/embedding/src/hello.py
CREATE packages/embedding/pyproject.toml
CREATE packages/embedding/tests/__init__.py
CREATE packages/embedding/tests/conftest.py
CREATE packages/embedding/tests/test_hello.py
=========
▶ npx nx g @nxlv/python:uv-project --help
NX generate @nxlv/python:uv-project [name] [options,...]
From: @nxlv/python (v20.7.0)
Name: uv-project
Options:
--name [string]
--projectType Project type [string] [choices: "application",
"library"] [default: "application"]
--buildBundleLocalDependencies Bundle local dependencies [boolean] [default: true]
--buildLockedVersions Use locked versions for build dependencies [boolean] [default: true]
--codeCoverage Generate code coverage report [boolean] [default: true]
--codeCoverageHtmlReport Generate html report for code coverage [boolean] [default: true]
--codeCoverageThreshold Code coverage threshold [number]
--codeCoverageXmlReport Generate Xml report for code coverage [boolean] [default: true]
--description Project short description [string]
--devDependenciesProject This approach installs all the missing dev [string]
dependencies in a separate project
(optional)
--directory A directory where the project is placed [string]
--linter Project linter [string] [choices: "flake8", "ruff",
"none"] [default: "ruff"]
--moduleName Python module name [string]
--packageName Python package name [string]
--projectNameAndRootFormat Whether to generate the project name and [string] [choices: "as-provided",
root directory as provided (`as-provided`) "derived"] [default: "as-provided"]
or generate them composing their values and
taking the configured layout into account
(`derived`).
--publishable Project is publishable [boolean]
--pyenvPythonVersion Pyenv .python-version content (default to [string]
current python version)
--pyprojectPythonDependency Pyproject python dependency version range [string] [default: ">=3.9,<4"]
--rootPyprojectDependencyGroup If a shared pyproject.toml is used, which [string] [default: "main"]
dependency group does this new project
should belong to
--tags, -t Add tags to the project (used for linting) [string]
--templateDir Custom template directory, this will [string]
override the default template, if not
provided the default template will be used
--unitTestHtmlReport Generate html report for unit tests [boolean] [default: true]
--unitTestJUnitReport Generate junit report for unit tests [boolean] [default: true]
--unitTestRunner Project unit test runner [string] [choices: "pytest", "none"]
[default: "pytest"]
- AI agents typically use language models as part of their software stack to interpret messages, perform reasoning, and execute actions.
- Each agent is a self-contained unit that can be developed, tested, and deployed independently.
[2] Multi Agent 특징
- Run within the same process or on the same machine
- Operate across different machines or organizational boundaries
- Be implemented in diverse programming languages and make use of different AI models or instructions
- Work together towards a shared goal, coordinating their actions through messaging
[3] Agent 실행 환경
the framework provides a runtime environment, which facilitates communication between agents, manages their identities and lifecycles, and enforce security and privacy boundaries.
Standalone Agent Runtime
- single process application
- all agents are implemented in the same language
- running in the same process.
Agent는 runtime 동안 메세지를 통해 통신을 하고, 런타임은 Agent의 LifeCycle을 관리한다.
Distrubuted Agent Runtime
- multi process applications
- Agents are implemented in different programming languages
- running on different machines
분산환경은 host servicer와 multiple workers를 갖는다.
- host servicer는 agent 사이의 통신과 연결상태를 관리한다.
- worker는 agent를 구동하고 host servicer와 gateway를 통해 통신한다.
[4] 애플리케이션 스택
AutoGen core는 다양한 multi-agent application 개발할 때 사용된다.
[5] Agent 식별 방법 & 라이프 사이클 관리
Agent 런타임은 에이젼트 identities와 lifecyles을 관리한다.
- Agent ID = Agent Type + Agent Key(instance)
런타임에서 Agent가 없으면 생성하고, 메세지로 agent type & key를 전달한다.
[6] Topic & Subscription
message를 broadcast할 때 방법을 설명한다.
- Topic : pubishing messages with Topic Type, Topic Source
- Subscription : topic 과 agentID와 맵팽한다. 런타임 환경에 맵핑을 만들고 삭제할 수 있다.
Type-based subscription
Topic Type -> Agent Type 전파
- Single Tenant & Single Topic
- Single Tenant & Multi Topics
- Multi Tenant
in single tenant, the topic source is "default". for multi tenant, it become data-dependent.
with get_openai_callback() as cb:는 Python의 컨텍스트 관리자(context manager)를 사용하여 get_openai_callback 함수가 반환하는 객체(cb)를 생성하고, 그 객체를 사용하는 블록을 정의하는 구문입니다. 이 구문을 이해하기 위해서는 Python의 컨텍스트 관리자가 어떻게 작동하는지와 get_openai_callback이 어떤 역할을 하는지를 아는 것이 중요합니다.
1. 컨텍스트 관리자 (Context Manager)
컨텍스트 관리자는 with 블록의 시작과 종료 시 특정 코드를 자동으로 실행하게 해줍니다. 일반적으로, 컨텍스트 관리자는 자원(resource)을 할당하고 해제하는 작업에 사용됩니다. 예를 들어, 파일을 열고 작업을 한 후 자동으로 파일을 닫는 데 사용할 수 있습니다.
•__enter__(): with 블록이 시작될 때 호출됩니다. 이 메서드는 일반적으로 어떤 자원을 할당하거나 초기화합니다.
•__exit__(): with 블록이 끝날 때 호출됩니다. 이 메서드는 자원을 해제하거나, 예외가 발생했을 때 이를 처리합니다.
2. get_openai_callback의 역할
get_openai_callback은 OpenAI API 호출과 관련된 메트릭을 수집하는 콜백 객체를 반환합니다. 이 콜백 객체는 컨텍스트 관리자에서 사용될 때 API 호출 동안의 토큰 사용량, 비용 등을 추적합니다.
3. with get_openai_callback() as cb:의 의미
•get_openai_callback()은 컨텍스트 관리자 역할을 하는 객체를 반환합니다.
•with 블록이 시작되면, cb 변수에 이 객체가 할당됩니다.
•with 블록 내에서 OpenAI API 호출이 이루어지면, cb 객체는 API 호출 관련 데이터를 수집합니다.
•with 블록이 종료되면, cb 객체는 수집한 데이터를 자동으로 정리하고, 필요한 경우 자원을 해제합니다.
예시 코드 분석
from langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback
llm = OpenAI(model="text-davinci-003")
with get_openai_callback() as cb:
response = llm("What is the capital of France?")
print(response)
print(f"Total Tokens: {cb.total_tokens}")
print(f"Total Cost: {cb.total_cost}")
•get_openai_callback(): 콜백 객체를 생성하여 반환합니다.
•with ... as cb:: cb 변수에 콜백 객체를 할당하고, with 블록 내에서 이 객체를 사용합니다.
•cb.total_tokens, cb.total_cost: with 블록이 끝난 후, API 호출 동안 사용된 총 토큰 수와 총 비용을 출력합니다.
이 구문을 사용함으로써 개발자는 OpenAI API 호출의 성능을 모니터링하고 리소스 사용량을 효율적으로 관리할 수 있습니다.
get_openai_callback
소스: langchain_community/callbacks/manager.py
from contextlib import contextmanager
@contextmanager
def get_openai_callback() -> Generator[OpenAICallbackHandler, None, None]:
"""Get the OpenAI callback handler in a context manager.
which conveniently exposes token and cost information.
Returns:
OpenAICallbackHandler: The OpenAI callback handler.
Example:
>>> with get_openai_callback() as cb:
... # Use the OpenAI callback handler
"""
cb = OpenAICallbackHandler()
openai_callback_var.set(cb)
yield cb
openai_callback_var.set(None)
Pydantic은 Python에서 데이터 유효성 검사 및 설정 관리를 위한 라이브러리입니다. 주로 FastAPI와 같은 웹 프레임워크와 함께 사용되며, 데이터를 구조화하고 검증하는 데 유용합니다. BaseModel은 Pydantic의 핵심 클래스 중 하나로, 데이터 모델을 정의하는 데 사용됩니다.
Pydantic의 주요 기능
1.유효성 검사 및 변환: 필드에 대해 타입을 지정하면, 입력 데이터가 자동으로 그 타입으로 변환되며, 유효성 검사가 수행됩니다.
2.자동 완성 및 타입 힌팅 지원: IDE의 자동 완성과 타입 힌팅을 통해 개발 생산성을 높입니다.
3.데이터 직렬화 및 역직렬화: 모델 인스턴스를 JSON으로 직렬화하거나 JSON으로부터 역직렬화할 수 있습니다.
4.데이터 검증 오류 관리: 잘못된 데이터를 입력하면, Pydantic이 자동으로 유효성 검사 오류를 생성합니다.
BaseModel 사용 예시
다음은 Pydantic의 BaseModel을 사용하여 간단한 사용자 데이터를 관리하는 예제입니다.
from pydantic import BaseModel, EmailStr, Field
from typing import Optional
class User(BaseModel):
id: int
name: str = Field(..., min_length=3, max_length=50)
email: EmailStr
age: Optional[int] = Field(None, ge=18)
is_active: bool = True
# Example usage
user_data = {
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com",
"age": 25,
}
user = User(**user_data)
print(user)
print(user.dict())
코드 설명
1.필드 정의:
•id: 정수형 필드.
•name: 길이가 3에서 50 사이인 문자열 필드.
•email: 이메일 형식의 문자열을 요구하는 필드. EmailStr 타입은 이메일 주소가 올바른 형식인지 검증합니다.
•age: 선택적 필드로, 값이 주어지면 18 이상이어야 합니다.
•is_active: 기본값이 True인 불리언 필드.
2.필드 유효성 검사:
•Field를 사용하여 각 필드에 대한 추가적인 제약 조건을 지정합니다.
3.데이터 생성 및 출력:
•user_data 딕셔너리를 통해 User 객체를 생성합니다. 생성된 객체를 출력하거나, .dict() 메서드를 사용하여 객체를 딕셔너리 형태로 변환할 수 있습니다.
이와 같이 Pydantic을 사용하면 데이터 모델을 간단하고 명확하게 정의할 수 있으며, 자동으로 타입 변환과 유효성 검사를 수행할 수 있습니다. 이를 통해 데이터 처리의 신뢰성과 안정성을 높일 수 있습니다.
BaseModel은 자동으로 __init__ 을 실행
Pydantic의 BaseModel을 사용하면 클래스 수준에서 필드를 정의할 수 있으며, 이러한 필드는 마치 __init__ 메서드에서 self.name과 같이 인스턴스 변수로 설정된 것처럼 동작합니다. Pydantic은 이러한 필드를 기반으로 자동으로 __init__ 메서드를 생성하고, 필드에 대한 타입 검사를 수행합니다.
이 방식은 일반적인 Python 클래스에서의 인스턴스 변수 설정과는 약간 다릅니다. 일반 Python 클래스에서는 인스턴스 변수를 __init__ 메서드 내에서 self를 통해 설정해야 하지만, Pydantic의 BaseModel을 사용하면 클래스 정의 시 필드의 타입과 기본값을 지정하여 더 간결하고 명확하게 모델을 정의할 수 있습니다.
예시 비교
일반 Python 클래스
class User:
def __init__(self, id: int, name: str, email: str, age: int, is_active: bool = True):
self.id = id
self.name = name
self.email = email
self.age = age
self.is_active = is_active
Pydantic BaseModel
from pydantic import BaseModel, EmailStr, Field
from typing import Optional
class User(BaseModel):
id: int
name: str = Field(..., min_length=3, max_length=50)
email: EmailStr
age: Optional[int] = Field(None, ge=18)
is_active: bool = True
차이점 설명
•일반 클래스에서는 __init__ 메서드 내에서 self를 사용하여 인스턴스 변수를 직접 설정합니다.
•Pydantic BaseModel에서는 클래스 정의 시 필드를 직접 설정하고, Pydantic이 자동으로 __init__ 메서드를 생성하여 필드 초기화, 타입 검사, 유효성 검사를 수행합니다.
이렇게 Pydantic의 BaseModel을 사용하면 코드가 더 간결해지며, 데이터 유효성 검사가 자동으로 처리되므로 안전하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.