New project name: Picasso

This commit is contained in:
Denis Makogon 2016-12-07 22:22:52 +02:00
parent ac95817513
commit 729f891158
25 changed files with 162 additions and 156 deletions

View File

@ -1,4 +1,4 @@
[DEFAULT]
test_command=${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./laosclient/tests} $LISTOPT $IDOPTION
test_command=${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./picassoclient/tests} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -13,4 +13,4 @@ Pull requests submitted through GitHub will be ignored.
Bugs should be filed on Launchpad, not GitHub:
https://bugs.launchpad.net/python-laosclient
https://bugs.launchpad.net/python-picassoclient

View File

@ -1,22 +1,21 @@
========================
python-laosclient
python-picassoclient
========================
OpenStack Functions Client Library
This is a client library for Project LaOS built on the Project LaOS API. It
provides a Python API (the ``laosclient`` module) and a command-line
tool (``laos``).
provides a Python API (the ``picassoclient`` module).
The project is hosted on `Launchpad`_, where bugs can be filed. The code is
hosted on `Github`_. Patches must be submitted using `Gerrit`_, *not* Github
pull requests.
.. _Github: https://github.com/iron-io/python-laosclient
.. _Launchpad: https://github.com/iron-io/python-laosclient/issues
.. _Github: https://github.com/iron-io/python-picassoclient
.. _Launchpad: https://github.com/iron-io/python-picassoclient/issues
.. _Gerrit: http://docs.openstack.org/infra/manual/developers.html#development-workflow
python-laosclient is licensed under the Apache License like the rest of
python-picassoclient is licensed under the Apache License like the rest of
OpenStack.
.. contents:: Contents:
@ -24,31 +23,31 @@ OpenStack.
Install the client from PyPI
----------------------------
The :program:`python-laosclient` package is published on `PyPI`_ and
The :program:`python-picassoclient` package is published on `PyPI`_ and
so can be installed using the pip tool, which will manage installing all
python dependencies::
$ pip install python-laosclient
$ pip install python-picassoclient
.. note::
The packages on PyPI may lag behind the git repo in functionality.
.. _PyPI: https://pypi.python.org/pypi/python-laosclient/
.. _PyPI: https://pypi.python.org/pypi/python-picassoclient/
Setup the client from source
----------------------------
* Clone repository for python-laosclient::
* Clone repository for python-picassoclient::
$ git clone https://github.com/iron-io/python-laosclient.git
$ cd python-laosclient
$ git clone https://github.com/iron-io/python-picassoclient.git
$ cd python-picassoclient
* Setup a virtualenv
.. note::
This is an optional step, but will allow laosclient's dependencies
This is an optional step, but will allow picassoclient's dependencies
to be installed in a contained environment that can be easily deleted
if you choose to start over or uninstall laosclient.
if you choose to start over or uninstall picassoclient.
::
@ -64,7 +63,7 @@ All further commands in this section should be run with the venv active:
.. note::
When ALL steps are complete, deactivate the virtualenv: $ deactivate
* Install laosclient and its dependencies::
* Install picassoclient and its dependencies::
(venv) $ python setup.py develop
@ -102,18 +101,18 @@ To use with keystone as the authentication system::
>>> from keystoneclient.auth.identity import generic
>>> from keystoneclient import session
>>> from laosclient import client
>>> from picassoclient import client
>>> auth = generic.Password(auth_url=OS_AUTH_URL, username=OS_USERNAME, password=OS_PASSWORD, tenant_name=OS_TENANT_NAME)
>>> keystone_session = session.Session(auth=auth)
>>> lc = client.Client('v1', session=keystone_session)
>>> lc.apps.list()
>>> picasso = client.Client('v1', session=keystone_session)
>>> picasso.apps.list()
[...]
* License: Apache License, Version 2.0
* Documentation: https://github.com/iron-io/python-laosclient
* Source: https://github.com/iron-io/python-laosclient
* Bugs: https://github.com/iron-io/python-laosclient
* Documentation: https://github.com/iron-io/python-picassoclient
* Source: https://github.com/iron-io/python-picassoclient
* Bugs: https://github.com/iron-io/python-picassoclient
Testing
-------

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# python-laosclient documentation build configuration file, created by
# python-picassoclient documentation build configuration file, created by
# sphinx-quickstart on Tue Dec 6 17:37:53 2016.
#
# This file is execfile()d with the current directory set to its
@ -66,7 +66,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = 'python-laosclient'
project = 'python-picassoclient'
copyright = '2016, Denis Makogon'
author = 'Denis Makogon'
@ -221,7 +221,7 @@ html_static_path = ['_static']
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'python-laosclientdoc'
htmlhelp_basename = 'python-picassoclientdoc'
# -- Options for LaTeX output ---------------------------------------------
@ -243,7 +243,7 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'python-laosclient.tex', 'python-laosclient Documentation',
(master_doc, 'python-picassoclient.tex', 'python-picassoclient Documentation',
'Denis Makogon', 'manual'),
]
@ -273,7 +273,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'python-laosclient', 'python-laosclient Documentation',
(master_doc, 'python-picassoclient', 'python-picassoclient Documentation',
[author], 1)
]
@ -287,8 +287,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'python-laosclient', 'python-laosclient Documentation',
author, 'python-laosclient', 'One line description of project.',
(master_doc, 'python-picassoclient', 'python-picassoclient Documentation',
author, 'python-picassoclient', 'One line description of project.',
'Miscellaneous'),
]

View File

@ -1,30 +0,0 @@
laosclient.v1 package
=====================
Submodules
----------
laosclient.v1.apps module
-------------------------
.. automodule:: laosclient.v1.apps
:members:
:undoc-members:
:show-inheritance:
laosclient.v1.routes module
---------------------------
.. automodule:: laosclient.v1.routes
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: laosclient.v1
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,7 +1,7 @@
laosclient
==========
picassoclient
=============
.. toctree::
:maxdepth: 4
laosclient
picassoclient

View File

@ -1,17 +1,17 @@
laosclient package
==================
picassoclient package
=====================
Subpackages
-----------
.. toctree::
laosclient.v1
picassoclient.v1
Module contents
---------------
.. automodule:: laosclient
.. automodule:: picassoclient
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,30 @@
picassoclient.v1 package
========================
Submodules
----------
picassoclient.v1.apps module
----------------------------
.. automodule:: picassoclient.v1.apps
:members:
:undoc-members:
:show-inheritance:
picassoclient.v1.routes module
------------------------------
.. automodule:: picassoclient.v1.routes
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: picassoclient.v1
:members:
:undoc-members:
:show-inheritance:

View File

@ -14,7 +14,7 @@ import functools
from keystoneauth1 import adapter
from laosclient.common import utils
from picassoclient.common import utils
def Client(version, *args, **kwargs):
@ -35,7 +35,7 @@ def construct_http_client(*args, **kwargs):
service_type=kwargs.get('service_type', 'functions'),
service_name=kwargs.get('service_name', 'functions'),
interface=kwargs.get('endpoint_type', 'public').rstrip('URL'),
user_agent=kwargs.get('user_agent', 'python-laosclient'),
user_agent=kwargs.get('user_agent', 'python-picassoclient'),
endpoint_override=kwargs.get('endpoint_override'),
timeout=kwargs.get('timeout'),
)

View File

@ -17,7 +17,7 @@ from oslo_utils import importutils
def import_versioned_module(version, submodule=None):
module = 'laosclient.%s' % version
module = 'picassoclient.%s' % version
if submodule:
module = '.'.join((module, submodule))
return importutils.import_module(module)

View File

@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
"""oslo_i18n integration module for laosclient.
"""oslo_i18n integration module for picassoclient.
See http://docs.openstack.org/developer/oslo.i18n/usage.html .
@ -19,7 +19,7 @@ See http://docs.openstack.org/developer/oslo.i18n/usage.html .
import oslo_i18n
_translators = oslo_i18n.TranslatorFactory(domain='laosclient')
_translators = oslo_i18n.TranslatorFactory(domain='picassoclient')
# The primary translation function using the well-known name "_"
_ = _translators.primary

View File

@ -21,7 +21,7 @@ DEFAULT_SEARCH_API_VERSION = '1'
API_VERSION_OPTION = 'os_functions_api_version'
API_NAME = 'functions'
API_VERSIONS = {
'1': 'laosclient.v1.client.Client',
'1': 'picassoclient.v1.client.Client',
}

View File

@ -61,7 +61,7 @@ class ShowApp(command.ShowOne):
class CreateApp(command.ShowOne):
"""Creates an app"""
"""Creates app"""
log = logging.getLogger(__name__ + ".CreateApp")
@ -71,7 +71,7 @@ class CreateApp(command.ShowOne):
help="App name to create")
parser.add_argument("--config", metavar="<config>",
help="Config for app to create "
"in JSON format")
"in JSON format", type=json.loads)
return parser
def take_action(self, parsed_args):
@ -79,13 +79,6 @@ class CreateApp(command.ShowOne):
fc = self.app.client_manager.functions
app_name = parsed_args.name
config = parsed_args.config
if config:
try:
config = json.loads(config)
except Exception as ex:
self.log.error("Invalid config JSON. "
"Reason: {}".format(str(ex)))
raise ex
app = fc.apps.create(app_name, config=config)["app"]
keys = list(app.keys())
@ -93,7 +86,7 @@ class CreateApp(command.ShowOne):
class DeleteApp(command.Command):
"""Deletes an app"""
"""Deletes app"""
log = logging.getLogger(__name__ + ".DeleteApp")
def get_parser(self, prog_name):
@ -110,7 +103,7 @@ class DeleteApp(command.Command):
class UpdateApp(command.ShowOne):
"""Deletes an app"""
"""Updates app"""
log = logging.getLogger(__name__ + ".UpdateApp")
def get_parser(self, prog_name):
@ -119,15 +112,14 @@ class UpdateApp(command.ShowOne):
help="App name to delete")
parser.add_argument("config", metavar="<config>",
help="Config for app to "
"create in JSON format")
"create in JSON format",
type=json.loads)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
fc = self.app.client_manager.functions
app_name = parsed_args.name
fc.apps.update(app_name)
config = parsed_args.config
app_name, config = parsed_args.name, parsed_args.config
if not config:
raise Exception("Nothing to update. "
"App config was not specified.")

View File

@ -73,7 +73,7 @@ class ShowAppRoute(command.ShowOne):
class CreateAppRoute(command.ShowOne):
"""Creates a new route"""
"""Creates a new app route"""
log = logging.getLogger(__name__ + ".CreateAppRoute")
def get_parser(self, prog_name):
@ -83,19 +83,23 @@ class CreateAppRoute(command.ShowOne):
parser.add_argument("route", metavar="<route-path>",
help="App route name to create")
parser.add_argument("type", metavar="<execution-type>",
help="App route type to create")
help="App route type to create",
choices=["async", "sync"])
parser.add_argument("image", metavar="<docker-image>",
help="Docker image to run")
parser.add_argument("--is-public", metavar="<is-public>",
help="Public/Private route to create")
parser.add_argument("--is-public",
help="Public/Private route to create",
action="store_true", default=False)
parser.add_argument("--memory", metavar="<memory>",
help="App route memory to allocate, in Mbs")
help="App route memory to allocate, in Mbs",
type=int)
parser.add_argument("--timeout", metavar="<timeout>",
help="For how log to run the function")
help="For how log to run the function",
type=int)
parser.add_argument("--max-concurrency", metavar="<max_concurrency>",
help="Cold/Hot container to use.")
help="Cold/Hot container to use.", type=int)
parser.add_argument("--config", metavar="<config>",
help="App route config")
help="App route config", type=json.loads)
return parser
def take_action(self, parsed_args):
@ -104,19 +108,12 @@ class CreateAppRoute(command.ShowOne):
# required
app, route, r_type, image = (parsed_args.app, parsed_args.route,
parsed_args.type, parsed_args.image)
#optional
# optional
is_public, memory, timeout, max_c, config = (
parsed_args.is_public, parsed_args.memory,
parsed_args.timeout, parsed_args.max_concurrency,
parsed_args.config
)
if config:
try:
config = json.loads(config)
except Exception as ex:
self.log.error("Invalid config JSON. "
"Reason: {}".format(str(ex)))
raise ex
new_route = fc.routes.create(app, r_type, route, image,
is_public=is_public, memory=memory,
@ -127,7 +124,7 @@ class CreateAppRoute(command.ShowOne):
class DeleteAppRoute(command.Command):
"""Deletes specific route"""
"""Deletes specific app route"""
log = logging.getLogger(__name__ + ".DeleteAppRoute")
def get_parser(self, prog_name):
@ -136,6 +133,7 @@ class DeleteAppRoute(command.Command):
help="Specifies which app to show")
parser.add_argument("route", metavar="<route-path>",
help="App route to look for")
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
@ -145,7 +143,7 @@ class DeleteAppRoute(command.Command):
class UpdateAppRoute(command.ShowOne):
"""Updates specific route"""
"""Updates specific app route"""
log = logging.getLogger(__name__ + ".UpdateAppRoute")
def get_parser(self, prog_name):
@ -157,41 +155,52 @@ class UpdateAppRoute(command.ShowOne):
parser.add_argument("--image", metavar="<docker-image>",
help="New Docker image")
parser.add_argument("--memory", metavar="<memory>",
help="App route memory to allocate, in Mbs")
help="App route memory to allocate, in Mbs",
type=int)
parser.add_argument("--timeout", metavar="<timeout>",
help="For how log to run the function")
parser.add_argument("--max-concurrency", metavar="<max_concurrency>",
name="max_concurrency",
help="For how log to run the function",
type=int)
parser.add_argument("--max-concurrency",
metavar="<max-concurrency>",
type=int,
help="Cold/Hot container to use.")
parser.add_argument("--type", metavar="<execution-type>",
help="App route type to updae",
choices=["async", "sync"])
parser.add_argument("--config", metavar="<config>",
help="App route config")
help="App route config", type=json.loads)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
fc = self.app.client_manager.functions
#required
# required
app, route = parsed_args.app, parsed_args.route
#optional
image, memory, max_c, config = (
# optional
image, memory, max_c, timeout, config = (
parsed_args.image, parsed_args.memory,
parsed_args.max_concurrency, parsed_args.config)
parsed_args.max_concurrency, parsed_args.timeout,
parsed_args.config)
data = {}
if image:
data.update(image=image)
if memory:
data.update(memory=memory)
if max_c:
data.update(max_concurrency=max_c)
if timeout:
data.update(timeout=timeout)
if config:
config = json.loads(config)
data.update(config=config)
updated_route = fc.routes.update(app, route, **{
"image": image,
"memory": memory,
"max_concurrency": max_c,
"config": config,
})
updated_route = fc.routes.update(app, route, **data)["route"]
keys = list(updated_route.keys())
return keys, utils.get_dict_properties(updated_route, keys)
class ExecuteAppRoute(command.ShowOne):
"""Runs execution against specific route"""
"""Runs execution against specific app route"""
log = logging.getLogger(__name__ + ".ExecuteAppRoute")
def get_parser(self, prog_name):
@ -200,16 +209,27 @@ class ExecuteAppRoute(command.ShowOne):
help="Specifies which app to show")
parser.add_argument("route", metavar="<route-path>",
help="App route to look for")
parser.add_argument("--supply-auth-properties", action='store_true',
help=("Whether to include auth properties "
"like OS_AUTH_URL and OS_TOKEN into "
"execution parameters data"))
parser.add_argument("--data", metavar="<data>",
help="Execution data")
help="Execution data", type=json.loads)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
fc = self.app.client_manager.functions
# required
app, route, data = parsed_args.app, parsed_args.route, parsed_args.data
# optional
supply_auth_properties = parsed_args.supply_auth_properties
if data:
data = json.loads(data)
result = fc.routes.execute(app, route, **data)
else:
data = {}
result = fc.routes.execute(
app, route,
supply_auth_properties=supply_auth_properties, **data)
clmns = list(result.keys())
return clmns, utils.get_dict_properties(result, clmns)

View File

@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from laosclient import client
from picassoclient import client
class Apps(object):

View File

@ -10,9 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from laosclient import client
from laosclient.v1 import apps
from laosclient.v1 import routes
from picassoclient import client
from picassoclient.v1 import apps
from picassoclient.v1 import routes
class Client(object):
@ -27,11 +27,11 @@ class Client(object):
(Default: public)
:param str region_name: The default region_name for URL discovery
:param str endpoint_override: Always use this endpoint URL for requests
for this laosclient
for this picassoclient
:param auth: An auth plugin to use instead of the session one
:type auth: keystoneauth1.plugin.BaseAuthPlugin
:param str user_agent: The User-Agent string to set
(Default is python-laosclient)
(Default is python-picassoclient)
"""
self.http_client = client.construct_http_client(*args, **kwargs)
self.apps = apps.Apps(self.http_client)

View File

@ -10,16 +10,14 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
from laosclient import client
from picassoclient import client
class Routes(object):
routes_path = "/v1/{project_id}/apps/{app}/routes"
route_path = "/v1/{project_id}/apps/{app}/routes{route_path}"
private_execution = "/v1/r/{app}{route_path}"
private_execution = "/v1/r/{project_id}/{app}{route_path}"
public_execution = "/r/{app}{route_path}"
def __init__(self, session_client: client.SessionClient):
@ -161,14 +159,14 @@ class Routes(object):
:rtype: dict
"""
route = self.show(app_name, route_path)
is_public = json.loads(route.get("is_public"))
is_public = route["route"].get("is_public")
url = (self.public_execution.format(
app=app_name, route_path=route_path) if is_public else
self.private_execution.format(
project_id=project_id, app=app_name,
route_path=route_path))
if supply_auth_properties:
data.update(OS_AUTH_URL=self.client.auth.auth_url,
data.update(OS_AUTH_URL=self.client.session.auth.auth_url,
OS_TOKEN=self.client.get_token())
response = self.client.post(url, json=data)
return response.json()

View File

@ -1,11 +1,11 @@
[metadata]
name = python-laosclient
name = python-picassoclient
summary = OpenStack Functions API Client Library
description-file =
README.rst
author = OpenStack
author-email = openstack-dev@lists.openstack.org
home-page = http://docs.openstack.org/developer/python-laosclient
home-page = http://docs.openstack.org/developer/python-picassoclient
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
@ -18,24 +18,24 @@ classifier =
[files]
packages =
laosclient
picassoclient
[entry_points]
openstack.cli.extension =
functions = laosclient.osc.plugin
functions = picassoclient.osc.plugin
openstack.functions.v1 =
fn-apps_list = laosclient.osc.v1.apps:ListApps
fn-apps_show = laosclient.osc.v1.apps:ShowApp
fn-apps_create = laosclient.osc.v1.apps:CreateApp
fn-apps_delete = laosclient.osc.v1.apps:DeleteApp
fn-apps_update = laosclient.osc.v1.apps:UpdateApp
fn-app_routes_list = laosclient.osc.v1.routes:ListAppRoutes
fn-app_routes_show = laosclient.osc.v1.routes:ShowAppRoute
fn-app_routes_create = laosclient.osc.v1.routes:CreateAppRoute
fn-app_routes_delete = laosclient.osc.v1.routes:DeleteAppRoute
fn-app_routes_update = laosclient.osc.v1.routes:UpdateAppRoute
fn-app_route_execute = laosclient.osc.v1.routes:ExecuteAppRoute
fn-apps_list = picassoclient.osc.v1.apps:ListApps
fn-apps_show = picassoclient.osc.v1.apps:ShowApp
fn-apps_create = picassoclient.osc.v1.apps:CreateApp
fn-apps_delete = picassoclient.osc.v1.apps:DeleteApp
fn-apps_update = picassoclient.osc.v1.apps:UpdateApp
fn-app_routes_list = picassoclient.osc.v1.routes:ListAppRoutes
fn-app_routes_show = picassoclient.osc.v1.routes:ShowAppRoute
fn-app_routes_create = picassoclient.osc.v1.routes:CreateAppRoute
fn-app_routes_delete = picassoclient.osc.v1.routes:DeleteAppRoute
fn-app_routes_update = picassoclient.osc.v1.routes:UpdateAppRoute
fn-app_route_execute = picassoclient.osc.v1.routes:ExecuteAppRoute
[global]
setup-hooks =

View File

@ -33,7 +33,7 @@ commands = python setup.py testr --coverage --testr-args='{posargs}'
[testenv:docs]
commands =
rm -rf doc/html doc/build
sphinx-apidoc -f -o doc/source laosclient laosclient/v1/client.py laosclient/client.py laosclient/i18n.py laosclient/osc laosclient/common
sphinx-apidoc -f -o doc/source picassoclient picassoclient/v1/client.py picassoclient/client.py picassoclient/i18n.py picassoclient/osc picassoclient/common picassoclient/tests
python setup.py build_sphinx
[flake8]
@ -41,6 +41,3 @@ ignore = E123,E126,E128,E241,E265,E713,H202,H405,H238,H404
show-source = True
exclude=.venv,.git,.tox,dist,*lib/python*,*egg,build,*venv*,doc*
max-complexity=20
[hacking]
import_exceptions = laosclient.openstack.common._i18n