Builtins
This chapter describes the AXIS namespace when executing custom scripts in a scenario or custom methods in ATOM.
In the namespace, there are a python module imported by default, an AXIS built-in function, an atom module, a model module, and a context containing plug-in modules and functions.
Module
python module imported by default into the namespace is as follows:
asyncio
datetime
ipaddress
json
re
sqlalchemy
statistics
time
traceback
urllib
uuid
xmltodict
yaml
When a developer installs additional modules by pip etc., the default import is performed by importing directly in the script or specifying module names separated by commas in --python_default_imports
in the startup parameter of AXIS.
--python_default_imports=boto3,kubernetes
Function
category | name | type | description |
---|---|---|---|
Basic | Error | class | Exception class. It is strongly recommended to use this class when throwing an exception. |
HTTPError | class | Exception class. It may become unusable in future releases due to deprecation . |
|
options | module | Module used to reference startup parameters. | |
logger | object | Logger object. | |
context | object | Object with accessor to plug-in module or function. | |
API | callout | function | API call function. |
status_poll | function | API polling function. It can be used to monitor state transitions. | |
queryjoin | function | Function to convert dictionary type to query string and generate URL. | |
asyncIO | multi | function | Function to wait for multiple coroutines. Same behavior as asyncio.gather . |
Awaitable | function | Function to co-routineize synchronous blocking call. It is recommended to use this function for co-routineization. | |
futureization | function | Function to co-routineize synchronous blocking call. It may be discontinued in the future because of deprecation . |
|
add_timeout | function | Function to delay function execution. | |
Schedule | regist_booking | function | Reservation registration function to schedule service. |
cancel_booking | function | Reservation cancellation function to schedule service. | |
modify_booking | function | Reservation modification function to schedule service. | |
retrieve_booking | function | Reservation search function from schedule service. | |
Transaction | get_transactions | function | Function to retrieve transaction from transaction service. |
transaction_active_check | function | Function to check if the specified transaction is still running. | |
Lambda | lambda_event | function | Function that raises lambda event. |
lambda_terminate | function | Function to wait for completion of lambda event and get the result. | |
lambda_bulk_terminate | function | Function to wait for completion of multiple lambda events and get list result in list. | |
Scenario | Scenario.load | function | Function to get scenario and return in execution format. |
Daemon.load | function | Function to get daemon and return in execution format. | |
Scenario.run | function | Function to run the specified scenario. | |
Daemon.run | function | Function to run the specified daemon. | |
get_service_config | function | A function to get the config with the specified name defined in the Config service. |
|
rendering | function | A function to get the rendering result of the template service to the specified template. |
|
task | function | Function to issue task | |
RDBMS | model | module | For object mapping of the table created from modelschema and ATOM and DB connection creation Context Manager is included in the package. |
and_ | function | AND conditional expression function (see SQL Alchemy ) |
|
or_ | function | OR conditional expression function (see SQL Alchemy ) |
|
not_ | function | NOT conditional expression function (see SQL Alchemy ) |
|
select | function | SELECT expression function (see SQL Alchemy ) |
|
join | function | JOIN expression function (see SQL Alchemy ) |
|
where_statement | function | Function to generate WHERE statement |
|
rowtodict | function | Function to convert row fetched from database to dict of python | |
SQL.run | function | Query function | |
GraphDB | neo4j | function | Function to get session to Neo4j |
nodetodict | function | Function to convert node fetched from graph database to dict of python | |
Redis | Redis | class | Context manager for manipulating redis. Use by plug-in developers is deprecated . |
pubsub | function | Publish Function to notify. Use by plug-in developers is deprecated . |
|
ATOM | deserialize | function | Function to restore JSON string to ATOM instance. |
drop_class | function | Function to delete ATOM class. Use by plug-in developers is deprecated . |
|
clear_redis_pool | function | Function to clean the redis connection pool. Use by plug-in developers is deprecated . |
|
XML | dict2xml | function | Function to convert a dictionary object to an XML string. |
ElementTree | class | Accessor to ElementTree class of xml library. | |
gRPC | gRPC | function | Function to get the gRPC client. |
Parse | function | Protocol buffer parser. | |
MessageToJson | function | Function to convert gRPC response to json string. | |
SNMP | SNMPv2 | class | SNMPv2 client |
SNMPv3 | class | SNMPv3 client | |
Cluster | raft | object | An object to access cluster information in Raft cluster mode. |
Utilities | magic | function | A function that returns dict with the key filter and key name conversion rule specified fordict . |
MU | class | It is Mutable Universal object . See the chapter on Datamodel. |
|
Frozen | class | It is a class that makes dict a frozen object. This class is deprecated , please use MU . |
|
clock | object | Utility object used for time processing. | |
ipam | object | Accessor object to IPAM service. | |
scp | function | Secure Copy function. | |
slack | function | Function to send a message to slack. You need to set the startup parameters appropriately. | |
genkey | function | Password generation function. | |
encrypt | function | Encryption function. | |
decrypt | function | Decryption function. | |
flattening | function | Function that converts a multi-level key dict object into a one-level dict object. The second and subsequent layers are stringified. |
Interactive shell
Interactive Shell is a feature that allows plug-in developers to try out the scripting of AXIS like REPL. The interactive shell works with the AXIS script execution namespace, so you can write and test code snipet with the above built-in and plug-ins.
Let's use some built-in functions in the interactive shell.
Example of using queryjoin
>>> print(queryjoin("/hoges", status=["active", "processing"], name="test"))↵
... ↵
/hoges?status=active&status=processing&name=test↵
↵
Example of using multi
>>> responses = await multi([callout(url="http://yahoo.co.jp") for i in range(10)])↵
... print([i.code for i in responses])↵
... ↵
[200, 200, 200, 200, 200, 200, 200, 200, 200, 200]↵
↵
Example of using Awaitable
>>> print(clock.now())↵
... await Awaitable(time.sleep, 3)↵
... print(clock.now())↵
... ↵
2019-04-24 11:11:39.392098+09:00↵
↵
2019-04-24 11:11:42.395468+09:00↵
↵
Example of using genkey
>>> print(genkey())↵
... ↵
D5AFlqE4yUoGPfUVGYuMJmm4RRli8jqk86Y3pkWfxUjYbsX3n9FyAzF8jqfHXEEJ↵
↵
>>> print(genkey(length=10, continuity=2))↵
... ↵
u66dkDHVab↵
↵`
Supported SQL execution from v19.11R1
...Connecting To : Scenario Master(192.168.172.141:9099)↵
AXIS Wild Side v19.11R1 [core-dev-py37(192.168.172.141)]
2019-11-06T10:10:53.859171+09:00
Type "copyright", "help", "commands", "tree"
↵
>>> a = atom.Aaa(name="hoge1", b=atom.Bbb(name="hoge2"))↵
... await a.save()↵
... ↵
... select * from Aaa;↵
| instance | xid | xname | name | b | status |
QWFhOjUzZWI0MjYwMDAzMjExZWE4MGIxMDAwYzI5ZGQ4MjUw NULL NULL hoge1 QmJiOjUzZWIyYzU4MDAzMjExZWE4MGIxMDAwYzI5ZGQ4MjUw NULL↵
>>> update Aaa set name="hoge123" where name="hoge1";↵
>>> select * from Aaa;↵
| instance | xid | xname | name | b | status |
QWFhOjUzZWI0MjYwMDAzMjExZWE4MGIxMDAwYzI5ZGQ4MjUw NULL NULL hoge123 QmJiOjUzZWIyYzU4MDAzMjExZWE4MGIxMDAwYzI5ZGQ4MjUw NULL↵
>>> a = await atom.Aaa.load("QWFhOjUzZWI0MjYwMDAzMjExZWE4MGIxMDAwYzI5ZGQ4MjUw")↵
... print(a.name)↵
... ↵
hoge123↵
>>> desc Aaa;↵
| Field | Type | Null | Key | Default | Extra |
instance varchar(255) NO PRI NULL
xid varchar(255) YES NULL
xname varchar(255) YES NULL
name varchar(255) YES UNI NULL
b mediumtext YES NULL
status varchar(255) YES NULL ↵
>>>
Example of using SNMPv2
...Connecting To : 127.0.0.1:9099(127.0.0.1:9099)
Qmonus-SDK v20.7LTS-patch20201015 [UG30-hash-dev.usen.ad.jp(192.168.2.103)]
2020-10-19T11:21:48.273723+09:00
Type "copyright", "help", "commands", "tree"
>>> snmp = SNMPv2("public")↵
... r = await snmp.get("192.168.2.200", oid="1.3.6.1.2.1.1.5.0")↵
... print(MU(r).yaml_format)↵
... ↵
address: 192.168.2.200
errorIndex: null
errorIndication: null
errorStatus: null
errorVarBind: null
objectType: DisplayString
oid: 1.3.6.1.2.1.1.5.0
value: csr1000v.ftth.ucom.ne.jp
↵
>>>
>>> r = await snmp.bulk("192.168.2.200", oids=["1.3.6.1.2.1.1"])↵
... for i in r:↵
... print(MU(i).yaml_format)↵
... ↵
address: 192.168.2.200
errorIndex: null
errorIndication: null
errorStatus: null
errorVarBind: null
oid: 1.3.6.1.2.1.1.1.0
type: DisplayString
value: "Cisco IOS Software, CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version\
\ 15.5(2)S, RELEASE SOFTWARE (fc3)\r\nTechnical Support: http://www.cisco.com/techsupport\r\
\nCopyright (c) 1986-2015 by Cisco Systems, Inc.\r\nCompiled Sun 22-Mar-15 01:36\
\ by mcpre"
address: 192.168.2.200
errorIndex: null
errorIndication: null
errorStatus: null
errorVarBind: null
oid: 1.3.6.1.2.1.1.2.0
type: ObjectIdentity
value: SNMPv2-SMI::enterprises.9.1.1537
...
>>>
>>>
>>> r = await snmp.getInterfaces("192.168.2.200")↵
>>> for i in r:↵
... print(i)↵
... ↵
{'index': '1', 'description': 'GigabitEthernet1'}
{'index': '2', 'description': 'GigabitEthernet2'}
{'index': '3', 'description': 'GigabitEthernet3'}
{'index': '4', 'description': 'VoIP-Null0'}
{'index': '5', 'description': 'Null0'}
↵
>>>
HTTP functions
callout
API calls use the callout
built-in function.
The main arguments are as follows:
argument | default | description |
---|---|---|
url | None | When specified, send directly from the scenario server to the specified URL (APIGW does not pass) |
endpoint | None | Send to specified endpoint. It is invalid when URL is specified. |
path | None | Specifies the HTTP request path. |
method | None | Specifies the HTTP request method. Default is GET .(POST|PUT|DELETE|GET|PATCH ) |
body | None | Specifies the HTTP request body.(str|list|dict types) |
static_route | None | Set the value in X-Xaas-Static-Routing of the request header. |
connect_timeout | None | Specifies the HTTP connect timeout. The default is the startup parameter --callout_connect_timeout . |
request_timeout | None | Specifies the HTTP request timeout. The default is the startup parameter --callout_request_timeout . |
retry_interval | None | Specify retry interval when HTTP error code specified in retry_codes is received. |
retry_count | None | Specify retry count when HTTP error code specified in retry_codes is received. |
retry_codes | None | Specifies the HTTP error code to be retried. |
authentication | None | Specifies authentication options. |
lambda_termination | None | Specifies whether to wait for the end of the lambda event and return the result in the case of the lambda proxy API call. |
validate_cert | None | For HTTPS requests, validate the server’s certificate? Default is True. |
ca_certs | None | Filename of CA certificates in PEM format, or None to use defaults. |
client_key | None | Filename for client SSL key, if any. |
client_cert | None | Filename for client SSL certificate, if any. |
Example of use
Direct communication from scenario server to endpoint
response = await callout(url="https://www.yahoo.co.jp")
Communication via APIGW
response = await callout(path="/v2.0/tenants")
BASIC certification
response = await callout(path="/example/basicAuthentications",
authentication=dict(auth_mode="basic",
username="admin",
password="admin"))
DIGEST certification
response = await callout(path="/example/digestAuthentications",
authentication=dict(auth_mode="digest",
username="admin",
password="admin"))
Keystone certification
response = await callout(path="/v2.0/tenants",
authentication=dict(auth_mode="keystone",
username="{username}",
password="{password}",
project_id="{project_id"}))
AWS-HMAC-V4 certification
response = await callout(url="directconnect.ap-northeast-1.amazonaws.com",
method="POST",
body=dict(connectionId="xxxxx"),
authentication=dict(auth_mode="AWS-HMAC-V4",
username="xxxxx",
password="xxxxx",
domain_id="ap-notrheast-1",
domain_name="DirectConnect",
project_id="DescribeVirtualInterfaces"))
Tip
Naturally, developers can also describe the authentication process without using the authentication option. If you use the authentication option, AXIS will cache and reuse the credentials. At expire time, it will be recaptured and re-cached automatically.
Retry in case of exclusive error (409 Conflict) and communication disconnection (599)
response = await callout(path="/v2.0/tenants",
method="POST",
body=dict(name="Sample tenant"),
retry_count=2,
retry_interval=3,
retry_codes=[409, 599])
status_poll
In resource control with REST-API, there are many cases of status polling. The status_poll
built-in function can write status polling simply.
argument | default | description |
---|---|---|
url | None | When specified, send directly from the scenario server to the specified URL (APIGW does not pass) |
endpoint | None | Send to specified endpoint. It is invalid when URL is specified. |
path | None | Specifies the HTTP request path. |
method | None | Specifies the HTTP request method. Default is GET .(POST|PUT|DELETE|GET|PATCH ) |
body | None | Specifies the HTTP request body.(str|list|dict types) |
connect_timeout | None | Specifies the HTTP connect timeout. The default is the startup parameter --callout_connect_timeout . |
request_timeout | None | Specifies the HTTP request timeout. The default is the startup parameter --callout_request_timeout . |
retry_interval | None | Specify retry interval |
retry_count | None | Specify retry count |
authentication | None | Specifies authentication options. |
xid | None | Transactions can be aborted during state polling. If you specify xid , transaction confirmation is performed at polling time, and abort will stop it. |
status_key | None | Key name to monitor as status attribute |
expected_status | [] | Expected state value candidate. If it matches, it will return a tuple of True and the response object. |
unexpected_status | [] | Not expected state value candidate. If it matches, it will return a tuple of False and the response object. |
break_codes | [] | HTTP response code candidate leaving status polling. If it matches, it will return a tuple of True and the response object. |
break_schemas | [] | HTTP body schema candidate leaving status polling. If it matches, it will return a tuple of True and the response object. |
fault_codes | [] | Failure judgment HTTP response code candidate. If it matches, it will return a tuple of False and the response object. |
countdown_hook | None | Specify a function to hook status polling. |
Example of use
result, response = await status_poll(path="/v2.0/networks/72a1b7a667e011e993ac000c29dd8250",
retry_interval=5,
retry_count=60,
xid=context.axis.xid,
status_key="status",
expected_status=["active"],
unexpected_status=["error"])
Database
Persistence tables automatically generated by modelschema or ATOM are ORM by SQLAlchemy and dynamically incorporated under the model module. A function for nonblocking execution of the connection to the database is also provided in the model module.
The RDBMS supported by AXIS are MySQL, PostgreSQL and SQLite3. The built-in functions and module used to operate the database are as follows:
name | type | description |
---|---|---|
model | module | For object mapping of the table created from modelschema and ATOM and DB connection creation Context Manager is included in the package. |
and_ | function | AND conditional expression function (see SQL Alchemy ) |
or_ | function | OR conditional expression function (see SQL Alchemy ) |
not_ | function | NOT conditional expression function (see SQL Alchemy ) |
select | function | SELECT expression function (see SQL Alchemy ) |
join | function | JOIN expression function (see SQL Alchemy ) |
where_statement | function | Function to generate WHERE statement |
rowtodict | function | Function to convert row fetched from database to dict of python |
SQL | function | Query function |
neo4j | function | Function to get session to Neo4j |
nodetodict | function | Function to convert node fetched from graph database to dict of python |
Database connections should use the async with
syntax as follows:
async with model.aiodb() as conn:
# Inside async with you can build and execute SQL freely with the syntax of SQLAlchemy.
cursor = await conn.execute(model.employee.select())
employees = await cursor.fetchall()
Database transaction is as follows:
async with model.aiodb() as conn:
async with conn.begin() as tran:
cursor = await conn.execute(model.employee.select().where(model.employee.c.status=="retired"))
employees = await cursor.fetchall()
[await conn.execute(model.employee.delete().where(model.employee.c.id==i.id)) for i in employees]
Alternatively you can use the SQL
built-in function
# SQLAlchemy
employees = await SQL(model.employee.select())
# Raw SQL statement
employees = await SQL("SELECT * FROM employee;")
# When using SQL function in transaction scope
async with model.aiodb() as conn:
async with conn.begin() as tran:
employees = await SQL(model.employee.select(), conn=conn)
How to use where_statement
employees = await SQL(model.employee.select().where(model.employee.where_statement({"status": "retired"})))
How to use neo4j
and nodetodict
>>> with neo4j() as sess:↵
... r = sess.run("MATCH (n)\nRETURN n")↵
... for i in r:↵
... print(nodetodict(i))↵
... ↵
{'name': 'top1', 'instance': 'VG9wOjhlMzg4OWM0N2I3NTExZTliMDBhMDAwYzI5ZGQ4MjUw', 'age': 10, 'status': True}↵
↵