Update formatter

This commit is contained in:
Jim Myers 2022-07-25 15:36:37 -04:00
parent 2b545b2f32
commit 60c105ae9d
20 changed files with 102 additions and 95 deletions

View File

@ -1,3 +1,6 @@
# Autoformatter friendly flake8 config (all formatting rules disabled)
[flake8]
extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5
max-line-length = 160
max-complexity = 15
exclude = tests/*
extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5

16
.pylintrc Normal file
View File

@ -0,0 +1,16 @@
[MASTER]
disable=
format, # Handled by Black autoformatter
E0401, # Unable to import X; import errors are highly environment dependant
C0114, # Missing module docstring
C0115, # Missing class docstring
C0116, # Missing function or method docstring
C0411, # Import order handled by isort
[MESSAGES CONTROL]
disable = C0330, C0326 # Black compatible
[flake8]
max-line-length = 160
max-complexity = 15
exclude = tests/*

View File

@ -5,7 +5,6 @@ lint:
enabled:
- actionlint@1.6.15
- black@22.6.0
- flake8@4.0.1
- git-diff-check@SYSTEM
- gitleaks@8.8.12
- isort@5.10.1

Binary file not shown.

17
python/LICENSE.txt Normal file
View File

@ -0,0 +1,17 @@
MIT License
Copyright (c) 2018 YOUR NAME
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3
python/MANIFEST.in Normal file
View File

@ -0,0 +1,3 @@
include requirements.txt
include requirements-dev.txt
include VERSION

View File

@ -30,22 +30,27 @@ build_wheel: clean
$(file >VERSION,$(NEXT_VER))
python setup.py bdist_wheel --universal
push_wheel: build_wheel
echo "building wheel"
# push_wheel: build_wheel
# echo "building wheel"
build_build_env:
docker build -f Dockerfile.build -t engine-build:latest .
# build_build_env:
# docker build -f Dockerfile.build -t engine-build:latest .
deploy_inside_docker:
make build_wheel;
make upload_wheel_to_nexus;
# deploy_inside_docker:
# make build_wheel;
# make upload_wheel_to_nexus;
deploy:
make build_build_env
docker run engine-build:latest make deploy_inside_docker
# deploy:
# make build_build_env
# docker run engine-build:latest make deploy_inside_docker
build_docker:
docker-compose build shell
shell:
docker-compose run shell bash
deploy:
make clean
python setup.py sdist
twine upload dist/* --verbose

View File

@ -1 +1 @@
0.0.1
1.0.0

4
python/setup.cfg Normal file
View File

@ -0,0 +1,4 @@
# Inside of setup.cfg
[metadata]
description-file = README.md

View File

@ -1,5 +1,4 @@
from setuptools import setup, find_packages
from setuptools import find_packages, setup
with open("./README.md", "r") as fh:
long_description = fh.read()
@ -15,7 +14,7 @@ with open("requirements.txt", "r") as fh:
setup(
install_requires=[req for req in requirements if req[:2] != "# "],
name="shroomdk",
name="flipside_shroomdk",
version=version,
author="dev@flipsidecrypto.com",
author_email="dev@flipsidecrypto.com",
@ -26,9 +25,14 @@ setup(
packages=find_packages(),
include_package_data=True,
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Development Status :: 5 - Production/Stable", # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
"Intended Audience :: Developers", # Define that your audience are developers
"License :: OSI Approved :: MIT License", # Again, pick a license
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
dependency_links=[],
python_requires=">=3.6",

View File

@ -59,14 +59,10 @@ class API(object):
status_code=result.status_code,
status_msg=result.reason,
error_msg=data.get("errors") if data else None,
data=CreateQueryJson(**data)
if data and data.get("errors") is None
else None,
data=CreateQueryJson(**data) if data and data.get("errors") is None else None,
)
def get_query_result(
self, query_id: str, page_number: int, page_size: int
) -> QueryResultResp:
def get_query_result(self, query_id: str, page_number: int, page_size: int) -> QueryResultResp:
result = self._session.get(
self.get_url(f"queries/{query_id}"),
params={"pageNumber": page_number, "pageSize": page_size},
@ -82,9 +78,7 @@ class API(object):
status_code=result.status_code,
status_msg=result.reason,
error_msg=data.get("errors") if data else None,
data=QueryResultJson(**data)
if data and data.get("errors") is None
else None,
data=QueryResultJson(**data) if data and data.get("errors") is None else None,
)
@property

View File

@ -9,7 +9,5 @@ class UserError(BaseError):
"""
def __init__(self, status_code: int, message: Union[str, None]):
self.message = (
f"user error occured with status code: {status_code}, msg: {message}"
)
self.message = f"user error occured with status code: {status_code}, msg: {message}"
super().__init__(self.message)

View File

@ -6,15 +6,9 @@ from .api_response import ApiResponse
class CreateQueryJson(BaseModel):
token: str = Field(
None, description="The server-side token of the query being executed."
)
errors: Union[Optional[str], None] = Field(
False, description="Error that occured when creating the query."
)
cached: Optional[bool] = Field(
False, description="Whether the query is cached or not."
)
token: str = Field(None, description="The server-side token of the query being executed.")
errors: Union[Optional[str], None] = Field(False, description="Error that occured when creating the query.")
cached: Optional[bool] = Field(False, description="Whether the query is cached or not.")
class CreateQueryResp(ApiResponse):

View File

@ -5,15 +5,9 @@ from pydantic import BaseModel, Field
class Query(BaseModel):
sql: str = Field(None, description="SQL query to execute")
ttl_minutes: Optional[int] = Field(
None, description="The number of minutes to cache the query results"
)
timeout_minutes: Optional[int] = Field(
None, description="The number of minutes to timeout the query"
)
retry_interval_seconds: Optional[Union[int, float]] = Field(
1, description="The number of seconds to use between retries"
)
ttl_minutes: Optional[int] = Field(None, description="The number of minutes to cache the query results")
timeout_minutes: Optional[int] = Field(None, description="The number of minutes to timeout the query")
retry_interval_seconds: Optional[Union[int, float]] = Field(1, description="The number of seconds to use between retries")
cached: Optional[bool] = Field(
None,
description="An override on the cache. A value of true will Re-Execute the query.",

View File

@ -2,15 +2,9 @@ from pydantic import BaseModel, Field
class QueryDefaults(BaseModel):
ttl_minutes: int = Field(
None, description="The number of minutes to cache the query results"
)
ttl_minutes: int = Field(None, description="The number of minutes to cache the query results")
cached: bool = Field(False, description="Whether or not to cache the query results")
timeout_minutes: int = Field(
None, description="The number of minutes to timeout the query"
)
retry_interval_seconds: float = Field(
None, description="The number of seconds to wait before retrying the query"
)
timeout_minutes: int = Field(None, description="The number of minutes to timeout the query")
retry_interval_seconds: float = Field(None, description="The number of seconds to wait before retrying the query")
page_size: int = Field(None, description="The number of results to return per page")
page_number: int = Field(None, description="The page number to return")

View File

@ -7,21 +7,13 @@ from .query_run_stats import QueryRunStats
class QueryResultSet(BaseModel):
query_id: Union[str, None] = Field(None, description="The server id of the query")
status: str = Field(
False, description="The status of the query (`PENDING`, `FINISHED`, `ERROR`)"
)
columns: Union[List[str], None] = Field(
None, description="The names of the columns in the result set"
)
column_types: Union[List[str], None] = Field(
None, description="The type of the columns in the result set"
)
status: str = Field(False, description="The status of the query (`PENDING`, `FINISHED`, `ERROR`)")
columns: Union[List[str], None] = Field(None, description="The names of the columns in the result set")
column_types: Union[List[str], None] = Field(None, description="The type of the columns in the result set")
rows: Union[List[Any], None] = Field(None, description="The results of the query")
run_stats: Union[QueryRunStats, None] = Field(
None,
description="Summary stats on the query run (i.e. the number of rows returned, the elapsed time, etc)",
)
records: Union[List[Any], None] = Field(
None, description="The results of the query transformed as an array of objects"
)
records: Union[List[Any], None] = Field(None, description="The results of the query transformed as an array of objects")
error: Any

View File

@ -10,6 +10,4 @@ class QueryRunStats(BaseModel):
None,
description="The number of seconds elapsed between the start and end times.",
)
record_count: int = Field(
None, description="The number of records returned by the query."
)
record_count: int = Field(None, description="The number of records returned by the query.")

View File

@ -103,9 +103,7 @@ def test_get_query_result_server_errors(requests_mock):
query_id = "test_query_id"
# User Error
requests_mock.get(
api.get_url(f"queries/{query_id}"), status_code=400, reason="user_error"
)
requests_mock.get(api.get_url(f"queries/{query_id}"), status_code=400, reason="user_error")
try:
qi._get_query_results("test_query_id")
@ -113,9 +111,7 @@ def test_get_query_result_server_errors(requests_mock):
assert type(e) == UserError
# Server Error
requests_mock.get(
api.get_url(f"queries/{query_id}"), status_code=500, reason="server error"
)
requests_mock.get(api.get_url(f"queries/{query_id}"), status_code=500, reason="server error")
try:
qi._get_query_results("test_query_id")

View File

@ -47,9 +47,7 @@ def test_create_query_user_error(requests_mock):
def test_create_query_server_error(requests_mock):
api = API("https://api.flipsidecrypto.xyz", "api_key")
result = requests_mock.post(
api.get_url("queries"), status_code=500, reason="Server Error"
)
result = requests_mock.post(api.get_url("queries"), status_code=500, reason="Server Error")
q = Query(sql="SELECT * FROM mytable", ttl_minutes=5) # type: ignore
@ -133,9 +131,7 @@ def test_get_query_result_server_error(requests_mock):
page_number = 1
page_size = 10
result = requests_mock.get(
api.get_url(f"queries/{query_id}"), status_code=500, reason="Server Error"
)
result = requests_mock.get(api.get_url(f"queries/{query_id}"), status_code=500, reason="Server Error")
result = api.get_query_result(query_id, page_number, page_size)
assert result.data is None

View File

@ -1,5 +1,6 @@
import time
from typing import Union
from shroomdk.models.sleep_config import SleepConfig
@ -12,24 +13,24 @@ def get_exp_backoff_seconds(attempts: Union[int, float]):
def get_linear_backoff_seconds(attempts: Union[int, float], interval_seconds: Union[int, float]):
return (attempts +1) * interval_seconds
return (attempts + 1) * interval_seconds
def get_elapsed_exp_seconds(config: SleepConfig):
if (not config.interval_seconds):
if not config.interval_seconds:
raise Exception("intervalSeconds is required for `get_elapsed_exp_seconds`")
elapsed_seconds = 0
for i in range(config.attempts):
elapsed_seconds += get_exp_backoff_seconds(i)
return elapsed_seconds
def exp_backoff(config: SleepConfig):
if (not config.interval_seconds):
if not config.interval_seconds:
raise Exception("intervalSeconds is required for `exp_backoff`")
elapsed_seconds = get_elapsed_exp_seconds(config)
should_continue = True
if elapsed_seconds / 60 > config.timeout_minutes:
@ -37,12 +38,12 @@ def exp_backoff(config: SleepConfig):
return should_continue
time.sleep(get_exp_backoff_seconds(config.attempts * config.interval_seconds))
return should_continue
def get_elapsed_linear_seconds(config: SleepConfig):
if (not config.interval_seconds):
if not config.interval_seconds:
raise Exception("intervalSeconds is required for `get_elapsed_linear_seconds`")
elapsed_seconds = 0
@ -52,8 +53,8 @@ def get_elapsed_linear_seconds(config: SleepConfig):
return elapsed_seconds
def linear_backoff(config: SleepConfig):
if (not config.interval_seconds):
def linear_backoff(config: SleepConfig):
if not config.interval_seconds:
raise Exception("intervalSeconds is required for `linear_backoff`")
elapsed_seconds = get_elapsed_linear_seconds(config)
@ -62,7 +63,6 @@ def linear_backoff(config: SleepConfig):
should_continue = False
return should_continue
# print("sleeping for {} seconds".format(get_linear_backoff_seconds(config.attempts, config.interval_seconds)))
time.sleep(get_linear_backoff_seconds(config.attempts, config.interval_seconds))
return should_continue