🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI

Gambaran Umum

  • Engineering
September 15, 2021
Zhen Chen

Gambaran Umum

URL proyek: https://github.com/milvus-io/milvus_cli

Persiapan Python3.8, Click 8.0.x

Perintah grup

Membuat sebuah perintah

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()

Seperti kode di atas, kita menggunakan @click.group() untuk membuat grup perintah cli sebagai titik masuk. Untuk mengimplementasikan CLI yang cepat, kita perlu menonaktifkan pesan bantuan untuk entri tersebut, jadi kita tambahkan no_args_is_help=False, add_help_option=False dan invoke_without_command=True. Dan tidak ada yang akan dicetak jika kita memasukkan cli di terminal saja.

Selain itu kita menggunakan @click.pass_context untuk memberikan konteks ke grup ini untuk penggunaan lebih lanjut.

Membuat sub perintah dari grup perintah

Kemudian kita tambahkan sub perintah pertama help di bawah cli:

# 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))

Sekarang kita dapat menggunakan cli help di terminal:

$ python milvus_cli/scripts/milvus_cli.py help

Membuat sub grup dari grup perintah

Kita tidak hanya ingin memiliki sub perintah seperti cli help, tetapi kita juga membutuhkan sub grup perintah seperti cli list collection, cli list partition dan cli list indexes.

Pertama kita buat sub grup perintah list, disini kita bisa memberikan parameter pertama ke @cli.group sebagai nama perintah dan bukan menggunakan nama fungsi default, sehingga kita bisa mengurangi duplikasi nama fungsi.

Perhatian di sini, kita menggunakan @cli.group() dan bukan @click.group sehingga kita membuat sub grup dari grup asal.

Kita menggunakan @click.pass_obj untuk meneruskan context.obj ke sub perintah dari sub grup ini.

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

Kemudian kita menambahkan beberapa sub perintah ke dalam sub grup ini dengan @listDetails.command() (bukan @cli.command()). Ini hanya sebuah contoh, Anda dapat mengabaikan implementasinya dan kita akan membahasnya nanti.

@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)

Setelah semua ini selesai, kita memiliki perintah miltigroup yang terlihat seperti:

image image

Menyesuaikan sebuah perintah

Menambahkan opsi

Anda dapat menambahkan beberapa opsi pada perintah yang akan digunakan seperti cli --test-option value.

Berikut ini adalah contohnya, kita menambahkan tiga opsi alias, host dan port untuk menentukan alamat yang akan terhubung ke Milvus.

Dua parameter pertama mendefinisikan nama opsi singkat dan lengkap, parameter ketiga mendefinisikan nama variabel, parameter help menentukan pesan bantuan singkat, parameter default menentukan nilai default dan type menentukan tipe nilai.

Dan semua nilai opsi akan diteruskan ke dalam fungsi sesuai dengan urutan definisi.

@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

Menambahkan opsi bendera

Kita menggunakan opsi di atas untuk mengoper nilai, tetapi terkadang kita hanya membutuhkan flag sebagai nilai boolean.

Seperti contoh di bawah ini, opsi autoId adalah opsi flag dan tidak mengoper data apa pun ke fungsi, jadi kita dapat menggunakannya seperti 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

Menambahkan argumen

Dalam proyek ini kita mengganti semua penggunaan argumen dengan penggunaan opsi. Namun kita masih memperkenalkan penggunaan argumen di sini. Berbeda dengan options, argumen digunakan seperti cli COMMAND [OPTIONS] ARGUEMENTS. Jika kita ubah contoh di atas menjadi penggunaan argumen, maka akan menjadi seperti ini:

@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

Maka penggunaannya akan menjadi cli create collection c_name -p p_name -a.

Menambahkan pesan bantuan lengkap

Setelah kita mendefinisikan pesan bantuan singkat di atas, kita dapat mendefinisikan pesan bantuan lengkap di dalam fungsi:

@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))

Blok pertama di dalam fungsi tersebut adalah pesan bantuan yang akan dicetak setelah kita memasukkan 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.

Tambahkan konfirmasi

Terkadang kita membutuhkan pengguna untuk mengkonfirmasi beberapa tindakan, terutama menghapus sesuatu. Kita dapat menambahkan click.confirm untuk menjeda dan meminta pengguna untuk mengkonfirmasi:

@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

Seperti contoh di atas, percakapan konfirmasi akan muncul seperti Aborted!ant to continue? [y/N]:.

Tambahkan petunjuk

Untuk mengimplementasikan prompt, kita perlu menambahkan 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

Prompt akan muncul ketika setiap click.prompt. Kami menggunakan beberapa prompt secara berurutan sehingga akan terlihat seperti percakapan yang berkelanjutan. Hal ini memastikan pengguna akan memasukkan data sesuai dengan urutan yang kita inginkan. Dalam hal ini kita membutuhkan pengguna untuk memilih sebuah koleksi terlebih dahulu, dan kita perlu mendapatkan semua partisi di bawah koleksi tersebut, lalu menampilkannya kepada pengguna untuk dipilih.

Menambahkan pilihan

Terkadang Anda ingin pengguna hanya memasukkan rentang/jenis nilai yang terbatas, Anda dapat menambahkan type=click.Choice([<any>]) ke click.prompt, click.options dan lain-lain.

Misalnya,

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

Maka pengguna hanya dapat memasukkan collection_1 atau collection_2, kesalahan akan muncul jika ada input lain.

Tambahkan layar yang jelas

Anda dapat menggunakan click.clear() untuk mengimplementasikannya.

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

Tips tambahan

  • Nilai defaultnya adalah None, jadi tidak ada artinya jika Anda menentukan nilai default sebagai None. Dan default None akan menyebabkan click.prompt terus ditampilkan jika Anda ingin mengosongkan nilai untuk melompati nilai tersebut.

Menerapkan prompt CLI untuk pengguna untuk memasukkan input

Mengapa prompt CLI

Untuk operasi basis data, kita membutuhkan koneksi secara terus menerus ke sebuah instance. Jika kita menggunakan mode baris perintah asal, koneksi akan terputus setelah setiap perintah dilakukan. Kita juga ingin menyimpan beberapa data ketika menggunakan CLI, dan membersihkannya setelah keluar.

Menerapkan

  1. Gunakan while True untuk mendengarkan input pengguna secara terus menerus.
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. Penggunaan input saja akan menyebabkan up, down, left, right tombol panah, tombol tab dan beberapa tombol lainnya dikonversi ke string Acsii secara otomatis. Selain itu perintah history tidak dapat dibaca dari session. Jadi kita tambahkan readline ke dalam fungsi runCliPrompt.
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. Tambahkan 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. Tangkap kesalahan KeyboardInterrupt saat menggunakan ctrl C untuk keluar.
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. Setelah semua beres, tampilan CLI sekarang menjadi seperti ini:
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

Menerapkan pelengkapan otomatis secara manual

Berbeda dengan pelengkapan otomatis shell klik, proyek kita membungkus baris perintah dan menggunakan perulangan untuk mendapatkan masukan dari pengguna untuk mengimplementasikan baris perintah prompt. Jadi kita perlu mengikat pelengkap ke 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]

Setelah mendefinisikan Completer kita bisa mengikatnya dengan 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)

Menambahkan opsi satu kali

Untuk baris perintah prompt, terkadang kita tidak ingin sepenuhnya menjalankan script untuk mendapatkan beberapa informasi seperti versi. Contoh yang baik adalah Python, ketika Anda mengetik python di terminal, baris perintah promtp akan muncul, tetapi hanya mengembalikan pesan versi dan tidak akan masuk ke dalam skrip prompt jika Anda mengetik python -V. Jadi kita dapat menggunakan sys.args dalam kode kita untuk mengimplementasikannya.

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()

Kita mendapatkan sys.args sebelum perulangan ketika pertama kali menjalankan skrip CLI. Jika argumen terakhir adalah --version, kode akan mengembalikan versi paket tanpa mengalami perulangan.

Ini akan sangat membantu setelah kita membuat kode sebagai sebuah paket. Pengguna dapat mengetikkan milvus_cli untuk langsung masuk ke CLI, atau mengetikkan milvus_cli --version untuk mendapatkan versinya saja.

Membangun dan merilis

Terakhir, kita ingin membangun sebuah paket dan merilisnya dengan PYPI. Sehingga pengguna cukup menggunakan pip install <package name> untuk menginstal.

Menginstal secara lokal untuk pengujian

Sebelum Anda mempublikasikan paket ke PYPI, Anda mungkin ingin menginstalnya secara lokal untuk beberapa pengujian.

Dalam hal ini, Anda cukup memasukkan cd ke dalam direktori paket dan menjalankan pip install -e . (Jangan lupa .).

Membuat berkas-berkas paket

Lihat: https://packaging.python.org/tutorials/packaging-projects/

Struktur sebuah paket akan terlihat seperti ini:

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

Membuat direktori paket

Buat direktori Milvus_cli dengan struktur di bawah ini:

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

Tulis kode entri

Entri skrip harus berada di Milvus_cli/milvus_cli/scripts, dan Milvus_cli/milvus_cli/scripts/milvus_cli.py harus seperti:

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()

Edit 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'
)

Beberapa tips di sini:

  1. Kami menggunakan konten README.md sebagai deskripsi panjang paket.
  2. Tambahkan semua dependensi ke install_requires.
  3. Tentukan entry_points. Dalam kasus ini, kita menetapkan milvus_cli sebagai anak dari console_scripts, sehingga kita dapat mengetikkan milvus_cli sebagai perintah secara langsung setelah kita menginstal paket ini. Dan titik masuk milvus_cli adalah fungsi runCliPrompt di milvus_cli/scripts/milvus_cli.py.

Membangun

  1. Tingkatkan paket build: python3 -m pip install --upgrade build

  2. Jalankan build: python -m build --sdist --wheel --outdir dist/ .

  3. Dua berkas akan dihasilkan di bawah direktori dist/:

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

Publikasikan rilis

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

  1. Tingkatkan paket twine: python3 -m pip install --upgrade twine
  2. Unggah ke PYPI test env: python3 -m twine upload --repository testpypi dist/*
  3. Unggah ke PYPI: python3 -m twine upload dist/*

Alur kerja CI/CD oleh Github

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

Kami ingin ada cara untuk mengunggah aset secara otomatis, yang dapat membangun paket dan mengunggahnya ke rilis github dan PYPI.

(Untuk beberapa alasan, kami hanya ingin alur kerja hanya mempublikasikan rilis untuk menguji 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

Pelajari lebih lanjut tentang Milvus

Milvus adalah alat yang kuat yang mampu memberdayakan beragam kecerdasan buatan dan aplikasi pencarian kemiripan vektor. Untuk mempelajari lebih lanjut tentang proyek ini, lihat sumber-sumber berikut:

  • Baca blog kami.
  • Berinteraksi dengan komunitas sumber terbuka kami di Slack.
  • Gunakan atau kontribusikan database vektor paling populer di dunia di GitHub.
  • Menguji dan menerapkan aplikasi AI dengan cepat menggunakan bootcamp baru kami.

Like the article? Spread the word

Terus Baca