Skip to content

Commit

Permalink
ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
drf7 committed Jan 3, 2025
1 parent d3ff586 commit 1825816
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 143 deletions.
121 changes: 8 additions & 113 deletions nuclia_e2e/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,119 +76,14 @@ lint.ignore = [
"ISC002", # multi-line-implicit-string-concatenation ()

# TODO: Remove these rules from ignore list after fixing them
"PGH004", # Use specific rule codes when using `noqa`
"PT003", # scope=function is implied in `@pytest.fixture()`
"B006", # Do not use mutable data structures for argument defaults"
"BLE001", # Do not catch blind exception: `Exception`
"TRY003", # Avoid specifying long messages outside the exception class
"TRY002", # Create your own exception
"EM102", # Exception must not use an f-string literal, assign to variable first
"PTH", # Ignore path library recommendations
"ERA001", # Found commented-out code
"S113", # Probable use of requests call without timeout
"PLR2004", # Magic value used in comparison, ...
"PLR0913", # Too many arguments ignored
"PLR0915", # Too many statements ignored
"N818", # Exception name
"SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements
"FBT001", # Boolean-typed positional argument in function definition"
"FBT002", # Boolean-typed positional argument in function definition"
"PLW0603", # Using the global statement to update `X` is discouraged
"E721", # Do not compare types, use `isinstance()`
"E501", # Line too long
"PLR0912", # Too many branches
"C901", # Code is too complex
"PGH003", # Use specific rule codes when ignoring type issues
"B904", # exceptions things
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"N805", # First argument of a method should be named `self`
"N802", # Function name `Chat` should be lowercase
"N803", # Argument name `backupCount` should be lowercase
"SLF001", # Private member accessed
"PYI036",
"N801", # Class name `X` should use CapWords convention
"N816", # Variable `X` in global scope should not be mixedCase
"G004", # Logging statement uses f-string
"UP006", # Use `dict` instead of `Dict` for type annotation
"UP035", # `typing.List` is deprecated, use `list` instead
"SIM401", # Use `x.get("y", z)` instead of an `if` block
"PT023", # Use `@pytest.mark.asyncio()` over `@pytest.mark.asyncio`
"F541", # f-string without any placeholders
"PT022", # No teardown in fixture `nats_consumer_factory`, use `return` instead of `yield`
"INP001", # add __init__.py
"RET505", # Unnecessary `else` after `return` statement
"TC002", # Move third-party import `X` into a type-checking block
"SIM115", # Use context handler for opening files
"C408", # Unnecessary `dict` call (rewrite as a literal)
"PT024", # `pytest.mark.asyncio` is unnecessary for fixtures
"C417", # Unnecessary `map` usage
"S104", # Possible binding to all interfaces
"UP026", # `mock` is deprecated, use `unittest.mock`
"UP031", # Use format specifiers instead of percent format
"TRY201", # Use `raise` without specifying exception name
"TRY203", # Remove exception handler; error is immediately re-raised
"B011", # Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
"PT015", # Assertion always fails, replace with `pytest.fail()`
"E722", # Do not use bare `except`
"SIM300", # Yoda conditions are discouraged, use `data2 == "a response"` instead
"UP032", # Use f-string instead of `format` call
"SIM118", # Use `key not in dict` instead of `key not in dict.keys()`
"PT001", # Use `@pytest.fixture()` over `@pytest.fixture`
"TRY300", # Consider moving this statement to an `else` block
"SIM102", # Use a single `if` statement instead of nested `if` statements
"UP004", # Class `Gnatsd` inherits from `object`
"EM101", # Exception must not use a string literal, assign to variable first
"RUF010", # Use explicit conversion flag
"RSE102", # Unnecessary parentheses on raised exception
"RUF100", # Unused blanket `noqa` directive
"S324", # Probable use of insecure hash functions in `hashlib`: `md5`
"RUF013", # PEP 484 prohibits implicit `Optional`
"SIM108", # Use ternary operator `bucket = self.bucket if self.field is None else self.field.bucket_name` instead of `if`-`else`-block
"S101", # Use of `assert` detected
"RET504", # Unnecessary assignment to `deleted` before `return` statement
"RET506", # Unnecessary `else` after `raise` statement
"TC003", # Move standard library import `concurrent.futures.ThreadPoolExecutor` into a type-checking block
"UP009", # UTF-8 encoding declaration is unnecessary
"S110", # `try`-`except`-`pass` detected, consider logging the exception
"RET503", # Missing explicit `return` at the end of function able to return non-`None` value
"PLW2901", # `for` loop variable `value` overwritten by assignment target
"TID252", # Prefer absolute imports over relative imports
"PLC0414", # Import alias does not rename original package
"S301", # `pickle` and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue
"F841", # Local variable `info_account_user_id` is assigned to but never used
"T201", #`print` found
"UP007", # Use `X | Y` for type annotations
"PLR1714", # Consider merging multiple comparisons
"B007", # Loop control variable `idx` not used within loop body
"SIM110", # Use `return any(scope in conn.auth.scopes for scope in scopes)` instead of `for` loop
"W291", # Trailing whitespace
"SIM113", # Use `enumerate()` for index variable `count` in `for` loop
"RET502", # Do not implicitly `return None` in function able to return non-`None` value
"UP030", # Use implicit references for positional format fields
"RUF015", # Prefer `next(iter(mock_aiohttp.requests.values()))` over single element slice
"SIM114", # Combine `if` branches using logical `or` operator
"PT018", # Assertion should be broken down into multiple parts
"RUF005", # Consider `[key, *values, str(int(time.time() // ttl))]` instead of concatenation
"UP039", # Unnecessary parentheses after class definition
"C416", # Unnecessary `list` comprehension (rewrite using `list()`)
"S105", # Possible hardcoded password assigned to: "TOKEN"
"PLR0911", # Too many return statements (7 > 6)
"B009", # Do not call `getattr` with a constant attribute value.
"PT017", # Found assertion on exception `r` in `except` block, use `pytest.raises()` instead
"TC001", # Move application import `stashify_idp.authorizer.db.IDPRegionalDatabaseUtility` into a type-checking block
"C401", # Unnecessary generator (rewrite as a `set` comprehension)
"UP015", # Unnecessary open mode parameters
"B023", # Function definition does not bind loop variable `assets`
"C403", # Unnecessary `list` comprehension (rewrite as a `set` comprehension)
"C419", # Unnecessary list comprehension
"PLR0402", # [*] Use `from nuclia_accounting import tables` in lieu of alias
"RUF002", # Docstring contains ambiguous `’` (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?
"N806", # Variable `rolloverAt` in function should be lowercase
"PLR0402", # [*] Use `from nuclia_external_auth import oauth` in lieu of alias
"B026", # Star-arg unpacking after a keyword argument is strongly discouraged
"PLR1711", # Useless `return` statement at end of function
"SIM910", # Use `dict.get()` without default value
"F601", # Dictionary key literal `"resources_processed"` repeated
"ERA001",
"PLR2004",
"T201",
"BLE001",
"PT004",
"RET504",
"SIM102",
"B007",
]

exclude = [
Expand Down
26 changes: 11 additions & 15 deletions nuclia_e2e/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from nuclia.data import get_auth
from nuclia.data import get_config
from nuclia.sdk.kbs import NucliaKBS
from nuclia_e2e.tests.data import TEST_ACCOUNT_SLUG

import aiohttp
import asyncio
Expand All @@ -19,12 +20,10 @@
import string
import tempfile

from .data import TEST_ACCOUNT_SLUG

TEST_ENV = os.environ.get("TEST_ENV")

# All tests that needs some existing account will use the one configured in the global "permanent_account_slug"
# with some predefined user credentials without expiration:
# All tests that needs some existing account will use the one configured in
# the global "permanent_account_slug" with some predefined user credentials without expiration:
# "permanent_account_owner_pat": PAT token for `[email protected]` on the suitable account

CLUSTERS_CONFIG = {
Expand Down Expand Up @@ -136,7 +135,8 @@ async def send_onboard_inquiry(self, data):

async def create_account(self, slug):
if not self.access_token:
raise ValueError("Access token is not set. Please provide an access token.")
msg = "Access token is not set. Please provide an access token."
raise ValueError(msg)
url = f"{self.base_url}/api/v1/accounts"
async with self.session.post(
url, json={"slug": slug, "title": slug}, headers=self.auth_headers
Expand Down Expand Up @@ -168,7 +168,7 @@ def global_api(aiohttp_session):
)


@pytest.fixture(scope="function")
@pytest.fixture()
def global_api_config():
global_config = CLUSTERS_CONFIG[TEST_ENV]["global"]
nuclia.BASE = global_config["base_url"]
Expand All @@ -182,7 +182,6 @@ def global_api_config():


@pytest.fixture(
scope="function",
params=[pytest.param(zone, id=zone["name"]) for zone in CLUSTERS_CONFIG[TEST_ENV]["zones"]],
)
def regional_api_config(request, global_api_config):
Expand All @@ -194,7 +193,7 @@ def regional_api_config(request, global_api_config):
config.set_default_account(global_api_config["permanent_account_slug"])
config.set_default_zone(zone_config["zone_slug"])
zone_config["test_kb_slug"] = "{test_kb_slug}-{name}".format(**zone_config)
yield zone_config
return zone_config


class EmailUtil:
Expand Down Expand Up @@ -261,7 +260,7 @@ async def get_last_email_body(self, test_address):
async def wait_for_email_signup_link(self, email_address, max_wait_time=20):
print(f"waiting 10 seconds for signup email at {email_address}")
signup_url = None
for i in range(max_wait_time):
for _ in range(max_wait_time):
print("still waiting...")
await asyncio.sleep(1)
body = await self.get_last_email_body(email_address)
Expand All @@ -276,11 +275,10 @@ async def wait_for_email_signup_link(self, email_address, max_wait_time=20):

@pytest.fixture(scope="session")
def email_util():
util = EmailUtil("[email protected]", "oynpctapnzwqjxol")
return util
return EmailUtil("[email protected]", "oynpctapnzwqjxol")


@pytest.fixture(scope="function")
@pytest.fixture()
async def cleanup_test_account(global_api: GlobalAPI):
await global_api.manager.delete_account(TEST_ACCOUNT_SLUG)

Expand All @@ -289,13 +287,11 @@ async def cleanup_test_account(global_api: GlobalAPI):
await global_api.manager.delete_account(TEST_ACCOUNT_SLUG)


@pytest.fixture(scope="function")
@pytest.fixture()
async def clean_kb_test(request, regional_api_config):
kbs = NucliaKBS()
try:
await asyncio.to_thread(partial(kbs.delete, slug=regional_api_config["test_kb_slug"]))
except ValueError:
# Raised by sdk when kb not found
pass

yield
21 changes: 11 additions & 10 deletions nuclia_e2e/tests/test_kb.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from collections.abc import Coroutine
from datetime import datetime
from datetime import timedelta
from datetime import timezone
Expand All @@ -23,7 +24,6 @@
from pathlib import Path
from time import monotonic
from typing import Any
from typing import Coroutine

import asyncio
import backoff
Expand Down Expand Up @@ -189,7 +189,8 @@ async def condition() -> tuple[bool, Any]:
continue
for fc in res.computedmetadata.field_classifications:
if fc.field.field_type.name == "GENERIC":
# in case only generic fields are found, result won't be ever trur and condition will fail.
# in case only generic fields are found,
# result won't be ever true and condition will fail.
continue

# heuristic, but [email protected] enough for now,
Expand Down Expand Up @@ -310,13 +311,13 @@ async def condition() -> tuple[bool, Any]:
partial(
kb.logs.query,
type=EventType.CHAT,
query=ActivityLogsChatQuery(year_month="{dt.year}-{dt.month}".format(dt=now), filters={}),
query=ActivityLogsChatQuery(year_month=f"{now.year}-{now.month}", filters={}),
)
)
if len(logs.data) >= 2:
# as the asks may be retried more than once (because some times rephrase doesn't always work)
# we need to check the last logs. The way the tests are setup if we reach here is because we validated
# that we got the expected results on ask, so the log should match this reasoning.
# we need to check the last logs. The way the tests are setup if we reach here is because we
# validated that we got the expected results on ask, so the log should match this reasoning.
if logs.data[-2].question == "why cocoa prices high?" and logs.data[-1].question == "when?":
return (True, logs)
return (False, None)
Expand All @@ -331,7 +332,7 @@ async def condition() -> tuple[bool, Any]:
partial(
kb.logs.query,
type=EventType.SEARCH,
query=ActivityLogsSearchQuery(year_month="{dt.year}-{dt.month}".format(dt=now), filters={}),
query=ActivityLogsSearchQuery(year_month=f"{now.year}-{now.month}", filters={}),
)
)
assert logs.data[-1].question == "why cocoa prices high?"
Expand All @@ -346,7 +347,7 @@ async def run_test_kb_deletion(regional_api_config):
assert kbid is None


@pytest.mark.asyncio_cooperative
@pytest.mark.asyncio_cooperative()
async def test_kb(regional_api_config, clean_kb_test):
"""
Test a chain of operations that simulates a normal use of a knowledgebox, just concentrated
Expand Down Expand Up @@ -375,9 +376,9 @@ async def test_kb(regional_api_config, clean_kb_test):
# Upload a new resource and validate that is correctly processed and stored in nuclia
(await run_test_upload_and_process(regional_api_config),)

# Wait for both labeller task results to be consolidated in nucliadb while we also run semantic search
# and a generative question. This /find and /ask requests are crafted so they trigger all the existing calls
# to predict features
# Wait for both labeller task results to be consolidated in nucliadb while we also run semantic search
# and a generative question. This /find and /ask requests are crafted so they trigger
# all the existing calls to predict features
await asyncio.gather(
run_test_check_da_labeller_output(regional_api_config),
run_test_find(regional_api_config),
Expand Down
10 changes: 5 additions & 5 deletions nuclia_e2e/tests/test_onboarding.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from nuclia_e2e.tests.data import TEST_ACCOUNT_SLUG
from nuclia_e2e.tests.data import TEST_ONBOARD_INQUIRY

import pytest
from .data import TEST_ONBOARD_INQUIRY, TEST_ACCOUNT_SLUG


@pytest.mark.asyncio_cooperative
async def test_onboarding(
request, global_api, email_util, cleanup_test_account, aiohttp_session
):
@pytest.mark.asyncio_cooperative()
async def test_onboarding(request, global_api, email_util, cleanup_test_account, aiohttp_session):
# Request signup using a random alias email
test_alias_email = email_util.generate_email_address()
test_password = "notarealpassword"
Expand Down

0 comments on commit 1825816

Please sign in to comment.