🚀 완전 관리형 Milvus인 Zilliz Cloud를 무료로 체험해보세요—10배 더 빠른 성능을 경험하세요! 지금 체험하기>>

milvus-logo
LFAI

개요

  • Engineering
September 15, 2021
Zhen Chen

개요

프로젝트 URL: https://github.com/milvus-io/milvus_cli

준비 Python3.8, Click 8.0.x

그룹 명령

명령 만들기

import click
from utils import PyOrm

@click.group(no_args_is_help=False, add_help_option=False, invoke_without_command=True)
@click.pass_context
def cli(ctx):
    """Milvus CLI"""
    ctx.obj = PyOrm() # PyOrm is a util class which wraps the milvus python SDK. You can pass any class instance here. Any command function passed by @click.obj can call it.

if __name__ == '__main__':
    cli()

위의 코드에서는 @click.group() 을 사용하여 cli 을 진입점으로 하는 명령 그룹을 만듭니다. 프롬프트 CLI를 구현하려면 항목에 대한 도움말 메시지를 비활성화해야 하므로 no_args_is_help=False, add_help_option=Falseinvoke_without_command=True 을 추가합니다. 터미널에 cli 만 입력하면 아무 것도 인쇄되지 않습니다.

또한 @click.pass_context 을 사용하여 추가 사용을 위해 이 그룹에 컨텍스트를 전달합니다.

명령 그룹의 하위 명령 만들기

그런 다음 cli 아래에 첫 번째 하위 명령 help 을 추가합니다:

# Print the help message of specified command.
def print_help_msg(command):
    with click.Context(command) as ctx:
        click.echo(command.get_help(ctx))


# Use @cli.command() to create a sub command of cli.
@cli.command()
def help():
    """Show help messages."""
    # Print help message of cli.
    click.echo(print_help_msg(cli))

이제 터미널에서 cli help 을 사용할 수 있습니다:

$ python milvus_cli/scripts/milvus_cli.py help

명령 그룹의 하위 그룹 만들기

cli help 과 같은 하위 명령뿐만 아니라 cli list collection, cli list partitioncli list indexes 과 같은 하위 그룹 명령도 필요합니다.

먼저 하위 그룹 명령 list 을 만들고, 여기서 기본 함수 이름을 사용하는 대신 첫 번째 매개 변수를 @cli.group 에 명령 이름으로 전달하여 중복된 함수 이름을 줄일 수 있습니다.

여기서는 @click.group 대신 @cli.group() 을 사용하여 원본 그룹의 하위 그룹을 만듭니다.

@click.pass_obj 을 사용하여 context.obj 을 이 하위 그룹의 하위 명령에 전달합니다.

@cli.group('list', no_args_is_help=False)
@click.pass_obj
def listDetails(obj):
    """List collections, partitions and indexes."""
    pass

그런 다음 @listDetails.command() ( @cli.command() 이 아닌)으로 이 하위 그룹에 일부 하위 명령을 추가합니다. 여기서는 예제일 뿐이므로 구현은 무시해도 되며 나중에 설명하겠습니다.

@listDetails.command()
@click.option('--timeout', 'timeout', help="[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is set to None, client waits until server response or error occur.", default=None)
@click.option('--show-loaded', 'showLoaded', help="[Optional] - Only show loaded collections.", default=False)
@click.pass_obj
def collections(obj, timeout, showLoaded):
    """List all collections."""
    try:
        obj.checkConnection()
        click.echo(obj.listCollections(timeout, showLoaded))
    except Exception as e:
        click.echo(message=e, err=True)


@listDetails.command()
@click.option('-c', '--collection', 'collection', help='The name of collection.', default='')
@click.pass_obj
def partitions(obj, collection):
    """List all partitions of the specified collection."""
    try:
        obj.checkConnection()
        validateParamsByCustomFunc(
            obj.getTargetCollection, 'Collection Name Error!', collection)
        click.echo(obj.listPartitions(collection))
    except Exception as e:
        click.echo(message=e, err=True)

이 모든 작업이 완료되면 다음과 같은 밀리그룹 명령이 생깁니다:

image image

명령 사용자 지정

옵션 추가하기

cli --test-option value 와 같이 사용할 명령에 몇 가지 옵션을 추가할 수 있습니다.

여기서는 alias, host, port 세 가지 옵션을 추가하여 Milvus에 연결할 주소를 지정하는 예제입니다.

처음 두 매개변수는 짧은 옵션 이름과 전체 옵션 이름을 정의하고, 세 번째 매개변수는 변수 이름을 정의하며, help 매개변수는 간단한 도움말 메시지를, default 매개변수는 기본값을, type 매개변수는 값 유형을 지정합니다.

그리고 모든 옵션의 값은 정의된 순서대로 함수에 전달됩니다.

@cli.command(no_args_is_help=False)
@click.option('-a', '--alias', 'alias', help="Milvus link alias name, default is `default`.", default='default', type=str)
@click.option('-h', '--host', 'host', help="Host name, default is `127.0.0.1`.", default='127.0.0.1', type=str)
@click.option('-p', '--port', 'port', help="Port, default is `19530`.", default=19530, type=int)
@click.pass_obj
def connect(obj, alias, host, port):
    pass

플래그 옵션 추가하기

위의 옵션을 사용하여 값을 전달하지만 때로는 부울 값으로 플래그만 전달해야 할 때도 있습니다.

아래 예시처럼 autoId 옵션은 플래그 옵션이며 함수에 데이터를 전달하지 않으므로 cli create collection -c c_name -p p_name -a 과 같이 사용할 수 있습니다.

@createDetails.command('collection')
@click.option('-c', '--collection-name', 'collectionName', help='Collection name to be created.', default='')
@click.option('-p', '--schema-primary-field', 'primaryField', help='Primary field name.', default='')
@click.option('-a', '--schema-auto-id', 'autoId', help='Enable auto id.', default=False, is_flag=True)
@click.pass_obj
def createCollection(obj, collectionName, primaryField, autoId, description, fields):
    pass

인수 추가하기

이 프로젝트에서는 모든 인자 사용을 옵션 사용으로 대체합니다. 하지만 여기서는 여전히 인자 사용법을 소개합니다. 옵션과 달리 인수는 cli COMMAND [OPTIONS] ARGUEMENTS 와 같이 사용됩니다. 위의 예제를 인수 사용법으로 변환하면 다음과 같이 됩니다:

@createDetails.command('collection')
@click.argument('collectionName')
@click.option('-p', '--schema-primary-field', 'primaryField', help='Primary field name.', default='')
@click.option('-a', '--schema-auto-id', 'autoId', help='Enable auto id.', default=False, is_flag=True)
@click.pass_obj
def createCollection(obj, collectionName, primaryField, autoId, description, fields):
    pass

그러면 사용법은 cli create collection c_name -p p_name -a 이 되어야 합니다.

전체 도움말 메시지 추가하기

위에서 짧은 도움말 메시지를 정의했듯이 함수에서 전체 도움말 메시지를 정의할 수 있습니다:

@cli.command(no_args_is_help=False)
@click.option('-a', '--alias', 'alias', help="Milvus link alias name, default is `default`.", default='default', type=str)
@click.option('-h', '--host', 'host', help="Host name, default is `127.0.0.1`.", default='127.0.0.1', type=str)
@click.option('-p', '--port', 'port', help="Port, default is `19530`.", default=19530, type=int)
@click.pass_obj
def connect(obj, alias, host, port):
    """
    Connect to Milvus.

    Example:

        milvus_cli > connect -h 127.0.0.1 -p 19530 -a default
    """
    try:
        obj.connect(alias, host, port)
    except Exception as e:
        click.echo(message=e, err=True)
    else:
        click.echo("Connect Milvus successfully!")
        click.echo(obj.showConnection(alias))

함수 내부의 첫 번째 블록은 cli connect --help 을 입력한 후 인쇄될 도움말 메시지입니다.

milvus_cli > connect --help
Usage: milvus_cli.py connect [OPTIONS]

  Connect to Milvus.

  Example:

      milvus_cli > connect -h 127.0.0.1 -p 19530 -a default

Options:
  -a, --alias TEXT    Milvus link alias name, default is `default`.
  -h, --host TEXT     Host name, default is `127.0.0.1`.
  -p, --port INTEGER  Port, default is `19530`.
  --help              Show this message and exit.

확인 추가

때로는 사용자가 어떤 작업을 확인해야 할 때, 특히 무언가를 삭제해야 할 때가 있습니다. click.confirm 을 추가하여 일시 중지하고 사용자에게 확인을 요청할 수 있습니다:

@deleteSth.command('collection')
@click.option('-c', '--collection', 'collectionName', help='The name of collection to be deleted.', default='')
@click.option('-t', '--timeout', 'timeout', help='An optional duration of time in seconds to allow for the RPC. If timeout is set to None, the client keeps waiting until the server responds or an error occurs.', default=None, type=int)
@click.pass_obj
def deleteCollection(obj, collectionName, timeout):
    """
    Drops the collection together with its index files.

    Example:

        milvus_cli > delete collection -c car
    """
    click.echo(
        "Warning!\nYou are trying to delete the collection with data. This action cannot be undone!\n")
    if not click.confirm('Do you want to continue?'):
        return
    pass

위의 예와 같이 확인 대화가 Aborted!ant to continue? [y/N]: 와 같이 표시됩니다.

프롬프트 추가하기

프롬프트를 구현하려면 click.prompt 을 추가해야 합니다.

@cli.command()
@click.pass_obj
def query(obj):
    """
    Query with a set of criteria, and results in a list of records that match the query exactly.
    """
    collectionName = click.prompt(
        'Collection name', type=click.Choice(obj._list_collection_names()))
    expr = click.prompt('The query expression(field_name in [x,y])')
    partitionNames = click.prompt(
        f'The names of partitions to search(split by "," if multiple) {obj._list_partition_names(collectionName)}', default='')
    outputFields = click.prompt(
        f'Fields to return(split by "," if multiple) {obj._list_field_names(collectionName)}', default='')
    timeout = click.prompt('timeout', default='')
    pass

프롬프트는 각 click.prompt. 프롬프트 몇 개를 연속적으로 사용하여 연속적으로 대화하는 것처럼 보이도록 합니다. 이렇게 하면 사용자가 원하는 순서대로 데이터를 입력할 수 있습니다. 이 경우 사용자가 먼저 컬렉션을 선택해야 하며, 이 컬렉션 아래의 모든 파티션을 가져온 다음 사용자가 선택할 수 있도록 표시해야 합니다.

선택 항목 추가

때로는 사용자가 제한된 범위/종류의 값만 입력하도록 하고 싶다면 type=click.Choice([<any>])click.prompt, click.options 등을 추가할 수 있습니다.

예를 들어,

collectionName = click.prompt(
        'Collection name', type=click.Choice(['collection_1', 'collection_2']))

그러면 사용자는 collection_1 또는 collection_2 만 입력할 수 있으며 다른 입력이 있으면 오류가 발생합니다.

투명 화면 추가

click.clear() 을 사용하여 구현할 수 있습니다.

@cli.command()
def clear():
    """Clear screen."""
    click.clear()

추가 팁

  • 기본값은 None 이므로 기본값을 None 으로 지정한 경우 의미가 없습니다. 값을 비워두고 건너뛰려면 기본값을 None 으로 지정하면 click.prompt 이 계속 표시됩니다.

사용자가 입력할 수 있는 프롬프트 CLI 구현하기

프롬프트 CLI가 필요한 이유

데이터베이스 작업을 위해서는 인스턴스에 지속적으로 연결해야 합니다. 오리진 명령줄 모드를 사용하면 각 명령이 수행될 때마다 연결이 끊어집니다. 또한 CLI를 사용할 때 일부 데이터를 저장하고 종료 후 정리하고 싶습니다.

구현하기

  1. 사용자의 입력을 지속적으로 수신하려면 while True 을 사용합니다.
def runCliPrompt():
    while True:
        astr = input('milvus_cli > ')
        try:
            cli(astr.split())
        except SystemExit:
            # trap argparse error message
            # print('error', SystemExit)
            continue


if __name__ == '__main__':
    runCliPrompt()
  1. input 만 사용하면 up, down, left, right 화살표 키, tab 키 및 기타 일부 키가 자동으로 Acsii 문자열로 변환됩니다. 게다가 히스토리 명령은 세션에서 읽을 수 없습니다. 따라서 runCliPrompt 함수에 readline 을 추가합니다.
def runCliPrompt():
    while True:
            import readline
        readline.set_completer_delims(' \t\n;')
        astr = input('milvus_cli > ')
        try:
            cli(astr.split())
        except SystemExit:
            # trap argparse error message
            # print('error', SystemExit)
            continue
  1. quit CLI를 추가합니다.
@cli.command('exit')
def quitapp():
    """Exit the CLI."""
    global quitapp
    quitapp = True


quitapp = False  # global flag


def runCliPrompt():
    while not quitapp:
            import readline
        readline.set_completer_delims(' \t\n;')
        astr = input('milvus_cli > ')
        try:
            cli(astr.split())
        except SystemExit:
            # trap argparse error message
            # print('error', SystemExit)
            continue
  1. ctrl C 을 사용하여 종료할 때 KeyboardInterrupt 오류가 발생합니다.
def runCliPrompt():
    try:
        while not quitapp:
            import readline
            readline.set_completer_delims(' \t\n;')
            astr = input('milvus_cli > ')
            try:
                cli(astr.split())
            except SystemExit:
                # trap argparse error message
                # print('error', SystemExit)
                continue
    except KeyboardInterrupt:
        sys.exit(0)
  1. 모든 설정이 완료되면 이제 CLI는 다음과 같습니다:
milvus_cli >
milvus_cli > connect
+-------+-----------+
| Host  | 127.0.0.1 |
| Port  |   19530   |
| Alias |  default  |
+-------+-----------+

milvus_cli > help
Usage:  [OPTIONS] COMMAND [ARGS]...

  Milvus CLI

Commands:
  clear     Clear screen.
  connect   Connect to Milvus.
  create    Create collection, partition and index.
  delete    Delete specified collection, partition and index.
  describe  Describe collection or partition.
  exit      Exit the CLI.
  help      Show help messages.
  import    Import data from csv file with headers and insert into target...
  list      List collections, partitions and indexes.
  load      Load specified collection.
  query     Query with a set of criteria, and results in a list of...
  release   Release specified collection.
  search    Conducts a vector similarity search with an optional boolean...
  show      Show connection, loading_progress and index_progress.
  version   Get Milvus CLI version.

milvus_cli > exit

수동으로 자동 완성 구현하기

클릭의 셸 자동 완성과는 달리, 우리 프로젝트는 명령줄을 래핑하고 루프를 사용하여 사용자의 입력을 받아 프롬프트 명령줄을 구현합니다. 따라서 완성자를 readline 에 바인딩해야 합니다.

class Completer(object):
    RE_SPACE = re.compile('.*\s+$', re.M)
    CMDS_DICT = {
        'clear': [],
        'connect': [],
        'create': ['collection', 'partition', 'index'],
        'delete': ['collection', 'partition', 'index'],
        'describe': ['collection', 'partition'],
        'exit': [],
        'help': [],
        'import': [],
        'list': ['collections', 'partitions', 'indexes'],
        'load': [],
        'query': [],
        'release': [],
        'search': [],
        'show': ['connection', 'index_progress', 'loading_progress'],
        'version': [],
    }

    def __init__(self) -> None:
        super().__init__()
        self.COMMANDS = list(self.CMDS_DICT.keys())
        self.createCompleteFuncs(self.CMDS_DICT)

    def createCompleteFuncs(self, cmdDict):
        for cmd in cmdDict:
            sub_cmds = cmdDict[cmd]
            complete_example = self.makeComplete(cmd, sub_cmds)
            setattr(self, 'complete_%s' % cmd, complete_example)

    def makeComplete(self, cmd, sub_cmds):
        def f_complete(args):
            f"Completions for the {cmd} command."
            if not args:
                return self._complete_path('.')
            if len(args) <= 1 and not cmd == 'import':
                return self._complete_2nd_level(sub_cmds, args[-1])
            return self._complete_path(args[-1])
        return f_complete

    def _listdir(self, root):
        "List directory 'root' appending the path separator to subdirs."
        res = []
        for name in os.listdir(root):
            path = os.path.join(root, name)
            if os.path.isdir(path):
                name += os.sep
            res.append(name)
        return res

    def _complete_path(self, path=None):
        "Perform completion of filesystem path."
        if not path:
            return self._listdir('.')
        dirname, rest = os.path.split(path)
        tmp = dirname if dirname else '.'
        res = [os.path.join(dirname, p)
               for p in self._listdir(tmp) if p.startswith(rest)]
        # more than one match, or single match which does not exist (typo)
        if len(res) > 1 or not os.path.exists(path):
            return res
        # resolved to a single directory, so return list of files below it
        if os.path.isdir(path):
            return [os.path.join(path, p) for p in self._listdir(path)]
        # exact file match terminates this completion
        return [path + ' ']

    def _complete_2nd_level(self, SUB_COMMANDS=[], cmd=None):
        if not cmd:
            return [c + ' ' for c in SUB_COMMANDS]
        res = [c for c in SUB_COMMANDS if c.startswith(cmd)]
        if len(res) > 1 or not (cmd in SUB_COMMANDS):
            return res
        return [cmd + ' ']

    def complete(self, text, state):
        "Generic readline completion entry point."
        buffer = readline.get_line_buffer()
        line = readline.get_line_buffer().split()
        # show all commands
        if not line:
            return [c + ' ' for c in self.COMMANDS][state]
        # account for last argument ending in a space
        if self.RE_SPACE.match(buffer):
            line.append('')
        # resolve command to the implementation function
        cmd = line[0].strip()
        if cmd in self.COMMANDS:
            impl = getattr(self, 'complete_%s' % cmd)
            args = line[1:]
            if args:
                return (impl(args) + [None])[state]
            return [cmd + ' '][state]
        results = [
            c + ' ' for c in self.COMMANDS if c.startswith(cmd)] + [None]
        return results[state]

Completer 을 정의한 후 readline으로 바인딩하면 됩니다:

comp = Completer()


def runCliPrompt():
    try:
        while not quitapp:
            import readline
            readline.set_completer_delims(' \t\n;')
            readline.parse_and_bind("tab: complete")
            readline.set_completer(comp.complete)
            astr = input('milvus_cli > ')
            try:
                cli(astr.split())
            except SystemExit:
                # trap argparse error message
                # print('error', SystemExit)
                continue
    except KeyboardInterrupt:
        sys.exit(0)

일회성 옵션 추가

프롬프트 명령줄의 경우 버전과 같은 일부 정보를 얻기 위해 스크립트를 완전히 실행하고 싶지 않을 때가 있습니다. 좋은 예는 Python, 터미널에서 python 을 입력하면 프롬프트 명령줄이 표시되지만 python -V 을 입력하면 버전 메시지만 반환하고 프롬프트 스크립트를 입력하지 않습니다. 따라서 코드에서 sys.args 을 사용하여 구현할 수 있습니다.

def runCliPrompt():
    args = sys.argv
    if args and (args[-1] == '--version'):
        print(f"Milvus Cli v{getPackageVersion()}")
        return
    try:
        while not quitapp:
            import readline
            readline.set_completer_delims(' \t\n;')
            readline.parse_and_bind("tab: complete")
            readline.set_completer(comp.complete)
            astr = input('milvus_cli > ')
            try:
                cli(astr.split())
            except SystemExit:
                # trap argparse error message
                # print('error', SystemExit)
                continue
    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == '__main__':
    runCliPrompt()

CLI 스크립트를 처음 실행할 때 루프 앞에 sys.args 가 나타납니다. 마지막 인수가 --version 인 경우 코드는 루프를 실행하지 않고 패키지 버전을 반환합니다.

코드를 패키지로 빌드한 후에 유용하게 사용할 수 있습니다. 사용자는 milvus_cli 을 입력하여 프롬프트 CLI로 이동하거나 milvus_cli --version 을 입력하여 버전만 가져올 수 있습니다.

빌드 및 릴리스

마지막으로 패키지를 빌드하고 PYPI로 릴리스하려고 합니다. 그러면 사용자는 pip install <package name> 을 사용하여 간단히 설치할 수 있습니다.

테스트를 위해 로컬에 설치

패키지를 PYPI에 게시하기 전에 몇 가지 테스트를 위해 로컬에 설치하고 싶을 수 있습니다.

이 경우 cd 을 패키지 디렉토리에 넣고 pip install -e . 을 실행하면 됩니다( . 을 잊지 마세요).

패키지 파일 만들기

참조: https://packaging.python.org/tutorials/packaging-projects/

패키지의 구조는 다음과 같아야 합니다:

package_example/
├── LICENSE
├── README.md
├── setup.py
├── src/
│   ├── __init__.py
│   ├── main.py
│   └── scripts/
│       ├── __init__.py
│       └── example.py
└── tests/

패키지 디렉터리 만들기

아래 구조로 Milvus_cli 디렉터리를 만듭니다:

Milvus_cli/
├── LICENSE
├── README.md
├── setup.py
├── milvus_cli/
│   ├── __init__.py
│   ├── main.py
│   ├── utils.py
│   └── scripts/
│       ├── __init__.py
│       └── milvus_cli.py
└── dist/

엔트리 코드를 작성합니다.

스크립트의 항목은 Milvus_cli/milvus_cli/scripts 에 있어야 하며 Milvus_cli/milvus_cli/scripts/milvus_cli.py 은 다음과 같아야 합니다:

import sys
import os
import click
from utils import PyOrm, Completer


pass_context = click.make_pass_decorator(PyOrm, ensure=True)


@click.group(no_args_is_help=False, add_help_option=False, invoke_without_command=True)
@click.pass_context
def cli(ctx):
    """Milvus CLI"""
    ctx.obj = PyOrm()

"""
...
Here your code.
...
"""

@cli.command('exit')
def quitapp():
    """Exit the CLI."""
    global quitapp
    quitapp = True


quitapp = False  # global flag
comp = Completer()


def runCliPrompt():
    args = sys.argv
    if args and (args[-1] == '--version'):
        print(f"Milvus Cli v{getPackageVersion()}")
        return
    try:
        while not quitapp:
            import readline
            readline.set_completer_delims(' \t\n;')
            readline.parse_and_bind("tab: complete")
            readline.set_completer(comp.complete)
            astr = input('milvus_cli > ')
            try:
                cli(astr.split())
            except SystemExit:
                # trap argparse error message
                # print('error', SystemExit)
                continue
            except Exception as e:
                click.echo(
                    message=f"Error occurred!\n{str(e)}", err=True)
    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == '__main__':
    runCliPrompt()

다음과 같아야 합니다. setup.py

from setuptools import setup, find_packages

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setup(
    name='milvus_cli',
    version='0.1.6',
    author='Milvus Team',
    author_email='milvus-team@zilliz.com',
    url='https://github.com/milvus-io/milvus_cli',
    description='CLI for Milvus',
    long_description=long_description,
    long_description_content_type='text/markdown',
    license='Apache-2.0',
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        'Click==8.0.1',
        'pymilvus==2.0.0rc5',
        'tabulate==0.8.9'
    ],
    entry_points={
        'console_scripts': [
            'milvus_cli = milvus_cli.scripts.milvus_cli:runCliPrompt',
        ],
    },
    python_requires='>=3.8'
)

여기에 몇 가지 팁이 있습니다:

  1. 패키지의 긴 설명으로 README.md 콘텐츠를 사용합니다.
  2. 모든 종속성을 install_requires 에 추가합니다.
  3. entry_points 을 지정합니다. 이 경우 milvus_cliconsole_scripts 의 하위 항목으로 설정하여 이 패키지를 설치한 후 바로 milvus_cli 을 명령으로 입력할 수 있도록 합니다. 그리고 milvus_cli 의 진입점은 milvus_cli/scripts/milvus_cli.pyrunCliPrompt 함수입니다.

빌드

  1. build 패키지를 업그레이드합니다: python3 -m pip install --upgrade build

  2. 빌드를 실행합니다: python -m build --sdist --wheel --outdir dist/ .

  3. dist/ 디렉토리에 두 개의 파일이 생성됩니다:

dist/
  example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
  example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz

릴리스 게시

참조: https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives

  1. twine 패키지를 업그레이드합니다: python3 -m pip install --upgrade twine
  2. PYPI 테스트 환경에 업로드합니다: python3 -m twine upload --repository testpypi dist/*
  3. PYPI 에 업로드합니다: python3 -m twine upload dist/*

Github 워크플로우별 CI/CD

참조: https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/

우리는 자동으로 에셋을 업로드하는 방법을 원하며, 패키지를 빌드하고 github 릴리스와 PYPI에 업로드할 수 있습니다.

(어떤 이유에서인지 워크플로에서 PYPI를 테스트하기 위한 릴리스만 게시하기를 원합니다.)

# This is a basic workflow to help you get started with Actions

name: Update the release's assets after it published

# Controls when the workflow will run
on:
  release:
    # The workflow will run after release published
    types: [published]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
        with:
          python-version: '3.8'
          architecture: 'x64'
      - name: Install pypa/build
        run: >-
          python -m
          pip install
          build
          --user
      - name: Clean dist/
        run: |
          sudo rm -fr dist/*
      - name: Build a binary wheel and a source tarball
        run: >-
          python -m
          build
          --sdist
          --wheel
          --outdir dist/
          .
      # Update target github release's assets
      - name: Update assets
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          files: ./dist/*
      - name: Publish distribution 📦 to Test PyPI
        if: contains(github.ref, 'beta') && startsWith(github.ref, 'refs/tags')
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.TEST_PYPI_API_TOKEN }}
          repository_url: https://test.pypi.org/legacy/
          packages_dir: dist/
          verify_metadata: false

Milvus에 대해 자세히 알아보기

Milvus는 방대한 인공 지능 및 벡터 유사도 검색 애플리케이션을 구동할 수 있는 강력한 도구입니다. 프로젝트에 대해 자세히 알아보려면 다음 리소스를 확인하세요:

  • 블로그 읽기.
  • Slack의 오픈 소스 커뮤니티와 교류하세요.
  • GitHub에서 세계에서 가장 인기 있는 벡터 데이터베이스를 사용하거나 기여하세요.
  • 새로운 부트캠프를 통해 AI 애플리케이션을 빠르게 테스트하고 배포하세요.

Like the article? Spread the word

계속 읽기