CPVM Python API

Usable both : inside fragments and using PaaS from clent side code

Начало работы

Авторизация:

import acapela
ap = acapela.AcapellaApi()

ap.auth.login('Alex', 'pass')

# если запрос прошел успешно в этих полях будет информация о текущей сессии:
print(ap.auth.user_id)
print(ap.auth.token)

После успешного выполнения команды auth.login все запросы для данного экземпляра AcapellaApi будут идти с токеном сессии.

Залив фрагментов

import acapela
from acapella.codebase import NewSnapshotResponse, ExecutorType

ap = acapela.AcapellaApi()

resp: NewSnapshotResponse = ap.codebase.create_snapshot(
            name = 'MySnapshot', 
            tag = 'v1.0', 
            # пытаемся автоматически добавить в снапшот фрагмент, который уже когда-то загружался в Acapella
            fragment_hashes = {
                'some/existing/fragment.py': 'sha1hash_23a339ca298b13343775d688aa866e7'
            }
)

# в notFound будут фрагменты которые не добавились в снапшот (не нашлись по хешу)       
if len(resp.notFound) > 0:
    print(resp.notFound) 
    ap.codebase.upload(
        sn_name: resp.snapshot.name,
        sn_tag: resp.snapshot.tag,
        path: 'another/fragment.lua',
        executable: 'print("hello")',
        exec_types: [ExecutorType.VM_LUAJ, ExecutorType.LUAJIT])

# ap.codebase.create_snapshot может вернуть уже замороженный снапшот, если все хеши фрагментов совпали
if not resp.snapshot.frozen:
    ap.codebase.freeze(resp.snapshot.name, resp.snapshot.tag)

Простой запуск

import acapela
from acapella.vm import TransactionParameters, ExecutionTimeout, TransactionStatus, TransactionState

ap = acapela.AcapellaApi()

resp = ap.call(
        sn_owner = 'Alex',
        sn_name = 'MySnapshot',
        sn_tag = 'v1.0',
        fr_path = "another/fragment.lua",
        args = {})

tr_id = resp.transaction_id

Запуск с подробной конфигурацией

from acapella.logs import LogParameters, LoggingParameters, LogScope

common_log = LogParameters(
    id = 'my_log',
    scope = LogScope.TRANSACTION
)

fr_log = LogParameters(
    id = 'fr_log',
    scope = LogScope.FRAGMENT
)

exec_log = LogParameters(
    id = 'fr_log',
    scope = LogScope.EXECUTION
)

params = TransactionParameters(
     fragment = f'Alex/MySnapshot/v1.0:another/fragment.lua',
     arguments = {},
     logging = LoggingParameters(
         redirections = {
             'stderr': common_log,
             'stdout': common_log,
             'my_custom_fr_stream1': fr_log,
             'my_custom_fr_stream2': exec_log,
             'my_custom_fr_stream3': common_log
         },
         allowCreateLogs = False
     ),
     tvmCount = 3,
     failover = False,
     allowRestart = True,
     allowSubFragments = True,
     allowConvertSyncToAsync = True,
     allowConvertAsyncToSync = True,
     resolveConflicts = True,
     syncTvmIo=True,
     beginKvTransaction=False
)

tr_id = ap.vm.start_transaction(params).transaction_id

Чтение лога

Все функции чтения логов блокируются до их завершения и выводят бинарный поток через параметр output (объект следующий контракту io.RawIOBase, например sys.stdout/sys.stderr или file object).

# лог конкретного исполнения определенного фрагмента (scope EXECUTION)
ap.vm.read_execution_log(tr_id, 'another/fragment.lua', 
                         dam = '1.0.255x12.4', 
                         log_id = 'my_log', 
                         output = sys.stdout)

# общий лог для всех исполнений определнного прототипа (scope FRAGMENT)
ap.vm.read_fragment_log(tr_id, 'another/fragment.lua', output = sys.stdout)

# общий лог всей транзакции (scope TRANSACTION)
ap.vm.read_tr_log(tr_id, output = sys.stdout)

# общий лог для всех транзакций текущего пользователя
ap.vm.read_global_log(output = sys.stdout)

Ожидание завершения транзакции

Если в процессе работы вы пытаетесь читать лог со скоупами EXECUTION, FRAGMENT, TRANSACTION, то по завершению транзакции этот лог тоже завершается. Обычное ожидание вылядит так:

status = ap.vm.wait_transaction(tr_id)

if status.state == TransactionState.FINISHED.value:
    print(status.statistics)
else
    print(status.error)