Skip to content

Commit

Permalink
[chore] Bump libs, use mypy, remove safety (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
aquamatthias authored Jan 15, 2024
1 parent 305a18d commit 748c91d
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 572 deletions.
3 changes: 3 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[mypy]
ignore_missing_imports = True
warn_return_any = False
16 changes: 4 additions & 12 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,16 @@
package = "resotoclient"
python_version = "3.9"
nox.needs_version = ">= 2021.6.6"
nox.options.sessions = ("safety", "pyright", "pytest")
nox.options.sessions = ("mypy", "pytest")


@session(python=python_version)
def safety(session: Session) -> None:
"""Scan dependencies for insecure packages."""
requirements = session.poetry.export_requirements()
session.install("safety")
session.run("safety", "check", "--full-report", f"--file={requirements}")


@session(python=python_version)
def pyright(session: Session) -> None:
def mypy(session: Session) -> None:
"""Type-check using mypy."""
args = session.posargs or ["resotoclient", "tests"]
session.install(".[extras]")
session.install("pyright", "pytest", "networkx")
session.run("pyright", *args)
session.install("mypy", "pytest", "networkx")
session.run("mypy", "--strict", "resotoclient", "tests")


@session(python=python_version)
Expand Down
929 changes: 459 additions & 470 deletions poetry.lock

Large diffs are not rendered by default.

33 changes: 16 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "resotoclient"
version = "1.6.1"
version = "1.6.2"
description = "Resoto Python client library"
authors = ["Some Engineering Inc."]
license = "Apache-2.0"
Expand Down Expand Up @@ -35,33 +35,32 @@ Changelog = "https://github.com/someengineering/resotoclient-python/releases"

[tool.poetry.dependencies]
python = "^3.9"
jsons="^1.6.1"
PyJWT="^2.3.0"
jsons=">=1.6.1"
PyJWT=">=2.3.0"
cryptography=">=36.0.2"
pandas = { version = "^1.4.2", optional = true }
graphviz = { version = "^0.20", optional = true }
aiohttp = "^3.8.1"
pandas = { version = ">=1.4.2", optional = true }
graphviz = { version = ">=0.20", optional = true }
aiohttp = ">=3.8.1"
certifi = ">=2017.4.17"


[tool.poetry.extras]
extras = ["pandas", "graphviz"]

[tool.poetry.dev-dependencies]
pytest = "^7.3.1"
safety = "^2.3.5"
pyright = "^1.1.304"
flake8 = "^6.0.0"
pytest = ">=7.3.1"
safety = ">=2.3.5"
pyright = ">=1.1.304"
flake8 = ">=6.0.0"
black = ">=22.12.0"
flake8-bandit = "^4.1.1"
flake8-bugbear = "^23.3.23"
pep8-naming = "^0.13.3"
networkx = "^2.8"
six = "^1.16.0"
urllib3 = "^1.26.15" # poetry itself stopped working with latest urllib3
flake8-bandit = ">=4.1.1"
flake8-bugbear = ">=23.3.23"
pep8-naming = ">=0.13.3"
networkx = ">=2.8"
six = ">=1.16.0"

[tool.poetry.group.dev.dependencies]
pytest-asyncio = "^0.19.0"
pytest-asyncio = ">=0.19.0"

[tool.pyright]
include = ["resotoclient", "tests"]
Expand Down
30 changes: 16 additions & 14 deletions resotoclient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
from attrs import define

try:
from pandas import DataFrame # type: ignore
import pandas as pd # type: ignore
from pandas import DataFrame
import pandas as pd
except ImportError:
DataFrame = None
try:
from graphviz import Digraph # type: ignore
from graphviz import Digraph
except ImportError:
Digraph = None

Expand Down Expand Up @@ -130,7 +130,7 @@ def __init__(
self.state_lock = threading.Lock()
self.client_state = ClientState.INITIALIZED

self.async_client = None
self.async_client: Optional[AsyncResotoClient] = None

def __enter__(self) -> "ResotoClient":
self.start()
Expand Down Expand Up @@ -389,7 +389,9 @@ def ping(self) -> str:
def ready(self) -> str:
return self._await(lambda c: c.ready())

def dataframe(self, search: str, section: Optional[str] = "reported", graph: str = "resoto", flatten: bool = True) -> DataFrame: # type: ignore
def dataframe(
self, search: str, section: Optional[str] = "reported", graph: str = "resoto", flatten: bool = True
) -> DataFrame:
if DataFrame is None:
raise ImportError("Python package resotoclient[extras] is not installed")
aggregate_search = False
Expand Down Expand Up @@ -453,24 +455,24 @@ def extract_node(node: JsObject) -> Optional[JsObject]:
return node_data

nodes = [extract_node(node) for node in iter]
return pd.json_normalize(nodes) # type: ignore
return pd.json_normalize(nodes)

def graphviz( # type: ignore
def graphviz(
self,
search: str,
section: Optional[str] = "reported",
graph: str = "resoto",
engine: str = "sfdp",
format: str = "svg",
) -> Digraph: # type: ignore
) -> Digraph:
if Digraph is None:
raise ImportError("Python package resotoclient[extras] is not installed")

digraph = Digraph(comment=search) # type: ignore
digraph = Digraph(comment=search)
digraph.format = format
digraph.engine = engine
digraph.graph_attr = {"rankdir": "LR", "splines": "true", "overlap": "false"} # type: ignore
digraph.node_attr = { # type: ignore
digraph.graph_attr = {"rankdir": "LR", "splines": "true", "overlap": "false"}
digraph.node_attr = {
"shape": "plain",
"colorscheme": "paired12",
}
Expand All @@ -490,16 +492,16 @@ def graphviz( # type: ignore
kind=parse_kind(kind),
kind_name=kind,
)
digraph.node( # type: ignore
digraph.node(
name=js_get(elem, ["id"]),
# label=rd.name,
label=render_resource(rd, color),
shape="plain",
)
elif elem.get("type") == "edge":
digraph.edge(js_get(elem, ["from"]), js_get(elem, ["to"])) # type: ignore
digraph.edge(js_get(elem, ["from"]), js_get(elem, ["to"]))

return digraph # type: ignore
return digraph


def rnd_str(str_len: int = 10) -> str:
Expand Down
32 changes: 17 additions & 15 deletions resotoclient/async_client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json
import logging

from resotoclient.http_client import HttpResponse
from resotoclient.jwt_utils import encode_jwt_to_headers
from typing import (
Any,
Expand Down Expand Up @@ -27,7 +29,7 @@
Model,
Kind,
)
from resotoclient.http_client.aiohttp_client import AioHttpClient, HttpResponse, PoisonPill
from resotoclient.http_client.aiohttp_client import AioHttpClient, PoisonPill
import random
import string
from datetime import timedelta
Expand Down Expand Up @@ -173,7 +175,7 @@ async def get_graph(self, name: str) -> Optional[JsObject]:
async def create_graph(self, name: str) -> JsObject:
response = await self._post(f"/graph/{name}")
# root node
return await response.json()
return await response.json() # type: ignore

async def delete_graph(self, name: str, truncate: bool = False) -> str:
props = {"truncate": "true"} if truncate else {}
Expand All @@ -187,7 +189,7 @@ async def create_node(self, parent_node_id: str, node_id: str, node: JsObject, g
json=node,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -204,14 +206,14 @@ async def patch_node(
json=node,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

async def get_node(self, node_id: str, graph: str = "resoto") -> JsObject:
response = await self._get(f"/graph/{graph}/node/{node_id}")
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -228,7 +230,7 @@ async def patch_nodes(self, nodes: List[JsObject], graph: str = "resoto") -> Lis
json=nodes,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand Down Expand Up @@ -264,7 +266,7 @@ async def list_batches(self, graph: str = "resoto") -> List[JsObject]:
f"/graph/{graph}/batch",
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand Down Expand Up @@ -292,7 +294,7 @@ async def search_graph_raw(self, search: str, graph: str = "resoto") -> JsObject
data=search,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -309,7 +311,7 @@ async def search_graph_explain(self, search: str, graph: str = "resoto") -> Esti
async def search_list(
self, search: str, section: Optional[str] = "reported", graph: str = "resoto"
) -> AsyncIterator[JsObject]:
params = {}
params: Dict[str, str] = {}
if section:
params["section"] = section

Expand All @@ -323,7 +325,7 @@ async def search_list(
async def search_graph(
self, search: str, section: Optional[str] = "reported", graph: str = "resoto"
) -> AsyncIterator[JsObject]:
params = {}
params: Dict[str, str] = {}
if section:
params["section"] = section
response = await self._post(f"/graph/{graph}/search/graph", params=params, data=search, stream=True)
Expand All @@ -336,7 +338,7 @@ async def search_graph(
async def search_aggregate(
self, search: str, section: Optional[str] = "reported", graph: str = "resoto"
) -> AsyncIterator[JsObject]:
params = {}
params: Dict[str, str] = {}
if section:
params["section"] = section
response = await self._post(f"/graph/{graph}/search/aggregate", params=params, data=search, stream=True)
Expand Down Expand Up @@ -521,7 +523,7 @@ async def cli_execute(
async def cli_info(self) -> JsObject:
response = await self._get("/cli/info")
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -538,7 +540,7 @@ async def config(self, config_id: str) -> JsObject:
f"/config/{config_id}",
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -550,7 +552,7 @@ async def put_config(self, config_id: str, json: JsObject, validate: bool = True
params=params,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand All @@ -560,7 +562,7 @@ async def patch_config(self, config_id: str, json: JsObject) -> JsObject:
json=json,
)
if response.status_code == 200:
return await response.json()
return await response.json() # type: ignore
else:
raise AttributeError(await response.text())

Expand Down
6 changes: 3 additions & 3 deletions resotoclient/ca.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def ca_bundle(
f.write(f"# Issuer: {cert.issuer.rfc4514_string()}\n")
f.write(f"# Subject: {cert.subject.rfc4514_string()}\n")
label = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value
f.write(f"# Label: {label}\n")
f.write(f"# Label: {label}\n") # type: ignore
f.write(f"# Serial: {cert.serial_number}\n")
md5 = cert_fingerprint(cert, "MD5")
sha1 = cert_fingerprint(cert, "SHA1")
Expand Down Expand Up @@ -119,9 +119,9 @@ def __init__(
) -> None:
self.resotocore_url = resotocore_url
self.psk = psk
self.__ca_cert = None
self.__ca_cert: Optional[Certificate] = None
self.__custom_ca_cert_path = custom_ca_cert_path
self.__ssl_context = None
self.__ssl_context: Optional[SSLContext] = None
self.__renew_before = renew_before
self.__watcher = Thread(
target=self.__certificates_watcher, name="certificates_watcher", daemon=True
Expand Down
Loading

0 comments on commit 748c91d

Please sign in to comment.