Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[doc] Add documentation to the python thrift client example #3652

Merged
merged 1 commit into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions scripts/thrift/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Python client for CodeChecker
`client.py` contains simple API requests to a CodeChecker server and it
can be a starting point for writing your own script.

Before you run this example program you have to do the following steps to
setup an environment:

```sh
# Create a Python virtualenv and set it as your environment.
python3 -m venv venv
source $PWD/venv/bin/activate

# Install thrift package.
pip3 install thrift==0.13.0

# Get and install CodeChecker API packages.
#
# It will download API packages for the 'v6.19.1' but you can download newer
# versions as well.
#
# WARNING: make sure that the package versions are not newer than what
# CodeChecker server uses.
wget https://github.com/Ericsson/codechecker/raw/v6.19.1/web/api/py/codechecker_api/dist/codechecker_api.tar.gz && \
pip3 install codechecker_api.tar.gz && \
rm -rf codechecker_api.tar.gz

wget https://github.com/Ericsson/codechecker/raw/v6.19.1/web/api/py/codechecker_api_shared/dist/codechecker_api_shared.tar.gz && \
pip3 install codechecker_api_shared.tar.gz && \
rm -rf codechecker_api_shared.tar.gz
Comment on lines +23 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these packages not available from PIP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, these are available only in the repository as local python packages. This way open source contributors are also able to change the API easily and there is no need extra permissions for pypi and npmjs.

```

After your environment is ready you can run the following command:

```sh
python3 client.py \
--protocol "http" \
--host "localhost" \
--port 8001 \
--username "codechecker" \
--password "admin"
```
77 changes: 59 additions & 18 deletions scripts/thrift/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
https://github.com/Ericsson/codechecker/tree/master/web/api
"""

import argparse
import getpass
import re
import subprocess
import sys

from typing import Optional
Expand Down Expand Up @@ -51,24 +55,27 @@
sys.exit(1)


PROTOCOL = "http"
HOST = "localhost"
PORT = 8001
def get_client_api_version() -> str:
""" Get client api version from the installed codechecker package. """
p = subprocess.run([
"pip3", "show", "codechecker_api"], stdout=subprocess.PIPE)
ver = p.stdout.decode('utf-8').strip().split('\n')[1]
res = re.search('^Version:\ (.*)$', ver)
return res.group(1)

USERNAME = "<myusername>"
PASSWORD = "<mypassword>"

CLIENT_API = "6.47"
CLIENT_API = get_client_api_version()


def create_client(
args,
cls,
endpoint: str,
product_name: Optional[str] = None,
token: Optional[str] = None
):
""" Create a Thrift client. """
url = f"{PROTOCOL}://{HOST}:{PORT}/"
url = f"{args.protocol}://{args.host}:{args.port}/"
if product_name:
url += f"{product_name}/"

Expand All @@ -84,36 +91,36 @@ def create_client(
return cls.Client(protocol)


def main():
def main(args):
""" Send multiple Thrift API requests to the server. """
# Get server info.
cli_server_info = create_client(ServerInfoAPI_v6, "ServerInfo")
cli_server_info = create_client(args, ServerInfoAPI_v6, "ServerInfo")
package_version = cli_server_info.getPackageVersion()
print(f"Package version: {package_version}\n")

# Login to a running CodeChecker server.
cli_auth = create_client(AuthAPI_v6, "Authentication")
cli_auth = create_client(args, AuthAPI_v6, "Authentication")

token = None

auth_params = cli_auth.getAuthParameters()
if auth_params.requiresAuthentication:
try:
print(f"Login '{USERNAME}'...")
print(f"Login '{args.username}'...")
token = cli_auth.performLogin(
"Username:Password", f"{USERNAME}:{PASSWORD}")
print(f"'{USERNAME}' successfully logged in.\n")
"Username:Password", f"{args.username}:{args.password}")
print(f"'{args.username}' successfully logged in.\n")
except RequestFailed as ex:
print(f"Failed to login {USERNAME} with the following exception: "
f"{ex.message}")
print(f"Failed to login {args.username} with the following "
f"exception: {ex.message}")
sys.exit(1)
except Exception as ex:
print(f"Something went wrong: {ex}")
print("Make sure your server is running.")
sys.exit(1)

# Get produts from the server.
cli_product = create_client(ProductAPI_v6, "Products", None, token)
cli_product = create_client(args, ProductAPI_v6, "Products", None, token)

product_endpoint_filter = None
product_name_filter = None
Expand All @@ -127,7 +134,7 @@ def main():

# Get runs for the default product.
cli_report = create_client(
ReportAPI_v6, "CodeCheckerService", "Default", token)
args, ReportAPI_v6, "CodeCheckerService", "Default", token)

run_filter = None
limit = 0
Expand All @@ -142,5 +149,39 @@ def main():
sys.exit(1)


def __add_arguments_to_parser(parser):
""" Add arguments to the the given parser. """
parser.add_argument('--protocol',
dest="protocol",
default="http",
help="CodeChecker server protocol.")

parser.add_argument('--host',
dest="host",
default="localhost",
help="CodeChecker server host.")

parser.add_argument('--port',
dest="port",
default="8001",
help="CodeChecker server port.")

parser.add_argument('--username',
dest="username",
default=getpass.getuser(),
help="The username to authenticate with.")

parser.add_argument('--password',
dest="password",
help="Password.")

if __name__ == "__main__":
main()
parser = argparse.ArgumentParser(
prog="client",
description="""
Python client to communicate with a CodeChecker server.""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
__add_arguments_to_parser(parser)
args = parser.parse_args()

main(args)