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

feat(Quality): Add Quality Tools: Flake8 & BugBear #3

Merged
merged 3 commits into from
Jan 15, 2023
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
18 changes: 18 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[flake8]
extend-exclude = venv*,*lib,*test

max-line-length = 160
max-doc-length = 160
indent-size = 2
show_source = True
statistics = True
count = True

ignore =
D10
D204
D401
E126

require-plugins =
flake8-bugbear
31 changes: 31 additions & 0 deletions .github/workflows/quality.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2022 Expedia, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Quality Checks
on: push
jobs:
flake8-lint:
runs-on: ubuntu-latest
name: Lint
steps:
- name: Check out source repository
uses: actions/checkout@v3
- name: Set up Python environment
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install Dependencies
run: pip install -r requirements.txt
- name: flake8 Lint
uses: py-actions/flake8@v2
6 changes: 6 additions & 0 deletions QUALITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Run Quality Checks

To run the code quality checks, run the following command:
```bash
flake8
```
4 changes: 1 addition & 3 deletions generator/scripts/add-imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
# limitations under the License.


"""
Add imports to all generated models.
"""
"""Add imports to all generated models."""

import pathlib
import ast
Expand Down
1 change: 0 additions & 1 deletion openworld/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

1 change: 0 additions & 1 deletion openworld/sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

1 change: 0 additions & 1 deletion openworld/sdk/core/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

3 changes: 1 addition & 2 deletions openworld/sdk/core/client/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from typing import Any, Dict, Optional
from datetime import datetime

from openworld.sdk.core.constant import header as header_constant, body, constant
from openworld.sdk.core.constant import header as header_constant
from openworld.sdk.core.util import log as log_util
from openworld.sdk.core.constant import log as log_constant
from http import HTTPStatus
Expand Down Expand Up @@ -71,7 +71,6 @@ def call(self, method: str, url: str, obj: Any = None, request_headers: Optional
:return: response as object
:rtype: Any
"""

self.__auth_client.refresh_token()

request_headers = ApiClient.__fill_request_headers(request_headers)
Expand Down
1 change: 0 additions & 1 deletion openworld/sdk/core/client/auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ def refresh_token(self) -> None:
:return: the new token.
:rtype: requests.Response
"""

if not self.__token.is_about_expired():
return

Expand Down
1 change: 0 additions & 1 deletion openworld/sdk/core/configuration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

6 changes: 4 additions & 2 deletions openworld/sdk/core/configuration/auth_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@

from openworld.sdk.core.model.exception import client as client_exception

DEFAULT_CREDENTIALS = Credentials(key=EMPTY_STRING, secret=EMPTY_STRING)


@dataclass
class AuthConfig:
def __init__(self,
credentials: Credentials = Credentials(key=EMPTY_STRING, secret=EMPTY_STRING),
credentials: Credentials = DEFAULT_CREDENTIALS,
auth_endpoint: str = AUTH_ENDPOINT):
r"""Holds authentication config data.

Expand All @@ -40,7 +42,7 @@ def __init__(self,
def __post_init__(self):
missing = list()

for attribute in [('Key',self.__credentials.key),
for attribute in [('Key', self.__credentials.key),
('Secret', self.__credentials.secret),
('Auth_Endpoint', self.__auth_endpoint)]:

Expand Down
4 changes: 1 addition & 3 deletions openworld/sdk/core/configuration/client_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@ def __init__(self,
:param endpoint: An optional API endpoint to use for requests.
:param auth_endpoint: An optional API endpoint to use for authentication.
"""

self.__auth_config = AuthConfig(Credentials(key, secret), auth_endpoint)
self.__endpoint = endpoint

self.__post_init__()

def __post_init__(self):
if not self.__endpoint:
raise client_exception.OpenWorldConfigurationException(
message.NONE_VALUE_NOT_ALLOWED_FOR_MESSAGE_TEMPLATE.format(self.__endpoint))
raise client_exception.OpenWorldConfigurationException(message.NONE_VALUE_NOT_ALLOWED_FOR_MESSAGE_TEMPLATE.format(self.__endpoint))

@property
def auth_config(self) -> AuthConfig:
Expand Down
1 change: 0 additions & 1 deletion openworld/sdk/core/constant/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

15 changes: 6 additions & 9 deletions openworld/sdk/core/constant/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import requests

from openworld.sdk.core.constant import constant

TOKEN_RENEWAL_IN_PROCESS: str = "Renewing token"

Expand All @@ -29,11 +26,11 @@
NEW_TOKEN_EXPIRATION_TEMPLATE: str = 'New token expires in {0} seconds'

HTTP_HEADERS_LOG_MESSAGE_TEMPLATE: str = '\tHeaders: \n' \
'\t--- BEGIN ---\n' \
'{0}' \
'\t--- END ---\n'
'\t--- BEGIN ---\n' \
'{0}' \
'\t--- END ---\n'

HTTP_BODY_LOG_MESSAGE_TEMPLATE: str = '\n\tBody: \n' \
'\t--- BEGIN ---\n' \
'{0}' \
'\t--- END ---\n'
'\t--- BEGIN ---\n' \
'{0}' \
'\t--- END ---\n'
1 change: 0 additions & 1 deletion openworld/sdk/core/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

9 changes: 5 additions & 4 deletions openworld/sdk/core/model/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@dataclass
class Credentials:
"""A pair of client key and secret."""

key: str
secret: str

Expand All @@ -40,6 +41,7 @@ class Credentials:
@dataclass
class _TokenResponse:
"""A model of an API response."""

access_token: str
expires_in: int
scope: str
Expand All @@ -59,8 +61,7 @@ def __init__(self, data: Dict):
self.lock = Lock()
self.__expiration_time = datetime.datetime.now() + datetime.timedelta(seconds=self.__token.expires_in)

LOG.info(log.OPENWORLD_LOG_MESSAGE_TEMPLATE.format(
log.NEW_TOKEN_EXPIRATION_TEMPLATE.format(str(self.__token.expires_in))))
LOG.info(log.OPENWORLD_LOG_MESSAGE_TEMPLATE.format(log.NEW_TOKEN_EXPIRATION_TEMPLATE.format(str(self.__token.expires_in))))

@property
def refresh_token(self) -> str:
Expand All @@ -78,8 +79,7 @@ def is_expired(self):
return datetime.datetime.now() >= self.__expiration_time

def is_about_expired(self):
return datetime.datetime.now() + datetime.timedelta(
seconds=REFRESH_TOKEN_TIME_GAP_IN_SECONDS) >= self.__expiration_time
return datetime.datetime.now() + datetime.timedelta(seconds=REFRESH_TOKEN_TIME_GAP_IN_SECONDS) >= self.__expiration_time

def update(self, data: Dict):
self.__token = _TokenResponse.from_dict(data)
Expand All @@ -89,6 +89,7 @@ def update(self, data: Dict):
@dataclass
class HttpBearerAuth(AuthBase):
r"""Holds Bearer access token."""

__access_token: str

def __init__(self, access_token):
Expand Down
43 changes: 23 additions & 20 deletions openworld/sdk/core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@

from setuptools import setup

setup(
name='openworld-sdk-python-core',
# TODO: Version should be received from another party (say GitHub actions)
version='0.0.1-alpha.1',
packages=[
'openworld.sdk.core',
'openworld.sdk.core.configuration',
'openworld.sdk.core.client',
'openworld.sdk.core.constant',
'openworld.sdk.core.model',
'openworld.sdk.core.model.exception',
'openworld.sdk.core.util'
],
package_dir={'openworld.sdk.core': '.'},
license='Apache License, Version 2.0',
author='Expedia Group',
install_requires=['dataclasses_json', 'uri', 'requests', 'python-dateutil'],
description='The Open World SDK for Python allows Expedia Group partners to easily build Python applications that '
'leverage the Open World (TM) platform. '
)
setup(name='openworld-sdk-python-core',
# TODO: Version should be received from another party (say GitHub actions)
version='0.0.1-alpha.1',
packages=[
'openworld.sdk.core',
'openworld.sdk.core.configuration',
'openworld.sdk.core.client',
'openworld.sdk.core.constant',
'openworld.sdk.core.model',
'openworld.sdk.core.model.exception',
'openworld.sdk.core.util'
],
package_dir={'openworld.sdk.core': '.'},
license='Apache License, Version 2.0',
author='Expedia Group',
install_requires=[
'dataclasses_json',
'uri',
'requests',
'python-dateutil'
],
description='The Open World SDK for Python allows Expedia Group partners to easily build Python applications that leverage the Open World (TM) platform.'
)
1 change: 0 additions & 1 deletion openworld/sdk/core/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

2 changes: 1 addition & 1 deletion openworld/sdk/core/util/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def response_log(response: requests.Response):
if not headers_log.endswith('\n'):
headers_log += '\n'

result: str = f'\nResponse:\n' + \
result: str = '\nResponse:\n' + \
log.HTTP_HEADERS_LOG_MESSAGE_TEMPLATE.format(headers_log) + \
log.HTTP_BODY_LOG_MESSAGE_TEMPLATE.format('\t\t' + response.text + '\n')

Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ dataclasses_json
build
setuptools
virtualenv
coverage
coverage
flake8~=6.0.0
flake8-bugbear~=22.12.6
6 changes: 3 additions & 3 deletions validate_test_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

MINIMUM_REQUIRED_COVERAGE_PERCENTAGE: int = 90
FAILURE_MESSAGE_TEMPLATE: str = 'Coverage Validation Failed!\n' \
'Minimum Required Coverage Percentage: {0}%\n' \
'Current Coverage Percentage: {1}%'
'Minimum Required Coverage Percentage: {0}%\n' \
'Current Coverage Percentage: {1}%'
SUCCESS_MESSAGE_TEMPLATE: str = 'Coverage Validation Succeed!\n' \
'Current Coverage Percentage: {0}%'
'Current Coverage Percentage: {0}%'


def validate_test_coverage(report: dict):
Expand Down