aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generalresearch/config.py2
-rw-r--r--generalresearch/grliq/managers/forensic_data.py10
-rw-r--r--generalresearch/grliq/models/forensic_data.py8
-rw-r--r--generalresearch/managers/base.py8
-rw-r--r--generalresearch/managers/cint/profiling.py5
-rw-r--r--generalresearch/managers/criteria.py5
-rw-r--r--generalresearch/managers/dynata/profiling.py5
-rw-r--r--generalresearch/managers/events.py10
-rw-r--r--generalresearch/managers/gr/authentication.py10
-rw-r--r--generalresearch/managers/gr/business.py24
-rw-r--r--generalresearch/managers/gr/team.py11
-rw-r--r--generalresearch/managers/innovate/profiling.py5
-rw-r--r--generalresearch/managers/leaderboard/tasks.py5
-rw-r--r--generalresearch/managers/lucid/profiling.py8
-rw-r--r--generalresearch/managers/marketplace/user_pid.py5
-rw-r--r--generalresearch/managers/morning/profiling.py5
-rw-r--r--generalresearch/managers/network/label.py11
-rw-r--r--generalresearch/managers/network/mtr.py6
-rw-r--r--generalresearch/managers/network/nmap.py6
-rw-r--r--generalresearch/managers/network/rdns.py6
-rw-r--r--generalresearch/managers/network/tool_run.py10
-rw-r--r--generalresearch/managers/pollfish/profiling.py5
-rw-r--r--generalresearch/managers/precision/profiling.py5
-rw-r--r--generalresearch/managers/prodege/profiling.py5
-rw-r--r--generalresearch/managers/repdata/profiling.py5
-rw-r--r--generalresearch/managers/repdata/survey.py5
-rw-r--r--generalresearch/managers/sago/profiling.py5
-rw-r--r--generalresearch/managers/spectrum/profiling.py5
-rw-r--r--generalresearch/managers/survey.py5
-rw-r--r--generalresearch/managers/thl/buyer.py7
-rw-r--r--generalresearch/managers/thl/cashout_method.py12
-rw-r--r--generalresearch/managers/thl/category.py10
-rw-r--r--generalresearch/managers/thl/contest_manager.py28
-rw-r--r--generalresearch/managers/thl/ipinfo.py13
-rw-r--r--generalresearch/managers/thl/ledger_manager/conditions.py17
-rw-r--r--generalresearch/managers/thl/ledger_manager/ledger.py13
-rw-r--r--generalresearch/managers/thl/ledger_manager/thl_ledger.py33
-rw-r--r--generalresearch/managers/thl/payout.py20
-rw-r--r--generalresearch/managers/thl/product.py13
-rw-r--r--generalresearch/managers/thl/profiling/uqa.py5
-rw-r--r--generalresearch/managers/thl/profiling/user_upk.py12
-rw-r--r--generalresearch/managers/thl/session.py29
-rw-r--r--generalresearch/managers/thl/survey.py8
-rw-r--r--generalresearch/managers/thl/survey_penalty.py23
-rw-r--r--generalresearch/managers/thl/task_adjustment.py11
-rw-r--r--generalresearch/managers/thl/user_compensate.py12
-rw-r--r--generalresearch/managers/thl/user_manager/__init__.py5
-rw-r--r--generalresearch/managers/thl/user_manager/mysql_user_manager.py7
-rw-r--r--generalresearch/managers/thl/user_manager/rate_limit.py5
-rw-r--r--generalresearch/managers/thl/user_manager/user_manager.py7
-rw-r--r--generalresearch/managers/thl/userhealth.py13
-rw-r--r--generalresearch/managers/thl/wall.py21
-rw-r--r--generalresearch/managers/thl/wallet/__init__.py36
-rw-r--r--generalresearch/managers/thl/wallet/approve.py18
-rw-r--r--generalresearch/managers/thl/wallet/tango.py21
-rw-r--r--generalresearch/models/admin/request.py5
-rw-r--r--generalresearch/models/cint/question.py4
-rw-r--r--generalresearch/models/cint/survey.py16
-rw-r--r--generalresearch/models/cint/task_collection.py6
-rw-r--r--generalresearch/models/dynata/question.py6
-rw-r--r--generalresearch/models/dynata/survey.py21
-rw-r--r--generalresearch/models/dynata/task_collection.py6
-rw-r--r--generalresearch/models/events.py27
-rw-r--r--generalresearch/models/gr/authentication.py6
-rw-r--r--generalresearch/models/gr/business.py53
-rw-r--r--generalresearch/models/gr/team.py67
-rw-r--r--generalresearch/models/innovate/question.py2
-rw-r--r--generalresearch/models/innovate/survey.py21
-rw-r--r--generalresearch/models/innovate/task_collection.py6
-rw-r--r--generalresearch/models/legacy/bucket.py14
-rw-r--r--generalresearch/models/legacy/offerwall.py38
-rw-r--r--generalresearch/models/legacy/questions.py12
-rw-r--r--generalresearch/models/lucid/question.py2
-rw-r--r--generalresearch/models/lucid/survey.py18
-rw-r--r--generalresearch/models/morning/question.py6
-rw-r--r--generalresearch/models/morning/survey.py26
-rw-r--r--generalresearch/models/morning/task_collection.py6
-rw-r--r--generalresearch/models/network/label.py9
-rw-r--r--generalresearch/models/network/mtr/command.py2
-rw-r--r--generalresearch/models/network/mtr/execute.py12
-rw-r--r--generalresearch/models/network/mtr/parser.py5
-rw-r--r--generalresearch/models/network/mtr/result.py9
-rw-r--r--generalresearch/models/network/nmap/command.py2
-rw-r--r--generalresearch/models/network/nmap/execute.py12
-rw-r--r--generalresearch/models/network/nmap/result.py6
-rw-r--r--generalresearch/models/network/rdns/command.py2
-rw-r--r--generalresearch/models/network/rdns/execute.py5
-rw-r--r--generalresearch/models/network/rdns/parser.py5
-rw-r--r--generalresearch/models/network/rdns/result.py4
-rw-r--r--generalresearch/models/network/tool_run.py31
-rw-r--r--generalresearch/models/network/tool_run_command.py6
-rw-r--r--generalresearch/models/precision/question.py2
-rw-r--r--generalresearch/models/precision/survey.py21
-rw-r--r--generalresearch/models/precision/task_collection.py6
-rw-r--r--generalresearch/models/prodege/question.py4
-rw-r--r--generalresearch/models/prodege/survey.py24
-rw-r--r--generalresearch/models/prodege/task_collection.py6
-rw-r--r--generalresearch/models/repdata/question.py2
-rw-r--r--generalresearch/models/repdata/survey.py14
-rw-r--r--generalresearch/models/repdata/task_collection.py6
-rw-r--r--generalresearch/models/sago/question.py2
-rw-r--r--generalresearch/models/sago/survey.py20
-rw-r--r--generalresearch/models/sago/task_collection.py6
-rw-r--r--generalresearch/models/spectrum/question.py4
-rw-r--r--generalresearch/models/spectrum/survey.py18
-rw-r--r--generalresearch/models/spectrum/task_collection.py6
-rw-r--r--generalresearch/models/thl/category.py5
-rw-r--r--generalresearch/models/thl/contest/__init__.py10
-rw-r--r--generalresearch/models/thl/contest/contest.py12
-rw-r--r--generalresearch/models/thl/contest/contest_entry.py10
-rw-r--r--generalresearch/models/thl/contest/leaderboard.py10
-rw-r--r--generalresearch/models/thl/contest/milestone.py6
-rw-r--r--generalresearch/models/thl/contest/raffle.py12
-rw-r--r--generalresearch/models/thl/demographics.py3
-rw-r--r--generalresearch/models/thl/finance.py4
-rw-r--r--generalresearch/models/thl/ipinfo.py11
-rw-r--r--generalresearch/models/thl/leaderboard.py7
-rw-r--r--generalresearch/models/thl/ledger.py19
-rw-r--r--generalresearch/models/thl/offerwall/base.py26
-rw-r--r--generalresearch/models/thl/offerwall/cache.py19
-rw-r--r--generalresearch/models/thl/payout.py25
-rw-r--r--generalresearch/models/thl/product.py16
-rw-r--r--generalresearch/models/thl/profiling/marketplace.py21
-rw-r--r--generalresearch/models/thl/profiling/question.py17
-rw-r--r--generalresearch/models/thl/profiling/upk_property.py7
-rw-r--r--generalresearch/models/thl/profiling/upk_question.py6
-rw-r--r--generalresearch/models/thl/profiling/upk_question_answer.py14
-rw-r--r--generalresearch/models/thl/profiling/user_info.py15
-rw-r--r--generalresearch/models/thl/profiling/user_question_answer.py13
-rw-r--r--generalresearch/models/thl/report_task.py5
-rw-r--r--generalresearch/models/thl/session.py23
-rw-r--r--generalresearch/models/thl/soft_pair.py12
-rw-r--r--generalresearch/models/thl/survey/__init__.py21
-rw-r--r--generalresearch/models/thl/survey/buyer.py14
-rw-r--r--generalresearch/models/thl/survey/model.py25
-rw-r--r--generalresearch/models/thl/survey/penalty.py13
-rw-r--r--generalresearch/models/thl/survey/task_collection.py4
-rw-r--r--generalresearch/models/thl/task_adjustment.py8
-rw-r--r--generalresearch/models/thl/task_status.py33
-rw-r--r--generalresearch/models/thl/user.py12
-rw-r--r--generalresearch/models/thl/user_iphistory.py17
-rw-r--r--generalresearch/models/thl/user_profile.py10
-rw-r--r--generalresearch/models/thl/user_quality_event.py10
-rw-r--r--generalresearch/models/thl/user_streak.py5
-rw-r--r--generalresearch/models/thl/wallet/cashout_method.py23
-rw-r--r--generalresearch/models/thl/wallet/payout.py12
-rw-r--r--generalresearch/models/thl/wallet/user_wallet.py7
-rw-r--r--generalresearch/wall_status_codes/cint.py6
-rw-r--r--test_utils/conftest.py2
-rw-r--r--test_utils/managers/gr/conftest.py48
-rw-r--r--test_utils/models/conftest.py37
-rw-r--r--test_utils/models/gr/conftest.py56
-rw-r--r--tests/models/gr/test_business.py352
153 files changed, 1319 insertions, 947 deletions
diff --git a/generalresearch/config.py b/generalresearch/config.py
index 73af565..2777aa4 100644
--- a/generalresearch/config.py
+++ b/generalresearch/config.py
@@ -53,6 +53,8 @@ class GRLBaseSettings(BaseSettings):
testing_postgres_user: str | None = Field(default=None)
testing_postgres_pass: str | None = Field(default=None)
+ testing_redis: InternalHostname | None = Field(default=None)
+
git_creds: str | None = Field(default=None)
# ---
diff --git a/generalresearch/grliq/managers/forensic_data.py b/generalresearch/grliq/managers/forensic_data.py
index c1eac37..0f8534c 100644
--- a/generalresearch/grliq/managers/forensic_data.py
+++ b/generalresearch/grliq/managers/forensic_data.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from psycopg import sql
from pydantic import NonNegativeInt, PositiveInt
@@ -14,9 +14,11 @@ from generalresearch.grliq.models.forensic_result import (
GrlIqForensicCategoryResult,
Phase,
)
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.thl.user import User
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.user import User
+ from generalresearch.pg_helper import PostgresConfig
class GrlIqDataManager:
diff --git a/generalresearch/grliq/models/forensic_data.py b/generalresearch/grliq/models/forensic_data.py
index 69b1760..6a07774 100644
--- a/generalresearch/grliq/models/forensic_data.py
+++ b/generalresearch/grliq/models/forensic_data.py
@@ -6,7 +6,7 @@ from collections import Counter
from datetime import UTC, datetime, timedelta
from enum import StrEnum
from functools import cached_property
-from typing import Annotated, Any, Literal, Self
+from typing import TYPE_CHECKING, Annotated, Any, Literal, Self
from uuid import uuid4
import pycountry
@@ -53,8 +53,10 @@ from generalresearch.models.custom_types import (
IPvAnyAddressStr,
UUIDStr,
)
-from generalresearch.models.thl.ipinfo import GeoIPInformation
-from generalresearch.models.thl.session import Session
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.ipinfo import GeoIPInformation
+ from generalresearch.models.thl.session import Session
fake = Faker()
diff --git a/generalresearch/managers/base.py b/generalresearch/managers/base.py
index ba42e9e..2227d21 100644
--- a/generalresearch/managers/base.py
+++ b/generalresearch/managers/base.py
@@ -3,10 +3,12 @@ from __future__ import annotations
from collections.abc import Collection
from contextlib import nullcontext
from enum import Enum
+from typing import TYPE_CHECKING
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
-from generalresearch.sql_helper import SqlHelper
+if TYPE_CHECKING:
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
+ from generalresearch.sql_helper import SqlHelper
class Permission(int, Enum):
diff --git a/generalresearch/managers/cint/profiling.py b/generalresearch/managers/cint/profiling.py
index 9216aa5..c550632 100644
--- a/generalresearch/managers/cint/profiling.py
+++ b/generalresearch/managers/cint/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.cint.question import CintQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/criteria.py b/generalresearch/managers/criteria.py
index b8ae6ac..760afd3 100644
--- a/generalresearch/managers/criteria.py
+++ b/generalresearch/managers/criteria.py
@@ -3,11 +3,14 @@ from __future__ import annotations
from abc import ABC
from collections.abc import Collection
from datetime import UTC, datetime
+from typing import TYPE_CHECKING
from more_itertools import chunked
from generalresearch.managers.base import SqlManager
-from generalresearch.models.thl.survey import MarketplaceCondition
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.survey import MarketplaceCondition
DB_FIELDS = [
"hash",
diff --git a/generalresearch/managers/dynata/profiling.py b/generalresearch/managers/dynata/profiling.py
index 661bdad..b76ecc7 100644
--- a/generalresearch/managers/dynata/profiling.py
+++ b/generalresearch/managers/dynata/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.dynata.question import DynataQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/events.py b/generalresearch/managers/events.py
index 6779104..c43a020 100644
--- a/generalresearch/managers/events.py
+++ b/generalresearch/managers/events.py
@@ -13,14 +13,12 @@ from redis.client import PubSub, Redis
from generalresearch.incite.base import LOG
from generalresearch.managers.base import RedisManager
from generalresearch.models import Source
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.events import (
AggregateBySource,
EventEnvelope,
EventMessage,
EventType,
MaxGaugeBySource,
- ServerToClientMessage,
ServerToClientMessageAdapter,
SessionEnterPayload,
SessionFinishPayload,
@@ -30,11 +28,15 @@ from generalresearch.models.events import (
TaskStatsSnapshot,
)
from generalresearch.models.thl.definitions import Status
-from generalresearch.models.thl.session import Session, Wall
-from generalresearch.models.thl.user import User
if TYPE_CHECKING:
from influxdb import InfluxDBClient
+
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.events import ServerToClientMessage
+ from generalresearch.models.thl.session import Session, Wall
+ from generalresearch.models.thl.user import User
+
else:
InfluxDBClient = object
diff --git a/generalresearch/managers/gr/authentication.py b/generalresearch/managers/gr/authentication.py
index 851b88a..ca56467 100644
--- a/generalresearch/managers/gr/authentication.py
+++ b/generalresearch/managers/gr/authentication.py
@@ -10,14 +10,14 @@ from psycopg import sql
from pydantic import AnyHttpUrl, PositiveInt
from generalresearch.managers.base import PostgresManager, PostgresManagerWithRedis
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
-
-LOG = logging.getLogger("gr")
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.gr.authentication import GRToken, GRUser
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
+
+LOG = logging.getLogger("gr")
class GRUserManager(PostgresManagerWithRedis):
diff --git a/generalresearch/managers/gr/business.py b/generalresearch/managers/gr/business.py
index 4da0e7f..ef26f30 100644
--- a/generalresearch/managers/gr/business.py
+++ b/generalresearch/managers/gr/business.py
@@ -11,14 +11,16 @@ from generalresearch.managers.base import (
PostgresManager,
PostgresManagerWithRedis,
)
-from generalresearch.models.custom_types import UUIDStr
+from generalresearch.models.gr.business import (
+ Business,
+ BusinessBankAccount,
+ BusinessType,
+)
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.gr.business import (
- Business,
BusinessAddress,
- BusinessBankAccount,
- BusinessType,
TransferMethod,
)
from generalresearch.models.gr.team import Team
@@ -36,8 +38,6 @@ class BusinessBankAccountManager(PostgresManager):
iban: str | None = None,
swift: str | None = None,
) -> BusinessBankAccount:
- from generalresearch.models.gr.business import BusinessBankAccount
-
ba = BusinessBankAccount.model_validate(
{
"business_id": business_id,
@@ -73,7 +73,6 @@ class BusinessBankAccountManager(PostgresManager):
return ba
def get_by_business_id(self, business_id: UUIDStr) -> list[BusinessBankAccount]:
- from generalresearch.models.gr.business import BusinessBankAccount
with self.pg_config.make_connection() as conn, conn.cursor() as c:
c.execute(
@@ -192,11 +191,7 @@ class BusinessManager(PostgresManagerWithRedis):
"""
Behavior: does this raise on duplicate?
"""
- from generalresearch.models.gr.business import (
- Business,
- BusinessType,
- )
-
+ # Business.model_rebuild()
business = Business.model_validate(
{
"uuid": uuid or uuid4().hex,
@@ -281,7 +276,6 @@ class BusinessManager(PostgresManagerWithRedis):
res = c.fetchall()
response = []
- from generalresearch.models.gr.business import Business
for i in res:
# i["contact"] = BusinessContact.model_validate(i)
@@ -370,8 +364,6 @@ class BusinessManager(PostgresManagerWithRedis):
self,
business_uuid: UUIDStr,
) -> Business | None:
- from generalresearch.models.gr.business import Business
-
assert UUID(hex=business_uuid).hex == business_uuid
with self.pg_config.make_connection() as conn, conn.cursor() as c:
@@ -397,8 +389,6 @@ class BusinessManager(PostgresManagerWithRedis):
return Business.model_validate(data)
def get_by_id(self, business_id: PositiveInt) -> Business | None:
- from generalresearch.models.gr.business import Business
-
assert isinstance(business_id, int)
with self.pg_config.make_connection() as conn, conn.cursor() as c:
diff --git a/generalresearch/managers/gr/team.py b/generalresearch/managers/gr/team.py
index d04370b..3283467 100644
--- a/generalresearch/managers/gr/team.py
+++ b/generalresearch/managers/gr/team.py
@@ -11,15 +11,16 @@ from generalresearch.managers.base import (
PostgresManager,
PostgresManagerWithRedis,
)
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.gr.team import Membership, MembershipPrivilege
+from generalresearch.models.gr.team import (
+ Membership,
+ MembershipPrivilege,
+)
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.gr.authentication import GRUser
from generalresearch.models.gr.business import Business
- from generalresearch.models.gr.team import (
- Team,
- )
+ from generalresearch.models.gr.team import Team
class MembershipManager(PostgresManager):
diff --git a/generalresearch/managers/innovate/profiling.py b/generalresearch/managers/innovate/profiling.py
index bfa2685..0f32999 100644
--- a/generalresearch/managers/innovate/profiling.py
+++ b/generalresearch/managers/innovate/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.innovate.question import InnovateQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/leaderboard/tasks.py b/generalresearch/managers/leaderboard/tasks.py
index 072a1aa..9e8dc9f 100644
--- a/generalresearch/managers/leaderboard/tasks.py
+++ b/generalresearch/managers/leaderboard/tasks.py
@@ -1,4 +1,5 @@
import logging
+from typing import TYPE_CHECKING
from redis import Redis
@@ -7,7 +8,9 @@ from generalresearch.models.thl.leaderboard import (
LeaderboardCode,
LeaderboardFrequency,
)
-from generalresearch.models.thl.session import Session
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.session import Session
logger = logging.getLogger()
diff --git a/generalresearch/managers/lucid/profiling.py b/generalresearch/managers/lucid/profiling.py
index fdd2d52..5937a59 100644
--- a/generalresearch/managers/lucid/profiling.py
+++ b/generalresearch/managers/lucid/profiling.py
@@ -2,12 +2,16 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from pydantic import ValidationError
-from generalresearch.decorators import LOG
from generalresearch.models.lucid.question import LucidQuestion, LucidQuestionType
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
+
+from generalresearch.decorators import LOG
def get_profiling_library(
diff --git a/generalresearch/managers/marketplace/user_pid.py b/generalresearch/managers/marketplace/user_pid.py
index 15d8a19..fe24d38 100644
--- a/generalresearch/managers/marketplace/user_pid.py
+++ b/generalresearch/managers/marketplace/user_pid.py
@@ -2,11 +2,14 @@ from __future__ import annotations
from abc import ABC
from collections.abc import Collection
+from typing import TYPE_CHECKING
from uuid import UUID
from generalresearch.managers.base import SqlManager
from generalresearch.models import Source
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
class UserPidManager(SqlManager, ABC):
diff --git a/generalresearch/managers/morning/profiling.py b/generalresearch/managers/morning/profiling.py
index 01f99f3..7335e6b 100644
--- a/generalresearch/managers/morning/profiling.py
+++ b/generalresearch/managers/morning/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.morning.question import MorningQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/network/label.py b/generalresearch/managers/network/label.py
index f0ba9f7..cec59ad 100644
--- a/generalresearch/managers/network/label.py
+++ b/generalresearch/managers/network/label.py
@@ -2,6 +2,7 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import UTC, datetime, timedelta
+from typing import TYPE_CHECKING
from psycopg import sql
from pydantic import IPvAnyNetwork, TypeAdapter
@@ -9,10 +10,16 @@ from pydantic import IPvAnyNetwork, TypeAdapter
from generalresearch.managers.base import PostgresManager
from generalresearch.models.custom_types import (
AwareDatetimeISO,
- IPvAnyAddressStr,
IPvAnyNetworkStr,
)
-from generalresearch.models.network.label import IPLabel, IPLabelKind, IPLabelSource
+from generalresearch.models.network.label import IPLabel
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ IPvAnyNetworkStr,
+ )
+ from generalresearch.models.network.label import IPLabelKind, IPLabelSource
class IPLabelManager(PostgresManager):
diff --git a/generalresearch/managers/network/mtr.py b/generalresearch/managers/network/mtr.py
index 179b8a9..7b79d96 100644
--- a/generalresearch/managers/network/mtr.py
+++ b/generalresearch/managers/network/mtr.py
@@ -1,9 +1,13 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
from psycopg import Cursor, sql
from generalresearch.managers.base import PostgresManager
-from generalresearch.models.network.tool_run import MTRRun
+
+if TYPE_CHECKING:
+ from generalresearch.models.network.tool_run import MTRRun
class MTRRunManager(PostgresManager):
diff --git a/generalresearch/managers/network/nmap.py b/generalresearch/managers/network/nmap.py
index 574bce1..96c6009 100644
--- a/generalresearch/managers/network/nmap.py
+++ b/generalresearch/managers/network/nmap.py
@@ -1,9 +1,13 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
from psycopg import Cursor, sql
from generalresearch.managers.base import PostgresManager
-from generalresearch.models.network.tool_run import NmapRun
+
+if TYPE_CHECKING:
+ from generalresearch.models.network.tool_run import NmapRun
class NmapRunManager(PostgresManager):
diff --git a/generalresearch/managers/network/rdns.py b/generalresearch/managers/network/rdns.py
index 95a1381..1800364 100644
--- a/generalresearch/managers/network/rdns.py
+++ b/generalresearch/managers/network/rdns.py
@@ -1,9 +1,13 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
from psycopg import Cursor
from generalresearch.managers.base import PostgresManager
-from generalresearch.models.network.tool_run import RDNSRun
+
+if TYPE_CHECKING:
+ from generalresearch.models.network.tool_run import RDNSRun
class RDNSRunManager(PostgresManager):
diff --git a/generalresearch/managers/network/tool_run.py b/generalresearch/managers/network/tool_run.py
index 73afc13..ec06305 100644
--- a/generalresearch/managers/network/tool_run.py
+++ b/generalresearch/managers/network/tool_run.py
@@ -1,10 +1,11 @@
from __future__ import annotations
from collections.abc import Collection
+from typing import TYPE_CHECKING
from psycopg import Cursor, sql
-from generalresearch.managers.base import Permission, PostgresManager
+from generalresearch.managers.base import PostgresManager
from generalresearch.managers.network.mtr import MTRRunManager
from generalresearch.managers.network.nmap import NmapRunManager
from generalresearch.managers.network.rdns import RDNSRunManager
@@ -13,10 +14,13 @@ from generalresearch.models.network.tool_run import (
MTRRun,
NmapRun,
RDNSRun,
- ToolName,
ToolRun,
)
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.managers.base import Permission
+ from generalresearch.models.network.tool_run import ToolName
+ from generalresearch.pg_helper import PostgresConfig
class ToolRunManager(PostgresManager):
diff --git a/generalresearch/managers/pollfish/profiling.py b/generalresearch/managers/pollfish/profiling.py
index daf529b..43afd30 100644
--- a/generalresearch/managers/pollfish/profiling.py
+++ b/generalresearch/managers/pollfish/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.pollfish.question import PollfishQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/precision/profiling.py b/generalresearch/managers/precision/profiling.py
index 449fd25..813542c 100644
--- a/generalresearch/managers/precision/profiling.py
+++ b/generalresearch/managers/precision/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.precision.question import PrecisionQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/prodege/profiling.py b/generalresearch/managers/prodege/profiling.py
index 54a7b57..cf77fca 100644
--- a/generalresearch/managers/prodege/profiling.py
+++ b/generalresearch/managers/prodege/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.prodege.question import ProdegeQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/repdata/profiling.py b/generalresearch/managers/repdata/profiling.py
index 4b97abd..ec30d78 100644
--- a/generalresearch/managers/repdata/profiling.py
+++ b/generalresearch/managers/repdata/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.repdata.question import RepDataQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/repdata/survey.py b/generalresearch/managers/repdata/survey.py
index ab66374..2c3156c 100644
--- a/generalresearch/managers/repdata/survey.py
+++ b/generalresearch/managers/repdata/survey.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import json
from collections.abc import Collection
from datetime import UTC, datetime
+from typing import TYPE_CHECKING
import pymysql
@@ -11,10 +12,12 @@ from generalresearch.managers.survey import SurveyManager
from generalresearch.models.repdata.survey import (
RepDataCondition,
RepDataStreamHashed,
- RepDataSurvey,
RepDataSurveyHashed,
)
+if TYPE_CHECKING:
+ from generalresearch.models.repdata.survey import RepDataSurvey
+
SURVEY_FIELDS = [
"survey_id",
"survey_uuid",
diff --git a/generalresearch/managers/sago/profiling.py b/generalresearch/managers/sago/profiling.py
index 4f5b2f5..3bbad3f 100644
--- a/generalresearch/managers/sago/profiling.py
+++ b/generalresearch/managers/sago/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.sago.question import SagoQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/spectrum/profiling.py b/generalresearch/managers/spectrum/profiling.py
index 8a0904a..5de218c 100644
--- a/generalresearch/managers/spectrum/profiling.py
+++ b/generalresearch/managers/spectrum/profiling.py
@@ -2,9 +2,12 @@ from __future__ import annotations
import json
from collections.abc import Collection
+from typing import TYPE_CHECKING
from generalresearch.models.spectrum.question import SpectrumQuestion
-from generalresearch.sql_helper import SqlHelper
+
+if TYPE_CHECKING:
+ from generalresearch.sql_helper import SqlHelper
def get_profiling_library(
diff --git a/generalresearch/managers/survey.py b/generalresearch/managers/survey.py
index 1f057fb..65dbdd9 100644
--- a/generalresearch/managers/survey.py
+++ b/generalresearch/managers/survey.py
@@ -1,9 +1,12 @@
from __future__ import annotations
from abc import ABC
+from typing import TYPE_CHECKING
from generalresearch.managers.base import SqlManager
-from generalresearch.models.thl.survey import MarketplaceTask
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.survey import MarketplaceTask
class SurveyManager(SqlManager, ABC):
diff --git a/generalresearch/managers/thl/buyer.py b/generalresearch/managers/thl/buyer.py
index 5aa2a01..1e20e2f 100644
--- a/generalresearch/managers/thl/buyer.py
+++ b/generalresearch/managers/thl/buyer.py
@@ -2,11 +2,14 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import UTC, datetime
+from typing import TYPE_CHECKING
from generalresearch.managers.base import Permission, PostgresManager
-from generalresearch.models import Source
from generalresearch.models.thl.survey.buyer import Buyer
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.pg_helper import PostgresConfig
class BuyerManager(PostgresManager):
diff --git a/generalresearch/managers/thl/cashout_method.py b/generalresearch/managers/thl/cashout_method.py
index f45e692..e701da3 100644
--- a/generalresearch/managers/thl/cashout_method.py
+++ b/generalresearch/managers/thl/cashout_method.py
@@ -3,20 +3,24 @@ from __future__ import annotations
from collections.abc import Collection
from copy import copy
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import UUID, uuid4
from pydantic import NonNegativeInt
from generalresearch.managers.base import PostgresManager
-from generalresearch.models.thl.user import User
from generalresearch.models.thl.wallet import PayoutType
from generalresearch.models.thl.wallet.cashout_method import (
- CashMailCashoutMethodData,
CashoutMethod,
- PaypalCashoutMethodData,
)
+if TYPE_CHECKING:
+ from generalresearch.models.thl.user import User
+ from generalresearch.models.thl.wallet.cashout_method import (
+ CashMailCashoutMethodData,
+ PaypalCashoutMethodData,
+ )
+
class CashoutMethodManager(PostgresManager):
diff --git a/generalresearch/managers/thl/category.py b/generalresearch/managers/thl/category.py
index e8a6aa6..e6a091b 100644
--- a/generalresearch/managers/thl/category.py
+++ b/generalresearch/managers/thl/category.py
@@ -1,11 +1,15 @@
from __future__ import annotations
from collections.abc import Collection
+from typing import TYPE_CHECKING
-from generalresearch.managers.base import Permission, PostgresManager
-from generalresearch.models.custom_types import UUIDStr
+from generalresearch.managers.base import PostgresManager
from generalresearch.models.thl.category import Category
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.managers.base import Permission
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.pg_helper import PostgresConfig
class CategoryManager(PostgresManager):
diff --git a/generalresearch/managers/thl/contest_manager.py b/generalresearch/managers/thl/contest_manager.py
index 64206e1..3f85d31 100644
--- a/generalresearch/managers/thl/contest_manager.py
+++ b/generalresearch/managers/thl/contest_manager.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import UTC, datetime
-from typing import Any, Literal, cast
+from typing import TYPE_CHECKING, Any, Literal, cast
from uuid import UUID
import redis
@@ -10,21 +10,10 @@ from pydantic import NonNegativeInt, PositiveInt
from redis import Redis
from generalresearch.managers.base import PostgresManager
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.managers.thl.user_manager.user_manager import (
- UserManager,
-)
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.contest import (
ContestPrize,
ContestWinner,
)
-from generalresearch.models.thl.contest.contest import (
- Contest,
- ContestUserView,
-)
from generalresearch.models.thl.contest.definitions import (
ContestStatus,
ContestType,
@@ -41,7 +30,6 @@ from generalresearch.models.thl.contest.leaderboard import (
LeaderboardContestUserView,
)
from generalresearch.models.thl.contest.milestone import (
- ContestEntryTrigger,
MilestoneContest,
MilestoneEntry,
MilestoneUserView,
@@ -54,6 +42,20 @@ from generalresearch.models.thl.contest.raffle import (
)
from generalresearch.models.thl.user import User
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.managers.thl.user_manager.user_manager import (
+ UserManager,
+ )
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.contest.contest import (
+ Contest,
+ ContestUserView,
+ )
+ from generalresearch.models.thl.contest.milestone import ContestEntryTrigger
+
CONTEST_SELECT = """
c.id,
c.uuid::uuid,
diff --git a/generalresearch/managers/thl/ipinfo.py b/generalresearch/managers/thl/ipinfo.py
index 90757a2..93914c3 100644
--- a/generalresearch/managers/thl/ipinfo.py
+++ b/generalresearch/managers/thl/ipinfo.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import ipaddress
from collections.abc import Collection
from decimal import Decimal
+from typing import TYPE_CHECKING
import faker
from grip_client.enums import AccessType
@@ -14,17 +15,19 @@ from generalresearch.managers.base import (
PostgresManager,
PostgresManagerWithRedis,
)
-from generalresearch.models.custom_types import (
- CountryISOLike,
- IPvAnyAddressStr,
-)
from generalresearch.models.thl.ipinfo import (
GeoIPInformation,
IPGeoname,
IPInformation,
normalize_ip,
)
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ CountryISOLike,
+ IPvAnyAddressStr,
+ )
+ from generalresearch.pg_helper import PostgresConfig
fake = faker.Faker()
diff --git a/generalresearch/managers/thl/ledger_manager/conditions.py b/generalresearch/managers/thl/ledger_manager/conditions.py
index b2fd465..7dd3021 100644
--- a/generalresearch/managers/thl/ledger_manager/conditions.py
+++ b/generalresearch/managers/thl/ledger_manager/conditions.py
@@ -7,22 +7,23 @@ from typing import TYPE_CHECKING
from generalresearch.config import JAMES_BILLINGS_BPID, JAMES_BILLINGS_TX_CUTOFF
from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.thl.product import Product
-from generalresearch.models.thl.session import Session, Wall
-from generalresearch.models.thl.user import User
-
-logging.basicConfig()
-logger = logging.getLogger("LedgerManager")
-logger.setLevel(logging.INFO)
if TYPE_CHECKING:
+
from generalresearch.managers.thl.ledger_manager.ledger import (
LedgerManager,
)
from generalresearch.managers.thl.ledger_manager.thl_ledger import (
ThlLedgerManager,
)
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.product import Product
+ from generalresearch.models.thl.session import Session, Wall
+ from generalresearch.models.thl.user import User
+
+logging.basicConfig()
+logger = logging.getLogger("LedgerManager")
+logger.setLevel(logging.INFO)
def generate_condition_mp_payment(wall: Wall) -> Callable[..., bool]:
diff --git a/generalresearch/managers/thl/ledger_manager/ledger.py b/generalresearch/managers/thl/ledger_manager/ledger.py
index a5263f0..6cb4b28 100644
--- a/generalresearch/managers/thl/ledger_manager/ledger.py
+++ b/generalresearch/managers/thl/ledger_manager/ledger.py
@@ -4,7 +4,7 @@ import logging
from collections import defaultdict
from collections.abc import Callable, Collection
from datetime import UTC, datetime, timedelta
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import UUID
import redis
@@ -28,16 +28,19 @@ from generalresearch.managers.thl.ledger_manager.exceptions import (
LedgerTransactionFlagAlreadyExistsError,
LedgerTransactionReleaseLockError,
)
-from generalresearch.models.custom_types import UUIDStr, check_valid_uuid
+from generalresearch.models.custom_types import check_valid_uuid
from generalresearch.models.thl.ledger import (
LedgerAccount,
LedgerEntry,
LedgerTransaction,
- UserLedgerTransactionType,
UserLedgerTransactionTypesSummary,
)
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.ledger import UserLedgerTransactionType
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
logging.basicConfig()
logger = logging.getLogger("LedgerManager")
diff --git a/generalresearch/managers/thl/ledger_manager/thl_ledger.py b/generalresearch/managers/thl/ledger_manager/thl_ledger.py
index ded6518..7aed619 100644
--- a/generalresearch/managers/thl/ledger_manager/thl_ledger.py
+++ b/generalresearch/managers/thl/ledger_manager/thl_ledger.py
@@ -29,15 +29,12 @@ from generalresearch.managers.thl.ledger_manager.conditions import (
from generalresearch.managers.thl.ledger_manager.ledger import (
LedgerManager,
)
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.thl.contest.contest import Contest
from generalresearch.models.thl.contest.definitions import (
ContestPrizeKind,
ContestType,
)
from generalresearch.models.thl.contest.milestone import MilestoneContest
from generalresearch.models.thl.contest.raffle import (
- ContestEntry,
ContestEntryType,
RaffleContest,
)
@@ -53,14 +50,20 @@ from generalresearch.models.thl.ledger import (
from generalresearch.models.thl.ledger import (
TransactionMetadataColumns as tmc,
)
-from generalresearch.models.thl.payout import UserPayoutEvent
from generalresearch.models.thl.product import Product
-from generalresearch.models.thl.session import Session, Status, Wall
-from generalresearch.models.thl.user import User
+from generalresearch.models.thl.session import Status
from generalresearch.models.thl.wallet import PayoutType
if TYPE_CHECKING:
- from generalresearch.models.thl.contest.contest import ContestWinner
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.contest.contest import Contest, ContestWinner
+ from generalresearch.models.thl.contest.raffle import (
+ ContestEntry,
+ )
+ from generalresearch.models.thl.ledger import LedgerTransaction
+ from generalresearch.models.thl.payout import UserPayoutEvent
+ from generalresearch.models.thl.session import Session, Wall
+ from generalresearch.models.thl.user import User
logging.basicConfig()
logger = logging.getLogger("LedgerManager")
@@ -663,9 +666,7 @@ class ThlLedgerManager(LedgerManager):
)
else:
- logger.info(
- "create_transaction_bp_adjustment. No transactions needed."
- )
+ logger.info("create_transaction_bp_adjustment. No transactions needed.")
return None
else:
new_bp_payout = new_payout
@@ -735,9 +736,7 @@ class ThlLedgerManager(LedgerManager):
)
else:
- logger.info(
- "create_transaction_bp_adjustment. No transactions needed."
- )
+ logger.info("create_transaction_bp_adjustment. No transactions needed.")
return None
logger.info(entries)
@@ -796,9 +795,7 @@ class ThlLedgerManager(LedgerManager):
if skip_one_per_day_check or skip_wallet_balance_check:
skip_flag_check = True
- assert (
- datetime.now(tz=UTC) > created
- ), "created cannot be in the future"
+ assert datetime.now(tz=UTC) > created, "created cannot be in the future"
f = lambda: self.create_tx_bp_payout_(
product=product,
amount=amount,
@@ -902,9 +899,7 @@ class ThlLedgerManager(LedgerManager):
:param skip_flag_check: If True, we skip the flag check to allow
for retry of a failed previous call.
"""
- assert (
- datetime.now(tz=UTC) > created
- ), "created cannot be in the future"
+ assert datetime.now(tz=UTC) > created, "created cannot be in the future"
assert isinstance(amount, int)
assert isinstance(amount, USDCent)
diff --git a/generalresearch/managers/thl/payout.py b/generalresearch/managers/thl/payout.py
index f50e0d2..2914ba4 100644
--- a/generalresearch/managers/thl/payout.py
+++ b/generalresearch/managers/thl/payout.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import uuid4
import numpy as np
@@ -19,16 +19,9 @@ from generalresearch.managers.base import (
from generalresearch.managers.thl.ledger_manager.exceptions import (
LedgerTransactionConditionFailedError,
)
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.managers.thl.product import ProductManager
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.gr.business import Business
from generalresearch.models.thl.definitions import PayoutStatus
from generalresearch.models.thl.ledger import (
Direction,
- LedgerAccount,
OrderBy,
)
from generalresearch.models.thl.payout import (
@@ -38,13 +31,22 @@ from generalresearch.models.thl.payout import (
PayoutEvent,
UserPayoutEvent,
)
-from generalresearch.models.thl.product import Product
from generalresearch.models.thl.wallet import PayoutType
from generalresearch.models.thl.wallet.cashout_method import (
CashMailOrderData,
CashoutRequestInfo,
)
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.managers.thl.product import ProductManager
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.gr.business import Business
+ from generalresearch.models.thl.ledger import LedgerAccount
+ from generalresearch.models.thl.product import Product
+
class PayoutEventManager(PostgresManagerWithRedis):
"""This is the default base Payout Event Manger. It acts as a base for
diff --git a/generalresearch/managers/thl/product.py b/generalresearch/managers/thl/product.py
index aac2979..535e566 100644
--- a/generalresearch/managers/thl/product.py
+++ b/generalresearch/managers/thl/product.py
@@ -18,15 +18,15 @@ from sentry_sdk import capture_exception
from generalresearch.decorators import LOG
from generalresearch.managers.base import (
- Permission,
PostgresManager,
)
-from generalresearch.models.custom_types import UUIDStr, is_valid_uuid
-from generalresearch.pg_helper import PostgresConfig
-
-logger = logging.getLogger()
+from generalresearch.models.custom_types import is_valid_uuid
if TYPE_CHECKING:
+ from generalresearch.managers.base import (
+ Permission,
+ )
+ from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.product import (
PayoutConfig,
Product,
@@ -38,6 +38,9 @@ if TYPE_CHECKING:
UserHealthConfig,
UserWalletConfig,
)
+ from generalresearch.pg_helper import PostgresConfig
+
+logger = logging.getLogger()
class ProductManager(PostgresManager):
diff --git a/generalresearch/managers/thl/profiling/uqa.py b/generalresearch/managers/thl/profiling/uqa.py
index fa1747b..d240eea 100644
--- a/generalresearch/managers/thl/profiling/uqa.py
+++ b/generalresearch/managers/thl/profiling/uqa.py
@@ -3,13 +3,16 @@ from __future__ import annotations
import logging
from collections.abc import Collection
from datetime import UTC, datetime, timedelta
+from typing import TYPE_CHECKING
from generalresearch.managers.base import PostgresManagerWithRedis
from generalresearch.models.thl.profiling.user_question_answer import (
DUMMY_UQA,
UserQuestionAnswer,
)
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.user import User
logger = logging.getLogger()
diff --git a/generalresearch/managers/thl/profiling/user_upk.py b/generalresearch/managers/thl/profiling/user_upk.py
index 6106037..53475b5 100644
--- a/generalresearch/managers/thl/profiling/user_upk.py
+++ b/generalresearch/managers/thl/profiling/user_upk.py
@@ -4,27 +4,29 @@ import json
from collections import defaultdict
from collections.abc import Collection
from datetime import UTC, datetime, timedelta
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import UUID
from psycopg import Cursor
from pydantic import PositiveInt
from generalresearch.managers.base import (
- Permission,
PostgresManagerWithRedis,
)
from generalresearch.managers.thl.profiling.schema import UpkSchemaManager
from generalresearch.models.thl.profiling.upk_property import (
Cardinality,
PropertyType,
- UpkProperty,
)
from generalresearch.models.thl.profiling.upk_question_answer import (
UpkQuestionAnswer,
)
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
+
+if TYPE_CHECKING:
+ from generalresearch.managers.base import Permission
+ from generalresearch.models.thl.profiling.upk_property import UpkProperty
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
class UserUpkManager(PostgresManagerWithRedis):
diff --git a/generalresearch/managers/thl/session.py b/generalresearch/managers/thl/session.py
index 959003c..7f17252 100644
--- a/generalresearch/managers/thl/session.py
+++ b/generalresearch/managers/thl/session.py
@@ -3,7 +3,7 @@ from __future__ import annotations
from collections.abc import Collection
from datetime import UTC, datetime, timedelta
from decimal import Decimal
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import UUID, uuid4
from faker import Faker
@@ -16,14 +16,7 @@ from generalresearch.managers.base import (
PostgresManager,
)
from generalresearch.managers.thl.product import ProductManager
-from generalresearch.models import DeviceType
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.legacy.bucket import Bucket
-from generalresearch.models.thl.definitions import (
- SessionStatusCode2,
- Status,
- StatusCode1,
-)
from generalresearch.models.thl.session import (
Session,
Wall,
@@ -34,6 +27,15 @@ from generalresearch.models.thl.task_status import (
)
from generalresearch.models.thl.user import User
+if TYPE_CHECKING:
+ from generalresearch.models import DeviceType
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.definitions import (
+ SessionStatusCode2,
+ Status,
+ StatusCode1,
+ )
+
fake = Faker()
@@ -190,7 +192,12 @@ class SessionManager(PostgresManager):
# re-run model_validate after
finished = finished if finished else datetime.now(tz=UTC)
session.update(
- status=status, status_code_1=status_code_1, status_code_2=status_code_2, finished=finished, payout=payout, user_payout=user_payout
+ status=status,
+ status_code_1=status_code_1,
+ status_code_2=status_code_2,
+ finished=finished,
+ payout=payout,
+ user_payout=user_payout,
)
d = session.model_dump_mysql()
self.pg_config.execute_write(
@@ -446,9 +453,7 @@ class SessionManager(PostgresManager):
if started_before or started_after:
started_after = started_after or datetime(2017, 1, 1, tzinfo=UTC)
started_before = started_before or datetime.now(tz=UTC)
- assert (
- started_after.tzinfo == UTC
- ), "started_after must be tz-aware as UTC"
+ assert started_after.tzinfo == UTC, "started_after must be tz-aware as UTC"
assert (
started_before.tzinfo == UTC
), "started_before must be tz-aware as UTC"
diff --git a/generalresearch/managers/thl/survey.py b/generalresearch/managers/thl/survey.py
index 024ad38..eacb345 100644
--- a/generalresearch/managers/thl/survey.py
+++ b/generalresearch/managers/thl/survey.py
@@ -3,7 +3,7 @@ from __future__ import annotations
from collections import defaultdict
from collections.abc import Collection
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from more_itertools import chunked
@@ -14,12 +14,14 @@ from generalresearch.managers.base import Permission, PostgresManager
from generalresearch.managers.thl.buyer import BuyerManager
from generalresearch.managers.thl.category import CategoryManager
from generalresearch.models import Source
-from generalresearch.models.custom_types import SurveyKey
from generalresearch.models.thl.survey.model import (
Survey,
SurveyStat,
)
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import SurveyKey
+ from generalresearch.pg_helper import PostgresConfig
class SurveyManager(PostgresManager):
diff --git a/generalresearch/managers/thl/survey_penalty.py b/generalresearch/managers/thl/survey_penalty.py
index bf914cb..08f8649 100644
--- a/generalresearch/managers/thl/survey_penalty.py
+++ b/generalresearch/managers/thl/survey_penalty.py
@@ -4,21 +4,24 @@ import json
import threading
from collections import defaultdict
from datetime import timedelta
+from typing import TYPE_CHECKING
from cachetools import TTLCache, cachedmethod
from generalresearch.decorators import LOG
from generalresearch.managers.base import RedisManager
-from generalresearch.models.custom_types import (
- UUIDStr,
-)
-from generalresearch.models.thl.survey.penalty import (
- BPSurveyPenalty,
- Penalty,
- PenaltyListAdapter,
- TeamSurveyPenalty,
-)
-from generalresearch.redis_helper import RedisConfig
+from generalresearch.models.thl.survey.penalty import PenaltyListAdapter
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ UUIDStr,
+ )
+ from generalresearch.models.thl.survey.penalty import (
+ BPSurveyPenalty,
+ Penalty,
+ TeamSurveyPenalty,
+ )
+ from generalresearch.redis_helper import RedisConfig
class SurveyPenaltyManager(RedisManager):
diff --git a/generalresearch/managers/thl/task_adjustment.py b/generalresearch/managers/thl/task_adjustment.py
index 2d89334..e3f382d 100644
--- a/generalresearch/managers/thl/task_adjustment.py
+++ b/generalresearch/managers/thl/task_adjustment.py
@@ -4,17 +4,14 @@ import logging
from datetime import UTC, datetime
from decimal import Decimal
from functools import cached_property
+from typing import TYPE_CHECKING
from generalresearch.managers import parse_order_by
from generalresearch.managers.base import (
PostgresManager,
)
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
from generalresearch.managers.thl.session import SessionManager
from generalresearch.managers.thl.wall import WallManager
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.definitions import (
Status,
WallAdjustedStatus,
@@ -24,6 +21,12 @@ from generalresearch.models.thl.session import (
)
from generalresearch.models.thl.task_adjustment import TaskAdjustmentEvent
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.models.custom_types import UUIDStr
+
logging.basicConfig()
logger = logging.getLogger(__name__)
diff --git a/generalresearch/managers/thl/user_compensate.py b/generalresearch/managers/thl/user_compensate.py
index 8338424..3f0f3ec 100644
--- a/generalresearch/managers/thl/user_compensate.py
+++ b/generalresearch/managers/thl/user_compensate.py
@@ -2,15 +2,17 @@ from __future__ import annotations
from datetime import UTC, datetime
from decimal import Decimal
+from typing import TYPE_CHECKING
from uuid import uuid4
from pydantic import NonNegativeInt
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.thl.user import User
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.user import User
def user_compensate(
diff --git a/generalresearch/managers/thl/user_manager/__init__.py b/generalresearch/managers/thl/user_manager/__init__.py
index 449dc2a..6414ef2 100644
--- a/generalresearch/managers/thl/user_manager/__init__.py
+++ b/generalresearch/managers/thl/user_manager/__init__.py
@@ -4,11 +4,12 @@ import csv
import logging
from pathlib import Path
from threading import RLock
-from typing import Any
+from typing import TYPE_CHECKING, Any
from cachetools import TTLCache, cached
-from generalresearch.models.thl.product import Product
+if TYPE_CHECKING:
+ from generalresearch.models.thl.product import Product
logger = logging.getLogger()
diff --git a/generalresearch/managers/thl/user_manager/mysql_user_manager.py b/generalresearch/managers/thl/user_manager/mysql_user_manager.py
index af65d65..2af23dc 100644
--- a/generalresearch/managers/thl/user_manager/mysql_user_manager.py
+++ b/generalresearch/managers/thl/user_manager/mysql_user_manager.py
@@ -4,14 +4,17 @@ import logging
from collections.abc import Collection
from datetime import UTC, datetime
from functools import lru_cache
+from typing import TYPE_CHECKING
from uuid import uuid4
import psycopg
from psycopg import sql
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.user import User
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.pg_helper import PostgresConfig
logging.basicConfig()
logger = logging.getLogger()
diff --git a/generalresearch/managers/thl/user_manager/rate_limit.py b/generalresearch/managers/thl/user_manager/rate_limit.py
index 5d239c6..2aaa134 100644
--- a/generalresearch/managers/thl/user_manager/rate_limit.py
+++ b/generalresearch/managers/thl/user_manager/rate_limit.py
@@ -1,4 +1,5 @@
import logging
+from typing import TYPE_CHECKING
from limits import RateLimitItem, RateLimitItemPerHour, storage, strategies
from limits.limits import TIME_TYPES, safe_string
@@ -10,7 +11,9 @@ from generalresearch.managers.thl.user_manager import (
from generalresearch.managers.thl.user_manager.exceptions import (
UserCreateNotAllowedError,
)
-from generalresearch.models.thl.product import Product
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.product import Product
logger = logging.getLogger()
diff --git a/generalresearch/managers/thl/user_manager/user_manager.py b/generalresearch/managers/thl/user_manager/user_manager.py
index 26b1fd6..907a030 100644
--- a/generalresearch/managers/thl/user_manager/user_manager.py
+++ b/generalresearch/managers/thl/user_manager/user_manager.py
@@ -10,7 +10,9 @@ from pydantic import RedisDsn
from generalresearch.managers.base import Permission
from generalresearch.managers.thl.product import ProductManager
-from generalresearch.managers.thl.user_manager.exceptions import UserDoesntExistError
+from generalresearch.managers.thl.user_manager.exceptions import (
+ UserDoesntExistError,
+)
from generalresearch.managers.thl.user_manager.mysql_user_manager import (
MysqlUserManager,
)
@@ -20,15 +22,16 @@ from generalresearch.managers.thl.user_manager.rate_limit import (
from generalresearch.managers.thl.user_manager.redis_user_manager import (
RedisUserManager,
)
-from generalresearch.pg_helper import PostgresConfig
from generalresearch.utils.copying_cache import deepcopy_return
if TYPE_CHECKING:
+
from generalresearch.managers.thl.userhealth import AuditLogManager
from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user import User
from generalresearch.models.thl.userhealth import AuditLog
+ from generalresearch.pg_helper import PostgresConfig
logging.basicConfig()
logger = logging.getLogger()
diff --git a/generalresearch/managers/thl/userhealth.py b/generalresearch/managers/thl/userhealth.py
index 2bbdfab..b986256 100644
--- a/generalresearch/managers/thl/userhealth.py
+++ b/generalresearch/managers/thl/userhealth.py
@@ -11,24 +11,25 @@ from pydantic import NonNegativeInt, PositiveInt
from generalresearch.decorators import LOG
from generalresearch.managers.base import (
- Permission,
PostgresManager,
PostgresManagerWithRedis,
)
from generalresearch.managers.thl.ipinfo import GeoIpInfoManager
-from generalresearch.models.custom_types import IPvAnyAddressStr
-from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user_iphistory import (
IPRecord,
UserIPHistory,
UserIPRecord,
)
-from generalresearch.models.thl.userhealth import AuditLog, AuditLogLevel
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
+from generalresearch.models.thl.userhealth import AuditLog
if TYPE_CHECKING:
+ from generalresearch.managers.base import Permission
+ from generalresearch.models.custom_types import IPvAnyAddressStr
+ from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user import User
+ from generalresearch.models.thl.userhealth import AuditLogLevel
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
fake = faker.Faker()
diff --git a/generalresearch/managers/thl/wall.py b/generalresearch/managers/thl/wall.py
index 774db9e..b9dc94d 100644
--- a/generalresearch/managers/thl/wall.py
+++ b/generalresearch/managers/thl/wall.py
@@ -6,6 +6,7 @@ from collections.abc import Collection
from datetime import UTC, datetime, timedelta
from decimal import Decimal
from functools import cached_property
+from typing import TYPE_CHECKING
from uuid import uuid4
from faker import Faker
@@ -15,18 +16,12 @@ from pydantic import AwareDatetime, PositiveInt
from generalresearch.managers import parse_order_by
from generalresearch.managers.base import (
- Permission,
PostgresManager,
PostgresManagerWithRedis,
)
from generalresearch.models import Source
-from generalresearch.models.custom_types import SurveyKey, UUIDStr
from generalresearch.models.thl.definitions import (
- ReportValue,
- Status,
- StatusCode1,
WallAdjustedStatus,
- WallStatusCode2,
)
from generalresearch.models.thl.ledger import OrderBy
from generalresearch.models.thl.session import (
@@ -35,7 +30,19 @@ from generalresearch.models.thl.session import (
check_adjusted_status_wall_consistent,
)
from generalresearch.models.thl.survey.model import TaskActivity
-from generalresearch.pg_helper import PostgresConfig
+
+if TYPE_CHECKING:
+ from generalresearch.managers.base import (
+ Permission,
+ )
+ from generalresearch.models.custom_types import SurveyKey, UUIDStr
+ from generalresearch.models.thl.definitions import (
+ ReportValue,
+ Status,
+ StatusCode1,
+ WallStatusCode2,
+ )
+ from generalresearch.pg_helper import PostgresConfig
logger = logging.getLogger("WallManager")
fake = Faker()
diff --git a/generalresearch/managers/thl/wallet/__init__.py b/generalresearch/managers/thl/wallet/__init__.py
index 05e700d..457483f 100644
--- a/generalresearch/managers/thl/wallet/__init__.py
+++ b/generalresearch/managers/thl/wallet/__init__.py
@@ -1,28 +1,30 @@
from decimal import Decimal
-from typing import Any
+from typing import TYPE_CHECKING, Any
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.managers.thl.payout import (
- PayoutEventManager,
- UserPayoutEventManager,
-)
-from generalresearch.managers.thl.tango_api import TangoClient
-from generalresearch.managers.thl.user_manager.user_manager import (
- UserManager,
-)
-from generalresearch.managers.thl.userhealth import UserIpHistoryManager
from generalresearch.managers.thl.wallet.approve import (
approve_amt_cashout,
approve_paypal_order,
)
from generalresearch.models.thl.definitions import PayoutStatus
-from generalresearch.models.thl.payout import UserPayoutEvent
from generalresearch.models.thl.wallet import PayoutType
-from generalresearch.models.thl.wallet.cashout_method import (
- CashMailOrderData,
-)
+
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.managers.thl.payout import (
+ PayoutEventManager,
+ UserPayoutEventManager,
+ )
+ from generalresearch.managers.thl.tango_api import TangoClient
+ from generalresearch.managers.thl.user_manager.user_manager import (
+ UserManager,
+ )
+ from generalresearch.managers.thl.userhealth import UserIpHistoryManager
+ from generalresearch.models.thl.payout import UserPayoutEvent
+ from generalresearch.models.thl.wallet.cashout_method import (
+ CashMailOrderData,
+ )
def manage_pending_cashout(
diff --git a/generalresearch/managers/thl/wallet/approve.py b/generalresearch/managers/thl/wallet/approve.py
index 4a7ae5e..7fedec1 100644
--- a/generalresearch/managers/thl/wallet/approve.py
+++ b/generalresearch/managers/thl/wallet/approve.py
@@ -1,10 +1,16 @@
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.managers.thl.payout import PayoutEventManager
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
from generalresearch.models.thl.definitions import PayoutStatus
-from generalresearch.models.thl.payout import UserPayoutEvent
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.managers.thl.payout import PayoutEventManager
+ from generalresearch.models.thl.payout import UserPayoutEvent
+ from generalresearch.models.thl.user import User
def approve_paypal_order(
diff --git a/generalresearch/managers/thl/wallet/tango.py b/generalresearch/managers/thl/wallet/tango.py
index be8fd97..038f67f 100644
--- a/generalresearch/managers/thl/wallet/tango.py
+++ b/generalresearch/managers/thl/wallet/tango.py
@@ -1,16 +1,21 @@
-from typing import Any
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
from generalresearch.config import (
is_debug,
)
-from generalresearch.managers.thl.ledger_manager.thl_ledger import (
- ThlLedgerManager,
-)
-from generalresearch.managers.thl.payout import PayoutEventManager
-from generalresearch.managers.thl.tango_api import TangoClient, TangoOrderRequest
+from generalresearch.managers.thl.tango_api import TangoOrderRequest
from generalresearch.models.thl.definitions import PayoutStatus
-from generalresearch.models.thl.payout import UserPayoutEvent
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.ledger_manager.thl_ledger import (
+ ThlLedgerManager,
+ )
+ from generalresearch.managers.thl.payout import PayoutEventManager
+ from generalresearch.managers.thl.tango_api import TangoClient
+ from generalresearch.models.thl.payout import UserPayoutEvent
+ from generalresearch.models.thl.user import User
def complete_tango_order(
diff --git a/generalresearch/models/admin/request.py b/generalresearch/models/admin/request.py
index 6112786..f128e1b 100644
--- a/generalresearch/models/admin/request.py
+++ b/generalresearch/models/admin/request.py
@@ -2,12 +2,13 @@ from __future__ import annotations
from datetime import UTC, datetime, timedelta
from enum import Enum
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
import pandas as pd
from pydantic import BaseModel, Field, computed_field, model_validator
-from generalresearch.models.custom_types import AwareDatetimeISO
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
class ReportType(Enum):
diff --git a/generalresearch/models/cint/question.py b/generalresearch/models/cint/question.py
index 4c0e52f..44efd13 100644
--- a/generalresearch/models/cint/question.py
+++ b/generalresearch/models/cint/question.py
@@ -9,14 +9,14 @@ from uuid import UUID
from pydantic import BaseModel, Field, field_validator, model_validator
from generalresearch.models import Source, string_utils
-from generalresearch.models.cint import CintQuestionIdType
-from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
MarketplaceUserQuestionAnswer,
)
if TYPE_CHECKING:
+ from generalresearch.models.cint import CintQuestionIdType
+ from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/cint/survey.py b/generalresearch/models/cint/survey.py
index fde4559..8c8f882 100644
--- a/generalresearch/models/cint/survey.py
+++ b/generalresearch/models/cint/survey.py
@@ -4,7 +4,7 @@ import json
import logging
from datetime import UTC, datetime
from decimal import Decimal
-from typing import Annotated, Any, Literal, Self
+from typing import TYPE_CHECKING, Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
@@ -19,12 +19,6 @@ from pydantic import (
from generalresearch.locales import Localelator
from generalresearch.models import Source, TaskCalculationType
-from generalresearch.models.cint import CintQuestionIdType
-from generalresearch.models.custom_types import (
- AlphaNumStr,
- AwareDatetimeISO,
- CoercedStr,
-)
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
from generalresearch.models.thl.survey.condition import (
@@ -32,6 +26,14 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.cint import CintQuestionIdType
+ from generalresearch.models.custom_types import (
+ AlphaNumStr,
+ AwareDatetimeISO,
+ CoercedStr,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/cint/task_collection.py b/generalresearch/models/cint/task_collection.py
index 4ae8de4..31a0173 100644
--- a/generalresearch/models/cint/task_collection.py
+++ b/generalresearch/models/cint/task_collection.py
@@ -1,15 +1,19 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
-from generalresearch.models.cint.survey import CintSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.cint.survey import CintSurvey
+
COUNTRY_ISOS: set[str] = Localelator().get_all_countries()
LANGUAGE_ISOS: set[str] = Localelator().get_all_languages()
diff --git a/generalresearch/models/dynata/question.py b/generalresearch/models/dynata/question.py
index b95f7c6..1ed560a 100644
--- a/generalresearch/models/dynata/question.py
+++ b/generalresearch/models/dynata/question.py
@@ -7,14 +7,16 @@ import re
from datetime import timedelta
from enum import StrEnum
from functools import cached_property
-from typing import Any, Literal
+from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, PositiveInt, field_validator, model_validator
from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.profiling.marketplace import MarketplaceQuestion
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/dynata/survey.py b/generalresearch/models/dynata/survey.py
index 942ab4f..70e3659 100644
--- a/generalresearch/models/dynata/survey.py
+++ b/generalresearch/models/dynata/survey.py
@@ -5,7 +5,7 @@ import logging
from datetime import UTC
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
@@ -19,14 +19,7 @@ from pydantic import (
)
from generalresearch.locales import Localelator
-from generalresearch.models import Source, TaskCalculationType
-from generalresearch.models.custom_types import (
- AlphaNumStr,
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- DeviceTypes,
-)
+from generalresearch.models import Source
from generalresearch.models.dynata import DynataStatus
from generalresearch.models.thl.demographics import (
Gender,
@@ -37,6 +30,16 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models import TaskCalculationType
+ from generalresearch.models.custom_types import (
+ AlphaNumStr,
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ DeviceTypes,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/dynata/task_collection.py b/generalresearch/models/dynata/task_collection.py
index 2b82bfd..94868bb 100644
--- a/generalresearch/models/dynata/task_collection.py
+++ b/generalresearch/models/dynata/task_collection.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
@@ -8,12 +8,14 @@ from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models import TaskCalculationType
from generalresearch.models.dynata import DynataStatus
-from generalresearch.models.dynata.survey import DynataSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.dynata.survey import DynataSurvey
+
COUNTRY_ISOS = Localelator().get_all_countries()
LANGUAGE_ISOS = Localelator().get_all_languages()
diff --git a/generalresearch/models/events.py b/generalresearch/models/events.py
index 70f699b..8d059f9 100644
--- a/generalresearch/models/events.py
+++ b/generalresearch/models/events.py
@@ -1,6 +1,6 @@
from datetime import UTC, datetime, timedelta
from enum import StrEnum
-from typing import Annotated, Literal
+from typing import TYPE_CHECKING, Annotated, Literal
from uuid import uuid4
from pydantic import (
@@ -13,18 +13,19 @@ from pydantic import (
model_validator,
)
-from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- UUIDStr,
-)
-from generalresearch.models.thl.definitions import (
- SessionStatusCode2,
- Status,
- StatusCode1,
- WallStatusCode2,
-)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.definitions import (
+ SessionStatusCode2,
+ Status,
+ StatusCode1,
+ WallStatusCode2,
+ )
class MessageKind(StrEnum):
diff --git a/generalresearch/models/gr/authentication.py b/generalresearch/models/gr/authentication.py
index 25f65fa..21ece8c 100644
--- a/generalresearch/models/gr/authentication.py
+++ b/generalresearch/models/gr/authentication.py
@@ -17,14 +17,14 @@ from pydantic import (
)
from generalresearch.decorators import LOG
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.gr.business import Business
from generalresearch.models.gr.team import Team
from generalresearch.models.thl.product import Product
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
class Claims(BaseModel):
diff --git a/generalresearch/models/gr/business.py b/generalresearch/models/gr/business.py
index f6689a8..146d690 100644
--- a/generalresearch/models/gr/business.py
+++ b/generalresearch/models/gr/business.py
@@ -20,24 +20,28 @@ from pydantic_extra_types.phone_numbers import PhoneNumber
from generalresearch.currency import USDCent
from generalresearch.decorators import LOG
-from generalresearch.incite.mergers.pop_ledger import PopLedgerMerge
from generalresearch.incite.schemas.mergers.pop_ledger import (
numerical_col_names,
)
from generalresearch.models.admin.request import ReportRequest, ReportType
-from generalresearch.models.custom_types import (
- AwareDatetime,
- UUIDStr,
- UUIDStrCoerce,
-)
+from generalresearch.models.gr.team import Team
from generalresearch.models.thl.finance import BusinessBalances, POPFinancial
-from generalresearch.models.thl.ledger import LedgerAccount, OrderBy
-from generalresearch.models.thl.payout import BusinessPayoutEvent
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
+from generalresearch.models.thl.ledger import OrderBy
from generalresearch.utils.aggregation import group_by_year
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.incite.mergers.pop_ledger import PopLedgerMerge
+ from generalresearch.models.custom_types import (
+ AwareDatetime,
+ UUIDStr,
+ UUIDStrCoerce,
+ )
+ from generalresearch.models.thl.ledger import LedgerAccount
+ from generalresearch.models.thl.payout import BusinessPayoutEvent
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
+
logging.basicConfig()
logger = logging.getLogger(__name__)
@@ -49,6 +53,9 @@ if TYPE_CHECKING:
from generalresearch.incite.mergers.foundations.enriched_wall import (
EnrichedWallMerge,
)
+ from generalresearch.managers.gr.business import (
+ BusinessBankAccountManager,
+ )
from generalresearch.managers.thl.ledger_manager.ledger import (
LedgerManager,
)
@@ -58,7 +65,7 @@ if TYPE_CHECKING:
from generalresearch.managers.thl.payout import (
BusinessPayoutEventManager,
)
- from generalresearch.models.gr.team import Team
+ from generalresearch.managers.thl.product import ProductManager
from generalresearch.models.thl.product import Product
@@ -263,8 +270,6 @@ class Business(BaseModel):
self.addresses = [BusinessAddress.model_validate(i) for i in res]
def prefetch_teams(self, pg_config: PostgresConfig) -> None:
- from generalresearch.models.gr.team import Team
-
with pg_config.make_connection() as conn, conn.cursor(
row_factory=dict_row
) as c:
@@ -288,30 +293,27 @@ class Business(BaseModel):
self.teams = [Team.model_validate(i) for i in res]
- def prefetch_products(self, thl_pg_config: PostgresConfig) -> None:
+ def prefetch_products(self, product_manager: ProductManager) -> None:
"""
:return: All the Products for this Business
"""
- from generalresearch.managers.thl.product import ProductManager
- pm = ProductManager(pg_config=thl_pg_config)
- self.products = pm.fetch_uuids(business_uuids=[self.uuid])
+ self.products = product_manager.fetch_uuids(business_uuids=[self.uuid])
- def prefetch_bank_accounts(self, pg_config: PostgresConfig) -> None:
- from generalresearch.managers.gr.business import (
- BusinessBankAccountManager,
+ def prefetch_bank_accounts(
+ self, business_bank_account_manager: BusinessBankAccountManager
+ ) -> None:
+ self.bank_accounts = business_bank_account_manager.get_by_business_id(
+ business_id=self.id
)
- bam = BusinessBankAccountManager(pg_config=pg_config)
- self.bank_accounts = bam.get_by_business_id(business_id=self.id)
-
def prefetch_bp_accounts(
- self, thl_lm: ThlLedgerManager, thl_pg_config: PostgresConfig
+ self, thl_lm: ThlLedgerManager, product_manager: ProductManager
):
# We need to prefetch the Products everytime because there is no way
# of knowing if a new Product has been added since the last time it
# ran.
- self.prefetch_products(thl_pg_config=thl_pg_config)
+ self.prefetch_products(product_manager=product_manager)
product_lookup = {p.uuid: p for p in self.products}
accounts = thl_lm.get_accounts_if_exists(
@@ -332,6 +334,7 @@ class Business(BaseModel):
)
product = product_lookup[product_uuid]
thl_lm.get_account_or_create_bp_wallet(product=product)
+
if refresh:
accounts = thl_lm.get_accounts_if_exists(
qualified_names=[
diff --git a/generalresearch/models/gr/team.py b/generalresearch/models/gr/team.py
index 4752bea..b36ac4c 100644
--- a/generalresearch/models/gr/team.py
+++ b/generalresearch/models/gr/team.py
@@ -22,27 +22,33 @@ from pydantic import (
from pydantic.json_schema import SkipJsonSchema
from generalresearch.decorators import LOG
-from generalresearch.incite.mergers.foundations.enriched_session import (
- EnrichedSessionMerge,
-)
-from generalresearch.incite.mergers.foundations.enriched_wall import (
- EnrichedWallMerge,
-)
from generalresearch.models.admin.request import ReportRequest, ReportType
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- UUIDStr,
- UUIDStrCoerce,
-)
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
from generalresearch.utils.enum import ReprEnumMeta
if TYPE_CHECKING:
from generalresearch.incite.base import GRLDatasets
+ from generalresearch.incite.mergers.foundations.enriched_session import (
+ EnrichedSessionMerge,
+ )
+ from generalresearch.incite.mergers.foundations.enriched_wall import (
+ EnrichedWallMerge,
+ )
+ from generalresearch.managers.gr.authentication import (
+ GRUserManager,
+ )
+ from generalresearch.managers.gr.business import BusinessManager
+ from generalresearch.managers.gr.team import MembershipManager
+ from generalresearch.managers.thl.product import ProductManager
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ UUIDStr,
+ UUIDStrCoerce,
+ )
from generalresearch.models.gr.authentication import GRUser
from generalresearch.models.gr.business import Business
from generalresearch.models.thl.product import Product
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
class MembershipPrivilege(Enum, metaclass=ReprEnumMeta):
@@ -120,36 +126,17 @@ class Team(BaseModel):
# --- Prefetch Methods ---
- def prefetch_memberships(self, pg_config: PostgresConfig) -> None:
- from generalresearch.managers.gr.team import MembershipManager
-
- mm = MembershipManager(pg_config=pg_config)
- self.memberships = mm.get_by_team_id(team_id=self.id)
-
- def prefetch_gr_users(
- self, pg_config: PostgresConfig, redis_config: RedisConfig
- ) -> None:
- from generalresearch.managers.gr.authentication import (
- GRUserManager,
- )
-
- gr_um = GRUserManager(pg_config=pg_config, redis_config=redis_config)
-
- self.gr_users = gr_um.get_by_team(team_id=self.id)
-
- def prefetch_businesses(
- self, pg_config: PostgresConfig, redis_config: RedisConfig
- ) -> None:
- from generalresearch.managers.gr.business import BusinessManager
+ def prefetch_memberships(self, membership_manager: MembershipManager) -> None:
+ self.memberships = membership_manager.get_by_team_id(team_id=self.id)
- bm = BusinessManager(pg_config=pg_config, redis_config=redis_config)
- self.businesses = bm.get_by_team(team_id=self.id)
+ def prefetch_gr_users(self, gr_user_manager: GRUserManager) -> None:
+ self.gr_users = gr_user_manager.get_by_team(team_id=self.id)
- def prefetch_products(self, thl_pg_config: PostgresConfig) -> None:
- from generalresearch.managers.thl.product import ProductManager
+ def prefetch_businesses(self, business_manager: BusinessManager) -> None:
+ self.businesses = business_manager.get_by_team(team_id=self.id)
- pm = ProductManager(pg_config=thl_pg_config)
- self.products = pm.fetch_uuids(team_uuids=[self.uuid])
+ def prefetch_products(self, product_manager: ProductManager) -> None:
+ self.products = product_manager.fetch_uuids(team_uuids=[self.uuid])
# --- Prebuild Methods ---
diff --git a/generalresearch/models/innovate/question.py b/generalresearch/models/innovate/question.py
index f5a4846..fc89524 100644
--- a/generalresearch/models/innovate/question.py
+++ b/generalresearch/models/innovate/question.py
@@ -9,13 +9,13 @@ from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator
from generalresearch.models import Source
-from generalresearch.models.innovate import InnovateQuestionID
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
MarketplaceUserQuestionAnswer,
)
if TYPE_CHECKING:
+ from generalresearch.models.innovate import InnovateQuestionID
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/innovate/survey.py b/generalresearch/models/innovate/survey.py
index d07f960..60921df 100644
--- a/generalresearch/models/innovate/survey.py
+++ b/generalresearch/models/innovate/survey.py
@@ -6,6 +6,7 @@ from datetime import UTC, date
from decimal import Decimal
from functools import cached_property
from typing import (
+ TYPE_CHECKING,
Annotated,
Any,
Literal,
@@ -26,20 +27,12 @@ from generalresearch.locales import Localelator
from generalresearch.models import (
LogicalOperator,
Source,
- TaskCalculationType,
-)
-from generalresearch.models.custom_types import (
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- DeviceTypes,
)
from generalresearch.models.innovate import (
InnovateDuplicateCheckLevel,
InnovateQuotaStatus,
InnovateStatus,
)
-from generalresearch.models.innovate.question import InnovateQuestionID
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
from generalresearch.models.thl.survey.condition import (
@@ -47,6 +40,18 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models import (
+ TaskCalculationType,
+ )
+ from generalresearch.models.custom_types import (
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ DeviceTypes,
+ )
+ from generalresearch.models.innovate.question import InnovateQuestionID
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/innovate/task_collection.py b/generalresearch/models/innovate/task_collection.py
index 7bf9d0f..a647d30 100644
--- a/generalresearch/models/innovate/task_collection.py
+++ b/generalresearch/models/innovate/task_collection.py
@@ -1,16 +1,20 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models.innovate import InnovateStatus
-from generalresearch.models.innovate.survey import InnovateSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.innovate.survey import InnovateSurvey
+
COUNTRY_ISOS: set[str] = Localelator().get_all_countries()
LANGUAGE_ISOS: set[str] = Localelator().get_all_languages()
diff --git a/generalresearch/models/legacy/bucket.py b/generalresearch/models/legacy/bucket.py
index 2650b90..f20a769 100644
--- a/generalresearch/models/legacy/bucket.py
+++ b/generalresearch/models/legacy/bucket.py
@@ -4,7 +4,7 @@ import logging
import math
from datetime import timedelta
from decimal import Decimal
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import (
BaseModel,
@@ -16,13 +16,15 @@ from pydantic import (
)
from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- HttpsUrl,
- PropertyCode,
- UUIDStr,
-)
from generalresearch.models.thl.stats import StatisticalSummary
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ HttpsUrl,
+ PropertyCode,
+ UUIDStr,
+ )
+
logger = logging.getLogger()
Eligibility = Literal["conditional", "unconditional", "ineligible"]
diff --git a/generalresearch/models/legacy/offerwall.py b/generalresearch/models/legacy/offerwall.py
index da28663..c150dcb 100644
--- a/generalresearch/models/legacy/offerwall.py
+++ b/generalresearch/models/legacy/offerwall.py
@@ -1,27 +1,33 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.legacy.bucket import (
- BucketBase,
- MarketplaceBucket,
- OneShotOfferwallBucket,
- OneShotSoftPairOfferwallBucket,
- SingleEntryBucket,
- SoftPairBucket,
- TimeBucksBucket,
- TopNBucket,
- TopNPlusBucket,
- TopNPlusRecontactBucket,
- WXETOfferwallBucket,
-)
from generalresearch.models.legacy.definitions import OfferwallReason
from generalresearch.models.thl.payout_format import (
PayoutFormatField,
- PayoutFormatType,
)
-from generalresearch.models.thl.profiling.upk_question import UpkQuestion
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.legacy.bucket import (
+ BucketBase,
+ MarketplaceBucket,
+ OneShotOfferwallBucket,
+ OneShotSoftPairOfferwallBucket,
+ SingleEntryBucket,
+ SoftPairBucket,
+ TimeBucksBucket,
+ TopNBucket,
+ TopNPlusBucket,
+ TopNPlusRecontactBucket,
+ WXETOfferwallBucket,
+ )
+ from generalresearch.models.thl.payout_format import (
+ PayoutFormatType,
+ )
+ from generalresearch.models.thl.profiling.upk_question import UpkQuestion
"""
Not Done:
diff --git a/generalresearch/models/legacy/questions.py b/generalresearch/models/legacy/questions.py
index 9f37837..bebd28f 100644
--- a/generalresearch/models/legacy/questions.py
+++ b/generalresearch/models/legacy/questions.py
@@ -15,19 +15,19 @@ from pydantic import (
)
from sentry_sdk import capture_exception
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.legacy.api_status import StatusResponse
-from generalresearch.models.thl.profiling.upk_question import (
- UpkQuestionOut,
-)
-from generalresearch.models.thl.session import Wall
-from generalresearch.models.thl.user import User
if TYPE_CHECKING:
from generalresearch.managers.thl.user_manager.user_manager import (
UserManager,
)
from generalresearch.managers.thl.wall import WallManager
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.profiling.upk_question import (
+ UpkQuestionOut,
+ )
+ from generalresearch.models.thl.session import Wall
+ from generalresearch.models.thl.user import User
class UpkQuestionResponse(StatusResponse):
diff --git a/generalresearch/models/lucid/question.py b/generalresearch/models/lucid/question.py
index af3420e..98f535b 100644
--- a/generalresearch/models/lucid/question.py
+++ b/generalresearch/models/lucid/question.py
@@ -7,12 +7,12 @@ from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import BaseModel, Field, field_validator, model_validator
from generalresearch.models import Source
-from generalresearch.models.lucid import LucidQuestionIdType
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
)
if TYPE_CHECKING:
+ from generalresearch.models.lucid import LucidQuestionIdType
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/lucid/survey.py b/generalresearch/models/lucid/survey.py
index 4b1bb98..0f03e31 100644
--- a/generalresearch/models/lucid/survey.py
+++ b/generalresearch/models/lucid/survey.py
@@ -1,22 +1,24 @@
from __future__ import annotations
-from typing import Any, Self
+from typing import TYPE_CHECKING, Any, Self
from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt
from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- BigAutoInteger,
- CoercedStr,
- UUIDStr,
-)
-from generalresearch.models.thl.locales import CountryISO, LanguageISO
from generalresearch.models.thl.survey.condition import (
ConditionValueType,
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ BigAutoInteger,
+ CoercedStr,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.locales import CountryISO, LanguageISO
+
class LucidCondition(MarketplaceCondition):
model_config = ConfigDict(populate_by_name=True, frozen=False, extra="ignore")
diff --git a/generalresearch/models/morning/question.py b/generalresearch/models/morning/question.py
index b64a44a..748fcc6 100644
--- a/generalresearch/models/morning/question.py
+++ b/generalresearch/models/morning/question.py
@@ -1,18 +1,20 @@
import json
from enum import StrEnum
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from uuid import UUID
from pydantic import BaseModel, Field, field_validator, model_validator
from generalresearch.locales import Localelator
from generalresearch.models import Source
-from generalresearch.models.morning import MorningQuestionID
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
MarketplaceUserQuestionAnswer,
)
+if TYPE_CHECKING:
+ from generalresearch.models.morning import MorningQuestionID
+
# todo: we could validate that the country_iso / language_iso exists ...
locale_helper = Localelator()
diff --git a/generalresearch/models/morning/survey.py b/generalresearch/models/morning/survey.py
index 91d1bce..1e217f6 100644
--- a/generalresearch/models/morning/survey.py
+++ b/generalresearch/models/morning/survey.py
@@ -6,6 +6,7 @@ from datetime import UTC
from decimal import Decimal
from functools import cached_property
from typing import (
+ TYPE_CHECKING,
Annotated,
Any,
Literal,
@@ -25,24 +26,27 @@ from pydantic import (
from generalresearch.locales import Localelator
from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- UUIDStrCoerce,
-)
-from generalresearch.models.morning import MorningQuestionID, MorningStatus
-from generalresearch.models.morning.question import MorningQuestion
+from generalresearch.models.morning import MorningStatus
from generalresearch.models.thl.demographics import Gender
-from generalresearch.models.thl.locales import (
- CountryISO,
- CountryISOs,
- LanguageISOs,
-)
from generalresearch.models.thl.survey import MarketplaceTask
from generalresearch.models.thl.survey.condition import (
ConditionValueType,
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ UUIDStrCoerce,
+ )
+ from generalresearch.models.morning import MorningQuestionID
+ from generalresearch.models.morning.question import MorningQuestion
+ from generalresearch.models.thl.locales import (
+ CountryISO,
+ CountryISOs,
+ LanguageISOs,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/morning/task_collection.py b/generalresearch/models/morning/task_collection.py
index 9303a2f..1117937 100644
--- a/generalresearch/models/morning/task_collection.py
+++ b/generalresearch/models/morning/task_collection.py
@@ -1,16 +1,20 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models.morning import MorningStatus
-from generalresearch.models.morning.survey import MorningBid
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.morning.survey import MorningBid
+
COUNTRY_ISOS: set[str] = Localelator().get_all_countries()
LANGUAGE_ISOS: set[str] = Localelator().get_all_languages()
diff --git a/generalresearch/models/network/label.py b/generalresearch/models/network/label.py
index b8fe4b0..c27f36f 100644
--- a/generalresearch/models/network/label.py
+++ b/generalresearch/models/network/label.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import ipaddress
from enum import StrEnum
from ipaddress import IPv4Network, IPv6Network
+from typing import TYPE_CHECKING
from pydantic import (
BaseModel,
@@ -13,10 +14,10 @@ from pydantic import (
field_validator,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- now_utc_factory,
-)
+from generalresearch.models.custom_types import now_utc_factory
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
class IPTrustClass(StrEnum):
diff --git a/generalresearch/models/network/mtr/command.py b/generalresearch/models/network/mtr/command.py
index 220bfc7..7e74f20 100644
--- a/generalresearch/models/network/mtr/command.py
+++ b/generalresearch/models/network/mtr/command.py
@@ -5,9 +5,9 @@ from typing import TYPE_CHECKING
from generalresearch.models.network.definitions import IPProtocol
from generalresearch.models.network.mtr.parser import parse_mtr_output
-from generalresearch.models.network.mtr.result import MTRResult
if TYPE_CHECKING:
+ from generalresearch.models.network.mtr.result import MTRResult
from generalresearch.models.network.tool_run_command import MTRRunCommand
SUPPORTED_PROTOCOLS = {
diff --git a/generalresearch/models/network/mtr/execute.py b/generalresearch/models/network/mtr/execute.py
index c5b3c5c..1a7c963 100644
--- a/generalresearch/models/network/mtr/execute.py
+++ b/generalresearch/models/network/mtr/execute.py
@@ -1,21 +1,29 @@
from __future__ import annotations
from datetime import UTC, datetime
+from typing import TYPE_CHECKING
from uuid import uuid4
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.network.definitions import IPProtocol
from generalresearch.models.network.mtr.command import (
get_mtr_version,
run_mtr,
)
-from generalresearch.models.network.tool_run import MTRRun, Status, ToolClass, ToolName
+from generalresearch.models.network.tool_run import (
+ MTRRun,
+ Status,
+ ToolClass,
+ ToolName,
+)
from generalresearch.models.network.tool_run_command import (
MTRRunCommand,
MTRRunCommandOptions,
)
from generalresearch.models.network.utils import get_source_ip
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+
def execute_mtr(
ip: str,
diff --git a/generalresearch/models/network/mtr/parser.py b/generalresearch/models/network/mtr/parser.py
index c29439e..a0f8998 100644
--- a/generalresearch/models/network/mtr/parser.py
+++ b/generalresearch/models/network/mtr/parser.py
@@ -1,8 +1,11 @@
import json
+from typing import TYPE_CHECKING
-from generalresearch.models.network.definitions import IPProtocol
from generalresearch.models.network.mtr.result import MTRResult
+if TYPE_CHECKING:
+ from generalresearch.models.network.definitions import IPProtocol
+
def parse_mtr_output(raw: str, port: int, protocol: IPProtocol) -> MTRResult:
data = parse_mtr_raw_output(raw)
diff --git a/generalresearch/models/network/mtr/result.py b/generalresearch/models/network/mtr/result.py
index 34de845..d17136c 100644
--- a/generalresearch/models/network/mtr/result.py
+++ b/generalresearch/models/network/mtr/result.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import re
from functools import cached_property
from ipaddress import ip_address
+from typing import TYPE_CHECKING
import tldextract
from pydantic import (
@@ -14,7 +15,13 @@ from pydantic import (
model_validator,
)
-from generalresearch.models.network.definitions import IPKind, IPProtocol, get_ip_kind
+from generalresearch.models.network.definitions import (
+ IPProtocol,
+ get_ip_kind,
+)
+
+if TYPE_CHECKING:
+ from generalresearch.models.network.definitions import IPKind
HOST_RE = re.compile(r"^(?P<hostname>.+?) \((?P<ip>[^)]+)\)$")
diff --git a/generalresearch/models/network/nmap/command.py b/generalresearch/models/network/nmap/command.py
index 42b7178..3509b8d 100644
--- a/generalresearch/models/network/nmap/command.py
+++ b/generalresearch/models/network/nmap/command.py
@@ -4,9 +4,9 @@ import subprocess
from typing import TYPE_CHECKING
from generalresearch.models.network.nmap.parser import parse_nmap_xml
-from generalresearch.models.network.nmap.result import NmapResult
if TYPE_CHECKING:
+ from generalresearch.models.network.nmap.result import NmapResult
from generalresearch.models.network.tool_run_command import NmapRunCommand
diff --git a/generalresearch/models/network/nmap/execute.py b/generalresearch/models/network/nmap/execute.py
index 6c05c89..e3610d9 100644
--- a/generalresearch/models/network/nmap/execute.py
+++ b/generalresearch/models/network/nmap/execute.py
@@ -1,15 +1,23 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
from uuid import uuid4
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.network.nmap.command import run_nmap
-from generalresearch.models.network.tool_run import NmapRun, Status, ToolClass, ToolName
+from generalresearch.models.network.tool_run import (
+ NmapRun,
+ Status,
+ ToolClass,
+ ToolName,
+)
from generalresearch.models.network.tool_run_command import (
NmapRunCommand,
NmapRunCommandOptions,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+
def execute_nmap(
ip: str,
diff --git a/generalresearch/models/network/nmap/result.py b/generalresearch/models/network/nmap/result.py
index 4552e15..57c2e8b 100644
--- a/generalresearch/models/network/nmap/result.py
+++ b/generalresearch/models/network/nmap/result.py
@@ -4,13 +4,15 @@ import json
from datetime import timedelta
from enum import StrEnum
from functools import cached_property
-from typing import Any, Literal
+from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, computed_field
-from generalresearch.models.custom_types import AwareDatetimeISO, IPvAnyAddressStr
from generalresearch.models.network.definitions import IPProtocol
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, IPvAnyAddressStr
+
class PortState(StrEnum):
OPEN = "open"
diff --git a/generalresearch/models/network/rdns/command.py b/generalresearch/models/network/rdns/command.py
index c63d6d2..2250449 100644
--- a/generalresearch/models/network/rdns/command.py
+++ b/generalresearch/models/network/rdns/command.py
@@ -2,9 +2,9 @@ import subprocess
from typing import TYPE_CHECKING
from generalresearch.models.network.rdns.parser import parse_rdns_output
-from generalresearch.models.network.rdns.result import RDNSResult
if TYPE_CHECKING:
+ from generalresearch.models.network.rdns.result import RDNSResult
from generalresearch.models.network.tool_run_command import RDNSRunCommand
diff --git a/generalresearch/models/network/rdns/execute.py b/generalresearch/models/network/rdns/execute.py
index d6de84b..6c14f77 100644
--- a/generalresearch/models/network/rdns/execute.py
+++ b/generalresearch/models/network/rdns/execute.py
@@ -1,9 +1,9 @@
from __future__ import annotations
from datetime import UTC, datetime
+from typing import TYPE_CHECKING
from uuid import uuid4
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.network.rdns.command import (
get_dig_version,
run_rdns,
@@ -19,6 +19,9 @@ from generalresearch.models.network.tool_run_command import (
RDNSRunCommandOptions,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+
def execute_rdns(ip: str, scan_group_id: UUIDStr | None = None):
started_at = datetime.now(tz=UTC)
diff --git a/generalresearch/models/network/rdns/parser.py b/generalresearch/models/network/rdns/parser.py
index 31a5ed6..dc33997 100644
--- a/generalresearch/models/network/rdns/parser.py
+++ b/generalresearch/models/network/rdns/parser.py
@@ -1,9 +1,12 @@
import ipaddress
import re
+from typing import TYPE_CHECKING
-from generalresearch.models.custom_types import IPvAnyAddressStr
from generalresearch.models.network.rdns.result import RDNSResult
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import IPvAnyAddressStr
+
PTR_RE = re.compile(r"\sPTR\s+([^\s]+)\.")
diff --git a/generalresearch/models/network/rdns/result.py b/generalresearch/models/network/rdns/result.py
index 46af643..6845775 100644
--- a/generalresearch/models/network/rdns/result.py
+++ b/generalresearch/models/network/rdns/result.py
@@ -2,11 +2,13 @@ from __future__ import annotations
import json
from functools import cached_property
+from typing import TYPE_CHECKING
import tldextract
from pydantic import BaseModel, Field, computed_field, model_validator
-from generalresearch.models.custom_types import IPvAnyAddressStr
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import IPvAnyAddressStr
class RDNSResult(BaseModel):
diff --git a/generalresearch/models/network/tool_run.py b/generalresearch/models/network/tool_run.py
index c49ffc0..8479f15 100644
--- a/generalresearch/models/network/tool_run.py
+++ b/generalresearch/models/network/tool_run.py
@@ -1,25 +1,26 @@
from __future__ import annotations
from enum import StrEnum
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
from uuid import uuid4
from pydantic import BaseModel, Field, PositiveInt
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- IPvAnyAddressStr,
- UUIDStr,
-)
-from generalresearch.models.network.mtr.result import MTRResult
-from generalresearch.models.network.nmap.result import NmapResult
-from generalresearch.models.network.rdns.result import RDNSResult
-from generalresearch.models.network.tool_run_command import (
- MTRRunCommand,
- NmapRunCommand,
- RDNSRunCommand,
- ToolRunCommand,
-)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ IPvAnyAddressStr,
+ UUIDStr,
+ )
+ from generalresearch.models.network.mtr.result import MTRResult
+ from generalresearch.models.network.nmap.result import NmapResult
+ from generalresearch.models.network.rdns.result import RDNSResult
+ from generalresearch.models.network.tool_run_command import (
+ MTRRunCommand,
+ NmapRunCommand,
+ RDNSRunCommand,
+ ToolRunCommand,
+ )
class ToolClass(StrEnum):
diff --git a/generalresearch/models/network/tool_run_command.py b/generalresearch/models/network/tool_run_command.py
index 6f22d6b..b07b811 100644
--- a/generalresearch/models/network/tool_run_command.py
+++ b/generalresearch/models/network/tool_run_command.py
@@ -1,12 +1,14 @@
from __future__ import annotations
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
from pydantic import BaseModel, Field
-from generalresearch.models.custom_types import IPvAnyAddressStr
from generalresearch.models.network.definitions import IPProtocol
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import IPvAnyAddressStr
+
class ToolRunCommand(BaseModel):
command: str = Field()
diff --git a/generalresearch/models/precision/question.py b/generalresearch/models/precision/question.py
index f532998..ba17361 100644
--- a/generalresearch/models/precision/question.py
+++ b/generalresearch/models/precision/question.py
@@ -9,13 +9,13 @@ from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator
from generalresearch.models import Source, string_utils
-from generalresearch.models.precision import PrecisionQuestionID
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
MarketplaceUserQuestionAnswer,
)
if TYPE_CHECKING:
+ from generalresearch.models.precision import PrecisionQuestionID
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/precision/survey.py b/generalresearch/models/precision/survey.py
index bf9e83e..fa30882 100644
--- a/generalresearch/models/precision/survey.py
+++ b/generalresearch/models/precision/survey.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import json
from datetime import UTC
from functools import cached_property
-from typing import Annotated, Any, Literal, Self
+from typing import TYPE_CHECKING, Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
@@ -16,14 +16,7 @@ from pydantic import (
)
from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- DeviceTypes,
- UUIDStrCoerce,
-)
-from generalresearch.models.precision import PrecisionQuestionID, PrecisionStatus
+from generalresearch.models.precision import PrecisionStatus
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
from generalresearch.models.thl.survey.condition import (
@@ -31,6 +24,16 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ DeviceTypes,
+ UUIDStrCoerce,
+ )
+ from generalresearch.models.precision import PrecisionQuestionID
+
class PrecisionCondition(MarketplaceCondition):
question_id: PrecisionQuestionID | None = Field()
diff --git a/generalresearch/models/precision/task_collection.py b/generalresearch/models/precision/task_collection.py
index c8db2af..71241ad 100644
--- a/generalresearch/models/precision/task_collection.py
+++ b/generalresearch/models/precision/task_collection.py
@@ -1,16 +1,18 @@
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models.precision import PrecisionStatus
-from generalresearch.models.precision.survey import PrecisionSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.precision.survey import PrecisionSurvey
+
COUNTRY_ISOS = Localelator().get_all_countries()
LANGUAGE_ISOS = Localelator().get_all_languages()
diff --git a/generalresearch/models/prodege/question.py b/generalresearch/models/prodege/question.py
index 58aed67..c43b51a 100644
--- a/generalresearch/models/prodege/question.py
+++ b/generalresearch/models/prodege/question.py
@@ -19,11 +19,11 @@ from pydantic import (
from generalresearch.locales import Localelator
from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO
-from generalresearch.models.prodege import ProdegeQuestionIdType
from generalresearch.models.thl.profiling.marketplace import MarketplaceQuestion
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
+ from generalresearch.models.prodege import ProdegeQuestionIdType
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/prodege/survey.py b/generalresearch/models/prodege/survey.py
index 5d0369a..7e56a9c 100644
--- a/generalresearch/models/prodege/survey.py
+++ b/generalresearch/models/prodege/survey.py
@@ -7,7 +7,7 @@ from collections import defaultdict
from datetime import UTC, datetime
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal
+from typing import TYPE_CHECKING, Any, Literal
from pydantic import (
BaseModel,
@@ -21,18 +21,9 @@ from pydantic import (
from generalresearch.locales import Localelator
from generalresearch.models import LogicalOperator, Source, TaskCalculationType
-from generalresearch.models.custom_types import (
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- InclExcl,
- UUIDStr,
-)
from generalresearch.models.prodege import (
ProdegePastParticipationType,
- ProdegeQuestionIdType,
ProdegeStatus,
- ProdgeRedirectStatus,
)
from generalresearch.models.prodege.definitions import PG_COUNTRY_TO_ISO
from generalresearch.models.thl.demographics import Gender
@@ -42,6 +33,19 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ InclExcl,
+ UUIDStr,
+ )
+ from generalresearch.models.prodege import (
+ ProdegeQuestionIdType,
+ ProdgeRedirectStatus,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/prodege/task_collection.py b/generalresearch/models/prodege/task_collection.py
index 9f6a81b..774fc7b 100644
--- a/generalresearch/models/prodege/task_collection.py
+++ b/generalresearch/models/prodege/task_collection.py
@@ -1,16 +1,18 @@
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models.prodege import ProdegeStatus
-from generalresearch.models.prodege.survey import ProdegeSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.prodege.survey import ProdegeSurvey
+
COUNTRY_ISOS = Localelator().get_all_countries()
LANGUAGE_ISOS = Localelator().get_all_languages()
diff --git a/generalresearch/models/repdata/question.py b/generalresearch/models/repdata/question.py
index 4fa2d22..8cb1fa7 100644
--- a/generalresearch/models/repdata/question.py
+++ b/generalresearch/models/repdata/question.py
@@ -18,10 +18,10 @@ from pydantic import (
)
from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.profiling.marketplace import MarketplaceQuestion
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/repdata/survey.py b/generalresearch/models/repdata/survey.py
index c5b0730..cea61ed 100644
--- a/generalresearch/models/repdata/survey.py
+++ b/generalresearch/models/repdata/survey.py
@@ -6,7 +6,7 @@ import logging
from datetime import UTC, datetime
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from uuid import UUID
from pydantic import (
@@ -27,11 +27,6 @@ from generalresearch.models import (
Source,
TaskCalculationType,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CoercedStr,
- UUIDStr,
-)
from generalresearch.models.repdata import RepDataStatus
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
@@ -40,6 +35,13 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CoercedStr,
+ UUIDStr,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/repdata/task_collection.py b/generalresearch/models/repdata/task_collection.py
index 5b9a4ba..04d79bd 100644
--- a/generalresearch/models/repdata/task_collection.py
+++ b/generalresearch/models/repdata/task_collection.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
@@ -8,12 +8,14 @@ from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models import TaskCalculationType
from generalresearch.models.repdata import RepDataStatus
-from generalresearch.models.repdata.survey import RepDataSurveyHashed
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.repdata.survey import RepDataSurveyHashed
+
COUNTRY_ISOS = Localelator().get_all_countries()
LANGUAGE_ISOS = Localelator().get_all_languages()
diff --git a/generalresearch/models/sago/question.py b/generalresearch/models/sago/question.py
index 291214f..cf9ea19 100644
--- a/generalresearch/models/sago/question.py
+++ b/generalresearch/models/sago/question.py
@@ -19,10 +19,10 @@ from pydantic import (
)
from generalresearch.models import MAX_INT32, Source, string_utils
-from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.profiling.marketplace import MarketplaceQuestion
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/sago/survey.py b/generalresearch/models/sago/survey.py
index 8550cd3..c2f886a 100644
--- a/generalresearch/models/sago/survey.py
+++ b/generalresearch/models/sago/survey.py
@@ -5,7 +5,7 @@ import logging
from datetime import UTC
from decimal import Decimal
from functools import cached_property
-from typing import Annotated, Any, Literal, Self
+from typing import TYPE_CHECKING, Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
@@ -19,14 +19,6 @@ from pydantic import (
from generalresearch.locales import Localelator
from generalresearch.models import LogicalOperator, Source
-from generalresearch.models.custom_types import (
- AlphaNumStr,
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- DeviceTypes,
- IPLikeStrSet,
-)
from generalresearch.models.sago import SagoStatus
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
@@ -35,6 +27,16 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AlphaNumStr,
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ DeviceTypes,
+ IPLikeStrSet,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/sago/task_collection.py b/generalresearch/models/sago/task_collection.py
index 2879d9c..490f7a0 100644
--- a/generalresearch/models/sago/task_collection.py
+++ b/generalresearch/models/sago/task_collection.py
@@ -1,18 +1,20 @@
from __future__ import annotations
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models.sago import SagoStatus
-from generalresearch.models.sago.survey import SagoSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.sago.survey import SagoSurvey
+
COUNTRY_ISOS: set[str] = Localelator().get_all_countries()
LANGUAGE_ISOS: set[str] = Localelator().get_all_languages()
diff --git a/generalresearch/models/spectrum/question.py b/generalresearch/models/spectrum/question.py
index 7add692..89fbeb3 100644
--- a/generalresearch/models/spectrum/question.py
+++ b/generalresearch/models/spectrum/question.py
@@ -19,13 +19,13 @@ from pydantic import (
)
from generalresearch.models import MAX_INT32, Source, string_utils
-from generalresearch.models.custom_types import AwareDatetimeISO
-from generalresearch.models.spectrum import SpectrumQuestionIdType
from generalresearch.models.thl.profiling.marketplace import (
MarketplaceQuestion,
)
if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
+ from generalresearch.models.spectrum import SpectrumQuestionIdType
from generalresearch.models.thl.profiling.upk_question import (
UpkQuestion,
)
diff --git a/generalresearch/models/spectrum/survey.py b/generalresearch/models/spectrum/survey.py
index 424d206..4daa00b 100644
--- a/generalresearch/models/spectrum/survey.py
+++ b/generalresearch/models/spectrum/survey.py
@@ -4,20 +4,13 @@ import json
import logging
from datetime import UTC
from decimal import Decimal
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from more_itertools import flatten
from pydantic import BaseModel, ConfigDict, Field, computed_field, model_validator
from generalresearch.locales import Localelator
from generalresearch.models import Source, TaskCalculationType
-from generalresearch.models.custom_types import (
- AlphaNumStr,
- AlphaNumStrSet,
- AwareDatetimeISO,
- CoercedStr,
- UUIDStrSet,
-)
from generalresearch.models.spectrum import SpectrumStatus
from generalresearch.models.thl.demographics import Gender
from generalresearch.models.thl.survey import MarketplaceTask
@@ -26,6 +19,15 @@ from generalresearch.models.thl.survey.condition import (
MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AlphaNumStr,
+ AlphaNumStrSet,
+ AwareDatetimeISO,
+ CoercedStr,
+ UUIDStrSet,
+ )
+
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
diff --git a/generalresearch/models/spectrum/task_collection.py b/generalresearch/models/spectrum/task_collection.py
index 8ca5a93..d909292 100644
--- a/generalresearch/models/spectrum/task_collection.py
+++ b/generalresearch/models/spectrum/task_collection.py
@@ -1,17 +1,21 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
from generalresearch.locales import Localelator
from generalresearch.models import TaskCalculationType
from generalresearch.models.spectrum import SpectrumStatus
-from generalresearch.models.spectrum.survey import SpectrumSurvey
from generalresearch.models.thl.survey.task_collection import (
TaskCollection,
create_empty_df_from_schema,
)
+if TYPE_CHECKING:
+ from generalresearch.models.spectrum.survey import SpectrumSurvey
+
COUNTRY_ISOS: set[str] = Localelator().get_all_countries()
LANGUAGE_ISOS: set[str] = Localelator().get_all_languages()
diff --git a/generalresearch/models/thl/category.py b/generalresearch/models/thl/category.py
index ebfc840..32841a5 100644
--- a/generalresearch/models/thl/category.py
+++ b/generalresearch/models/thl/category.py
@@ -1,11 +1,12 @@
from __future__ import annotations
-from typing import Any, Self
+from typing import TYPE_CHECKING, Any, Self
from uuid import uuid4
from pydantic import BaseModel, Field, PositiveInt, model_validator
-from generalresearch.models.custom_types import UUIDStr
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
class Category(BaseModel, frozen=True):
diff --git a/generalresearch/models/thl/contest/__init__.py b/generalresearch/models/thl/contest/__init__.py
index 65b28f4..f243ce4 100644
--- a/generalresearch/models/thl/contest/__init__.py
+++ b/generalresearch/models/thl/contest/__init__.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import UTC, datetime
-from typing import Any, Self
+from typing import TYPE_CHECKING, Any, Self
from uuid import uuid4
from pydantic import (
@@ -12,10 +12,12 @@ from pydantic import (
model_validator,
)
-from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.contest.definitions import ContestPrizeKind
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.currency import USDCent
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.user import User
class ContestEntryRule(BaseModel):
diff --git a/generalresearch/models/thl/contest/contest.py b/generalresearch/models/thl/contest/contest.py
index 6fc60f6..173d486 100644
--- a/generalresearch/models/thl/contest/contest.py
+++ b/generalresearch/models/thl/contest/contest.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import json
from abc import ABC, abstractmethod
from datetime import UTC, datetime
-from typing import Any, Self
+from typing import TYPE_CHECKING, Any, Self
from uuid import uuid4
from pydantic import (
@@ -15,18 +15,22 @@ from pydantic import (
model_validator,
)
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.contest import (
ContestEndCondition,
ContestPrize,
- ContestWinner,
)
from generalresearch.models.thl.contest.definitions import (
ContestEndReason,
ContestStatus,
ContestType,
)
-from generalresearch.models.thl.locales import CountryISOs
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.contest import (
+ ContestWinner,
+ )
+ from generalresearch.models.thl.locales import CountryISOs
class ContestBase(BaseModel, ABC):
diff --git a/generalresearch/models/thl/contest/contest_entry.py b/generalresearch/models/thl/contest/contest_entry.py
index b5f0ac3..a57b2df 100644
--- a/generalresearch/models/thl/contest/contest_entry.py
+++ b/generalresearch/models/thl/contest/contest_entry.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import uuid4
from pydantic import (
@@ -12,9 +12,11 @@ from pydantic import (
)
from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.thl.contest.definitions import ContestEntryType
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.contest.definitions import ContestEntryType
+ from generalresearch.models.thl.user import User
class ContestEntryCreate(BaseModel):
diff --git a/generalresearch/models/thl/contest/leaderboard.py b/generalresearch/models/thl/contest/leaderboard.py
index 080f356..efbbd0a 100644
--- a/generalresearch/models/thl/contest/leaderboard.py
+++ b/generalresearch/models/thl/contest/leaderboard.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import UTC, datetime, timedelta
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import (
ConfigDict,
@@ -16,9 +16,6 @@ from generalresearch.currency import USDCent
from generalresearch.decorators import LOG
from generalresearch.managers.leaderboard import country_timezone
from generalresearch.managers.leaderboard.manager import LeaderboardManager
-from generalresearch.managers.thl.user_manager.user_manager import (
- UserManager,
-)
from generalresearch.models.thl.contest import (
ContestEndCondition,
ContestPrize,
@@ -42,6 +39,11 @@ from generalresearch.models.thl.leaderboard import (
LeaderboardFrequency,
)
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.user_manager.user_manager import (
+ UserManager,
+ )
+
class LeaderboardContestCreate(ContestBase):
model_config = ConfigDict(
diff --git a/generalresearch/models/thl/contest/milestone.py b/generalresearch/models/thl/contest/milestone.py
index db5ba2f..e2ff2bc 100644
--- a/generalresearch/models/thl/contest/milestone.py
+++ b/generalresearch/models/thl/contest/milestone.py
@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
from datetime import timedelta
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import (
BaseModel,
@@ -13,7 +13,6 @@ from pydantic import (
)
from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import AwareDatetimeISO
from generalresearch.models.thl.contest import (
ContestPrize,
)
@@ -32,6 +31,9 @@ from generalresearch.models.thl.contest.definitions import (
ContestType,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO
+
logging.basicConfig()
LOG = logging.getLogger()
LOG.setLevel(logging.INFO)
diff --git a/generalresearch/models/thl/contest/raffle.py b/generalresearch/models/thl/contest/raffle.py
index 14b3fb6..b944740 100644
--- a/generalresearch/models/thl/contest/raffle.py
+++ b/generalresearch/models/thl/contest/raffle.py
@@ -4,7 +4,7 @@ import logging
import random
from collections import defaultdict
from datetime import UTC, datetime
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import (
ConfigDict,
@@ -20,7 +20,6 @@ from generalresearch.models.thl.contest import (
ContestEndCondition,
ContestEntryRule,
ContestPrize,
- ContestWinner,
)
from generalresearch.models.thl.contest.contest import (
Contest,
@@ -28,7 +27,6 @@ from generalresearch.models.thl.contest.contest import (
ContestUserView,
)
from generalresearch.models.thl.contest.contest_entry import (
- ContestEntry,
ContestEntryType,
)
from generalresearch.models.thl.contest.definitions import (
@@ -38,6 +36,14 @@ from generalresearch.models.thl.contest.definitions import (
ContestType,
)
+if TYPE_CHECKING:
+ from generalresearch.models.thl.contest import (
+ ContestWinner,
+ )
+ from generalresearch.models.thl.contest.contest_entry import (
+ ContestEntry,
+ )
+
logging.basicConfig()
LOG = logging.getLogger()
LOG.setLevel(logging.INFO)
diff --git a/generalresearch/models/thl/demographics.py b/generalresearch/models/thl/demographics.py
index c11f8b2..ce4939c 100644
--- a/generalresearch/models/thl/demographics.py
+++ b/generalresearch/models/thl/demographics.py
@@ -8,9 +8,8 @@ from typing import TYPE_CHECKING, Any, Literal
import numpy as np
-from generalresearch.models.thl.locales import CountryISO
-
if TYPE_CHECKING:
+ from generalresearch.models.thl.locales import CountryISO
from generalresearch.models.thl.survey import MarketplaceTask
diff --git a/generalresearch/models/thl/finance.py b/generalresearch/models/thl/finance.py
index 79a74a7..4b750da 100644
--- a/generalresearch/models/thl/finance.py
+++ b/generalresearch/models/thl/finance.py
@@ -18,17 +18,17 @@ from pydantic import (
from pydantic.json_schema import SkipJsonSchema
from generalresearch.config import is_debug
-from generalresearch.currency import USDCent
from generalresearch.decorators import LOG
from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.definitions import SessionAdjustedStatus
-from generalresearch.pg_helper import PostgresConfig
payout_example = random.randint(150, 750 * 100)
adjustment_example = random.randint(-1_000, 50 * 100)
if TYPE_CHECKING:
+ from generalresearch.currency import USDCent
from generalresearch.models.thl.ledger import LedgerAccount
+ from generalresearch.pg_helper import PostgresConfig
class AdjustmentType(BaseModel):
diff --git a/generalresearch/models/thl/ipinfo.py b/generalresearch/models/thl/ipinfo.py
index 8fbae4c..8322c7d 100644
--- a/generalresearch/models/thl/ipinfo.py
+++ b/generalresearch/models/thl/ipinfo.py
@@ -15,14 +15,13 @@ from pydantic import (
field_validator,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- IPvAnyAddressStr,
-)
-
if TYPE_CHECKING:
from generalresearch.managers.thl.ipinfo import IPGeonameManager
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ IPvAnyAddressStr,
+ )
fake = Faker()
diff --git a/generalresearch/models/thl/leaderboard.py b/generalresearch/models/thl/leaderboard.py
index 4d116a5..3b33fe6 100644
--- a/generalresearch/models/thl/leaderboard.py
+++ b/generalresearch/models/thl/leaderboard.py
@@ -4,7 +4,7 @@ import logging
import math
from datetime import UTC, datetime, timedelta
from enum import StrEnum
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
from uuid import UUID, uuid3
from zoneinfo import ZoneInfo
@@ -21,9 +21,12 @@ from pydantic import (
from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.legacy.api_status import StatusResponse
-from generalresearch.models.thl.locales import CountryISO
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.models.thl.locales import CountryISO
+
+
logger = logging.getLogger()
diff --git a/generalresearch/models/thl/ledger.py b/generalresearch/models/thl/ledger.py
index 518e390..c38e83b 100644
--- a/generalresearch/models/thl/ledger.py
+++ b/generalresearch/models/thl/ledger.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import UTC, datetime
from enum import IntEnum, StrEnum
-from typing import Annotated, Any, Literal, Self
+from typing import TYPE_CHECKING, Annotated, Any, Literal, Self
from uuid import uuid4
from pydantic import (
@@ -16,12 +16,7 @@ from pydantic import (
model_validator,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- HttpsUrlStr,
- UUIDStr,
- check_valid_uuid,
-)
+from generalresearch.models.custom_types import check_valid_uuid
from generalresearch.models.thl.pagination import Page
from generalresearch.models.thl.payout_format import (
PayoutFormatType,
@@ -29,6 +24,16 @@ from generalresearch.models.thl.payout_format import (
)
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ HttpsUrlStr,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.payout_format import (
+ PayoutFormatType,
+ )
+
def _example_user_tx_payout(schema: dict[str, Any]) -> None:
diff --git a/generalresearch/models/thl/offerwall/base.py b/generalresearch/models/thl/offerwall/base.py
index 33b9847..1d41ef2 100644
--- a/generalresearch/models/thl/offerwall/base.py
+++ b/generalresearch/models/thl/offerwall/base.py
@@ -4,7 +4,7 @@ import statistics
from datetime import timedelta
from decimal import Decimal
from string import Formatter
-from typing import Annotated, Any, Self
+from typing import TYPE_CHECKING, Annotated, Any, Self
from uuid import uuid4
import numpy as np
@@ -20,31 +20,37 @@ from pydantic import (
)
from generalresearch.models import Source
-from generalresearch.models.custom_types import HttpsUrl, UUIDStr
from generalresearch.models.legacy.bucket import (
Bucket as LegacyBucket,
)
from generalresearch.models.legacy.bucket import (
- CategoryAssociation,
DurationSummary,
- Eligibility,
PayoutSummary,
PayoutSummaryDecimal,
- SurveyEligibilityCriterion,
)
from generalresearch.models.legacy.definitions import OfferwallReason
-from generalresearch.models.thl.locales import CountryISO
from generalresearch.models.thl.offerwall import (
OFFERWALL_TYPE_CLASS,
- OfferWallType,
- OfferWallTypeClass,
)
from generalresearch.models.thl.offerwall.bucket import (
generate_offerwall_entry_url,
)
-from generalresearch.models.thl.profiling.upk_question import UpkQuestion
from generalresearch.models.thl.soft_pair import SoftPairResultType
-from generalresearch.models.thl.user import User
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import HttpsUrl, UUIDStr
+ from generalresearch.models.legacy.bucket import (
+ CategoryAssociation,
+ Eligibility,
+ SurveyEligibilityCriterion,
+ )
+ from generalresearch.models.thl.locales import CountryISO
+ from generalresearch.models.thl.offerwall import (
+ OfferWallType,
+ OfferWallTypeClass,
+ )
+ from generalresearch.models.thl.profiling.upk_question import UpkQuestion
+ from generalresearch.models.thl.user import User
class MergeTableFeatures(BaseModel):
diff --git a/generalresearch/models/thl/offerwall/cache.py b/generalresearch/models/thl/offerwall/cache.py
index 97546b2..aa18014 100644
--- a/generalresearch/models/thl/offerwall/cache.py
+++ b/generalresearch/models/thl/offerwall/cache.py
@@ -1,18 +1,19 @@
from __future__ import annotations
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, Field
-from generalresearch.models import Source
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.thl.offerwall import OfferWallRequest
-from generalresearch.models.thl.offerwall.base import (
- OfferwallBase,
- ScoredTaskResult,
- TaskResult,
-)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.offerwall import OfferWallRequest
+ from generalresearch.models.thl.offerwall.base import (
+ OfferwallBase,
+ ScoredTaskResult,
+ TaskResult,
+ )
class GetOfferWallCache(BaseModel):
diff --git a/generalresearch/models/thl/payout.py b/generalresearch/models/thl/payout.py
index ce8a809..9902af3 100644
--- a/generalresearch/models/thl/payout.py
+++ b/generalresearch/models/thl/payout.py
@@ -2,7 +2,7 @@ from __future__ import annotations
import json
from datetime import UTC, datetime
-from typing import Self
+from typing import TYPE_CHECKING, Self
from uuid import uuid4
from pydantic import (
@@ -17,12 +17,18 @@ from pydantic import (
from pydantic.json_schema import SkipJsonSchema
from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr, UUIDStrCoerce
from generalresearch.models.thl.definitions import PayoutStatus
from generalresearch.models.thl.wallet import PayoutType
-from generalresearch.models.thl.wallet.cashout_method import (
- CashMailOrderData,
-)
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ UUIDStr,
+ UUIDStrCoerce,
+ )
+ from generalresearch.models.thl.wallet.cashout_method import (
+ CashMailOrderData,
+ )
class PayoutEvent(BaseModel):
@@ -59,9 +65,7 @@ class PayoutEvent(BaseModel):
examples=["a6dc1fc1bf934557b952f253dee12813"],
)
- created: AwareDatetimeISO = Field(
- default_factory=lambda: datetime.now(tz=UTC)
- )
+ created: AwareDatetimeISO = Field(default_factory=lambda: datetime.now(tz=UTC))
# In the smallest unit of the currency being transacted. For USD, this
# is cents.
@@ -233,9 +237,7 @@ class BusinessPayoutEventCreate(BaseModel):
examples=[uuid4().hex],
)
- created: AwareDatetimeISO = Field(
- default_factory=lambda: datetime.now(tz=UTC)
- )
+ created: AwareDatetimeISO = Field(default_factory=lambda: datetime.now(tz=UTC))
# In the smallest unit of the currency being transacted. For USD, this
# is cents.
@@ -351,5 +353,6 @@ class BusinessPayoutEventCreate(BaseModel):
)
return d
+
class BusinessPayoutEvent(BusinessPayoutEventCreate):
id: SkipJsonSchema[PositiveInt] = Field(exclude=True)
diff --git a/generalresearch/models/thl/product.py b/generalresearch/models/thl/product.py
index 83955a6..988b72d 100644
--- a/generalresearch/models/thl/product.py
+++ b/generalresearch/models/thl/product.py
@@ -45,7 +45,13 @@ from generalresearch.models.custom_types import (
HttpsUrlStr,
UUIDStr,
)
-from generalresearch.models.thl.ledger import LedgerAccount
+from generalresearch.models.thl.finance import (
+ POPFinancial,
+ ProductBalances,
+)
+from generalresearch.models.thl.payout import (
+ BrokerageProductPayoutEvent,
+)
from generalresearch.models.thl.payout_format import (
PayoutFormatType,
format_payout_format,
@@ -70,13 +76,7 @@ if TYPE_CHECKING:
from generalresearch.managers.thl.payout import (
BrokerageProductPayoutEventManager,
)
- from generalresearch.models.thl.finance import (
- POPFinancial,
- ProductBalances,
- )
- from generalresearch.models.thl.payout import (
- BrokerageProductPayoutEvent,
- )
+ from generalresearch.models.thl.ledger import LedgerAccount
# fmt: off
diff --git a/generalresearch/models/thl/profiling/marketplace.py b/generalresearch/models/thl/profiling/marketplace.py
index 0129e38..0c1e39b 100644
--- a/generalresearch/models/thl/profiling/marketplace.py
+++ b/generalresearch/models/thl/profiling/marketplace.py
@@ -3,18 +3,21 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from datetime import UTC, datetime
from functools import cached_property
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, ConfigDict, Field, PositiveInt, computed_field
-from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- LanguageISOLike,
- UUIDStr,
-)
-from generalresearch.models.thl.locales import CountryISO, LanguageISO
+from generalresearch.models import MAX_INT32
+
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ LanguageISOLike,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.locales import CountryISO, LanguageISO
class MarketplaceQuestion(BaseModel, ABC):
diff --git a/generalresearch/models/thl/profiling/question.py b/generalresearch/models/thl/profiling/question.py
index 3e2984a..920dd3a 100644
--- a/generalresearch/models/thl/profiling/question.py
+++ b/generalresearch/models/thl/profiling/question.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pydantic import (
BaseModel,
@@ -9,13 +9,14 @@ from pydantic import (
computed_field,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- LanguageISOLike,
- UUIDStr,
-)
-from generalresearch.models.thl.profiling.upk_question import UpkQuestion
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ LanguageISOLike,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.profiling.upk_question import UpkQuestion
class Question(BaseModel):
diff --git a/generalresearch/models/thl/profiling/upk_property.py b/generalresearch/models/thl/profiling/upk_property.py
index e46e00a..922f5a4 100644
--- a/generalresearch/models/thl/profiling/upk_property.py
+++ b/generalresearch/models/thl/profiling/upk_property.py
@@ -2,14 +2,17 @@ from __future__ import annotations
from enum import StrEnum
from functools import cached_property
+from typing import TYPE_CHECKING
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field, TypeAdapter
-from generalresearch.models.custom_types import CountryISOLike, UUIDStr
-from generalresearch.models.thl.category import Category
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import CountryISOLike, UUIDStr
+ from generalresearch.models.thl.category import Category
+
class PropertyType(StrEnum, metaclass=ReprEnumMeta):
# UserProfileKnowledge Item
diff --git a/generalresearch/models/thl/profiling/upk_question.py b/generalresearch/models/thl/profiling/upk_question.py
index 3bb0733..a73683c 100644
--- a/generalresearch/models/thl/profiling/upk_question.py
+++ b/generalresearch/models/thl/profiling/upk_question.py
@@ -5,7 +5,7 @@ import json
import re
from enum import StrEnum
from functools import cached_property
-from typing import Annotated, Any, Literal
+from typing import TYPE_CHECKING, Annotated, Any, Literal
from pydantic import (
BaseModel,
@@ -18,9 +18,11 @@ from pydantic import (
)
from generalresearch.models import Source
-from generalresearch.models.custom_types import UUIDStr
from generalresearch.models.thl.category import Category
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+
class UPKImportance(BaseModel):
task_count: int | None = Field(
diff --git a/generalresearch/models/thl/profiling/upk_question_answer.py b/generalresearch/models/thl/profiling/upk_question_answer.py
index d8323ad..41895b1 100644
--- a/generalresearch/models/thl/profiling/upk_question_answer.py
+++ b/generalresearch/models/thl/profiling/upk_question_answer.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import UTC, datetime
-from typing import Any, Self
+from typing import TYPE_CHECKING, Any, Self
from uuid import uuid4
from pydantic import (
@@ -14,16 +14,18 @@ from pydantic import (
)
from generalresearch.models import MAX_INT32
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- UUIDStr,
-)
from generalresearch.models.thl.profiling.upk_property import (
Cardinality,
PropertyType,
)
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ UUIDStr,
+ )
+
class UpkQuestionAnswer(BaseModel):
diff --git a/generalresearch/models/thl/profiling/user_info.py b/generalresearch/models/thl/profiling/user_info.py
index 32af704..c82e2d2 100644
--- a/generalresearch/models/thl/profiling/user_info.py
+++ b/generalresearch/models/thl/profiling/user_info.py
@@ -1,14 +1,17 @@
from __future__ import annotations
+from typing import TYPE_CHECKING
+
from pydantic import BaseModel, ConfigDict, Field
from pydantic.json_schema import SkipJsonSchema
-from generalresearch.models import Source
-from generalresearch.models.custom_types import AwareDatetimeISO
-from generalresearch.models.thl.profiling.user_question_answer import (
- MarketplaceResearchProfileQuestion,
-)
-from generalresearch.models.thl.user import User
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import AwareDatetimeISO
+ from generalresearch.models.thl.profiling.user_question_answer import (
+ MarketplaceResearchProfileQuestion,
+ )
+ from generalresearch.models.thl.user import User
class UserProfileKnowledgeAnswer(BaseModel):
diff --git a/generalresearch/models/thl/profiling/user_question_answer.py b/generalresearch/models/thl/profiling/user_question_answer.py
index 378345e..b1868b3 100644
--- a/generalresearch/models/thl/profiling/user_question_answer.py
+++ b/generalresearch/models/thl/profiling/user_question_answer.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import json
from collections.abc import Iterator
from datetime import UTC, datetime, timedelta
-from typing import Any, Literal
+from typing import TYPE_CHECKING, Any, Literal
from pydantic import (
BaseModel,
@@ -14,10 +14,13 @@ from pydantic import (
model_validator,
)
-from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.thl.locales import CountryISO, LanguageISO
-from generalresearch.models.thl.profiling.upk_question import UpkQuestion
+from generalresearch.models import MAX_INT32
+
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.locales import CountryISO, LanguageISO
+ from generalresearch.models.thl.profiling.upk_question import UpkQuestion
class UserQuestionAnswer(BaseModel):
diff --git a/generalresearch/models/thl/report_task.py b/generalresearch/models/thl/report_task.py
index 299ba90..e4a8f48 100644
--- a/generalresearch/models/thl/report_task.py
+++ b/generalresearch/models/thl/report_task.py
@@ -3,11 +3,14 @@ from __future__ import annotations
import random
from collections import defaultdict
from collections.abc import Collection
+from typing import TYPE_CHECKING
from pydantic import BaseModel, ConfigDict, Field
from generalresearch.models.thl.definitions import ReportValue
-from generalresearch.models.thl.user import BPUIDStr
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.user import BPUIDStr
# If a report is made with multiple values, we'll take the one with the
# highest priority
diff --git a/generalresearch/models/thl/session.py b/generalresearch/models/thl/session.py
index 31dc668..871e5c4 100644
--- a/generalresearch/models/thl/session.py
+++ b/generalresearch/models/thl/session.py
@@ -18,14 +18,7 @@ from pydantic import (
model_validator,
)
-from generalresearch.models import DeviceType, Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- EnumNameSerializer,
- IPvAnyAddressStr,
- UUIDStr,
-)
-from generalresearch.models.legacy.bucket import Bucket
+from generalresearch.models import Source
from generalresearch.models.thl import (
decimal_to_int_cents,
int_cents_to_decimal,
@@ -33,9 +26,7 @@ from generalresearch.models.thl import (
from generalresearch.models.thl.definitions import (
WALL_ALLOWED_STATUS_CODE_1_2,
WALL_ALLOWED_STATUS_STATUS_CODE,
- ReportValue,
SessionAdjustedStatus,
- SessionStatusCode2,
Status,
StatusCode1,
WallAdjustedStatus,
@@ -46,6 +37,18 @@ if TYPE_CHECKING:
from generalresearch.managers.thl.ledger_manager.thl_ledger import (
ThlLedgerManager,
)
+ from generalresearch.models import DeviceType
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ EnumNameSerializer,
+ IPvAnyAddressStr,
+ UUIDStr,
+ )
+ from generalresearch.models.legacy.bucket import Bucket
+ from generalresearch.models.thl.definitions import (
+ ReportValue,
+ SessionStatusCode2,
+ )
from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user import User
diff --git a/generalresearch/models/thl/soft_pair.py b/generalresearch/models/thl/soft_pair.py
index 7c2f36e..313d374 100644
--- a/generalresearch/models/thl/soft_pair.py
+++ b/generalresearch/models/thl/soft_pair.py
@@ -2,12 +2,14 @@ from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
+from typing import TYPE_CHECKING
-from generalresearch.models import Source
-from generalresearch.models.dynata.survey import DynataCondition
-from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
-)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.dynata.survey import DynataCondition
+ from generalresearch.models.thl.survey.condition import (
+ MarketplaceCondition,
+ )
class SoftPairResultType(int, Enum):
diff --git a/generalresearch/models/thl/survey/__init__.py b/generalresearch/models/thl/survey/__init__.py
index 6e6b475..d0f2b33 100644
--- a/generalresearch/models/thl/survey/__init__.py
+++ b/generalresearch/models/thl/survey/__init__.py
@@ -3,27 +3,32 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from decimal import Decimal
from itertools import product
+from typing import TYPE_CHECKING
from more_itertools import flatten
from pydantic import BaseModel, Field
-from generalresearch.models import Source
from generalresearch.models.thl.demographics import (
AgeGroup,
DemographicTarget,
Gender,
)
-from generalresearch.models.thl.locales import (
- CountryISO,
- CountryISOs,
- LanguageISO,
- LanguageISOs,
-)
from generalresearch.models.thl.survey.condition import (
ConditionValueType,
- MarketplaceCondition,
)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.thl.locales import (
+ CountryISO,
+ CountryISOs,
+ LanguageISO,
+ LanguageISOs,
+ )
+ from generalresearch.models.thl.survey.condition import (
+ MarketplaceCondition,
+ )
+
class MarketplaceTask(BaseModel, ABC):
"""This is called a "Task" even though generally it represents a survey
diff --git a/generalresearch/models/thl/survey/buyer.py b/generalresearch/models/thl/survey/buyer.py
index b888007..26846d3 100644
--- a/generalresearch/models/thl/survey/buyer.py
+++ b/generalresearch/models/thl/survey/buyer.py
@@ -3,7 +3,7 @@ from __future__ import annotations
from datetime import UTC, datetime
from decimal import Decimal
from math import log
-from typing import Annotated
+from typing import TYPE_CHECKING, Annotated
from pydantic import (
BaseModel,
@@ -17,11 +17,13 @@ from pydantic import (
from scipy.stats import beta as beta_dist
from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- UUIDStr,
-)
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ UUIDStr,
+ )
class Buyer(BaseModel):
diff --git a/generalresearch/models/thl/survey/model.py b/generalresearch/models/thl/survey/model.py
index 2eed8f7..9fa3d8e 100644
--- a/generalresearch/models/thl/survey/model.py
+++ b/generalresearch/models/thl/survey/model.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import UTC, datetime
from decimal import Decimal
-from typing import Annotated, Any
+from typing import TYPE_CHECKING, Annotated, Any
from pydantic import (
BaseModel,
@@ -17,18 +17,21 @@ from pydantic import (
)
from generalresearch.managers.thl.buyer import Buyer
-from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- EnumNameSerializer,
- PropertyCode,
- SurveyKey,
-)
-from generalresearch.models.thl.category import Category
-from generalresearch.models.thl.definitions import Status, StatusCode1
+from generalresearch.models.thl.definitions import StatusCode1
from generalresearch.models.thl.pagination import Page
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ EnumNameSerializer,
+ PropertyCode,
+ SurveyKey,
+ )
+ from generalresearch.models.thl.category import Category
+ from generalresearch.models.thl.definitions import Status
+
class SurveyCategoryModel(BaseModel):
model_config = ConfigDict(from_attributes=True)
diff --git a/generalresearch/models/thl/survey/penalty.py b/generalresearch/models/thl/survey/penalty.py
index 755d25c..54edb94 100644
--- a/generalresearch/models/thl/survey/penalty.py
+++ b/generalresearch/models/thl/survey/penalty.py
@@ -2,15 +2,16 @@ from __future__ import annotations
import abc
from datetime import UTC, datetime
-from typing import Annotated, Literal
+from typing import TYPE_CHECKING, Annotated, Literal
from pydantic import BaseModel, ConfigDict, Field, TypeAdapter
-from generalresearch.models import Source
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- UUIDStr,
-)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ UUIDStr,
+ )
class SurveyPenalty(BaseModel, abc.ABC):
diff --git a/generalresearch/models/thl/survey/task_collection.py b/generalresearch/models/thl/survey/task_collection.py
index d8db0d1..c9614d5 100644
--- a/generalresearch/models/thl/survey/task_collection.py
+++ b/generalresearch/models/thl/survey/task_collection.py
@@ -3,12 +3,14 @@ from __future__ import annotations
import copy
import json
import logging
+from typing import TYPE_CHECKING
import pandas as pd
import pandera.pandas as pa
from pydantic import BaseModel, ConfigDict, Field, model_validator
-from generalresearch.models.thl.survey import MarketplaceTask
+if TYPE_CHECKING:
+ from generalresearch.models.thl.survey import MarketplaceTask
logging.basicConfig()
logger = logging.getLogger()
diff --git a/generalresearch/models/thl/task_adjustment.py b/generalresearch/models/thl/task_adjustment.py
index 27c47d4..fa5592e 100644
--- a/generalresearch/models/thl/task_adjustment.py
+++ b/generalresearch/models/thl/task_adjustment.py
@@ -2,16 +2,20 @@ from __future__ import annotations
from datetime import UTC, datetime
from decimal import Decimal
+from typing import TYPE_CHECKING
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field, PositiveInt, model_validator
-from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+from generalresearch.models import MAX_INT32
from generalresearch.models.thl.definitions import (
WallAdjustedStatus,
)
+if TYPE_CHECKING:
+ from generalresearch.models import Source
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+
class TaskAdjustmentEvent(BaseModel):
"""
diff --git a/generalresearch/models/thl/task_status.py b/generalresearch/models/thl/task_status.py
index 7719b18..817f4c5 100644
--- a/generalresearch/models/thl/task_status.py
+++ b/generalresearch/models/thl/task_status.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import datetime
-from typing import Annotated, Any, Literal
+from typing import TYPE_CHECKING, Annotated, Any, Literal
from pydantic import (
BaseModel,
@@ -13,11 +13,6 @@ from pydantic import (
model_validator,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- EnumNameSerializer,
- UUIDStr,
-)
from generalresearch.models.thl import decimal_to_int_cents
from generalresearch.models.thl.definitions import (
SessionAdjustedStatus,
@@ -28,13 +23,23 @@ from generalresearch.models.thl.definitions import (
from generalresearch.models.thl.pagination import Page
from generalresearch.models.thl.payout_format import (
PayoutFormatOptionalField,
- PayoutFormatType,
-)
-from generalresearch.models.thl.product import (
- PayoutTransformation,
- Product,
)
-from generalresearch.models.thl.session import Session, WallOut
+from generalresearch.models.thl.session import WallOut
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ EnumNameSerializer,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.payout_format import (
+ PayoutFormatType,
+ )
+ from generalresearch.models.thl.product import (
+ PayoutTransformation,
+ Product,
+ )
+ from generalresearch.models.thl.session import Session
# API uses the ints, b/c this is what the grpc returned originally ...
STATUS_MAP = {
@@ -171,12 +176,12 @@ class TaskStatusResponse(BaseModel):
# Serialize enum → int
@field_serializer("status", return_type=int)
- def serialize_status(self, v: Status | None, _info):
+ def serialize_status(self, v: Status | None):
return STATUS_MAP[v]
# Accept int OR string for input, but internally store a Status enum
@field_validator("status", mode="before")
- def deserialize_status(cls, v):
+ def deserialize_status(cls, v: Status | None):
# int → enum
if isinstance(v, int):
return REVERSE_STATUS_MAP[v]
diff --git a/generalresearch/models/thl/user.py b/generalresearch/models/thl/user.py
index d3ffb0d..302aa72 100644
--- a/generalresearch/models/thl/user.py
+++ b/generalresearch/models/thl/user.py
@@ -21,18 +21,18 @@ from pydantic import (
from sentry_sdk import set_tag, set_user
from generalresearch.models import MAX_INT32
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.thl.ipinfo import GeoIPInformation
-from generalresearch.models.thl.ledger import LedgerTransaction
-from generalresearch.models.thl.product import Product
-from generalresearch.models.thl.userhealth import AuditLog
-from generalresearch.pg_helper import PostgresConfig
if TYPE_CHECKING:
from generalresearch.managers.thl.ledger_manager.thl_ledger import (
ThlLedgerManager,
)
from generalresearch.managers.thl.userhealth import AuditLogManager
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.ipinfo import GeoIPInformation
+ from generalresearch.models.thl.ledger import LedgerTransaction
+ from generalresearch.models.thl.product import Product
+ from generalresearch.models.thl.userhealth import AuditLog
+ from generalresearch.pg_helper import PostgresConfig
# from generalresearch.managers.thl.userhealth import UserIpHistoryManager
diff --git a/generalresearch/models/thl/user_iphistory.py b/generalresearch/models/thl/user_iphistory.py
index 812c18f..0d25322 100644
--- a/generalresearch/models/thl/user_iphistory.py
+++ b/generalresearch/models/thl/user_iphistory.py
@@ -5,7 +5,6 @@ from datetime import UTC, datetime, timedelta
from typing import TYPE_CHECKING, Self
from faker import Faker
-from grip_client.enums import AccessType
from pydantic import (
BaseModel,
ConfigDict,
@@ -14,18 +13,20 @@ from pydantic import (
field_validator,
)
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- CountryISOLike,
- IPvAnyAddressStr,
-)
from generalresearch.models.thl.ipinfo import normalize_ip
-from generalresearch.pg_helper import PostgresConfig
-from generalresearch.redis_helper import RedisConfig
if TYPE_CHECKING:
+ from grip_client.enums import AccessType
+
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ CountryISOLike,
+ IPvAnyAddressStr,
+ )
from generalresearch.models.thl.ipinfo import GeoIPInformation
from generalresearch.models.thl.user import User
+ from generalresearch.pg_helper import PostgresConfig
+ from generalresearch.redis_helper import RedisConfig
fake = Faker()
diff --git a/generalresearch/models/thl/user_profile.py b/generalresearch/models/thl/user_profile.py
index 0ec605a..2dc19b7 100644
--- a/generalresearch/models/thl/user_profile.py
+++ b/generalresearch/models/thl/user_profile.py
@@ -1,7 +1,7 @@
from __future__ import annotations
import hashlib
-from typing import Annotated, Any, Self
+from typing import TYPE_CHECKING, Annotated, Any, Self
from pydantic import (
BaseModel,
@@ -14,9 +14,11 @@ from pydantic import (
from pydantic.json_schema import SkipJsonSchema
from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import UUIDStr
-from generalresearch.models.thl.user import User
-from generalresearch.models.thl.user_streak import UserStreak
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import UUIDStr
+ from generalresearch.models.thl.user import User
+ from generalresearch.models.thl.user_streak import UserStreak
class UserMetadata(BaseModel):
diff --git a/generalresearch/models/thl/user_quality_event.py b/generalresearch/models/thl/user_quality_event.py
index cfb4ff3..5438740 100644
--- a/generalresearch/models/thl/user_quality_event.py
+++ b/generalresearch/models/thl/user_quality_event.py
@@ -3,16 +3,18 @@ from __future__ import annotations
from datetime import UTC, datetime
from decimal import Decimal
from enum import StrEnum
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
from pydantic import BaseModel, Field, PositiveInt
from generalresearch.models import MAX_INT32, Source
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-from generalresearch.models.thl.definitions import WallAdjustedStatus
-from generalresearch.models.thl.user import BPUIDStr
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.definitions import WallAdjustedStatus
+ from generalresearch.models.thl.user import BPUIDStr
+
"""
Typically used internally. These affect a user's quality standing.
"""
diff --git a/generalresearch/models/thl/user_streak.py b/generalresearch/models/thl/user_streak.py
index cc4d643..6cd853a 100644
--- a/generalresearch/models/thl/user_streak.py
+++ b/generalresearch/models/thl/user_streak.py
@@ -2,6 +2,7 @@ from __future__ import annotations
from datetime import date, datetime, timedelta
from enum import StrEnum
+from typing import TYPE_CHECKING
from zoneinfo import ZoneInfo
import pandas as pd
@@ -19,7 +20,9 @@ from pydantic.json_schema import SkipJsonSchema
from generalresearch.managers.leaderboard import country_timezone
from generalresearch.models import MAX_INT32
-from generalresearch.models.thl.locales import CountryISO
+
+if TYPE_CHECKING:
+ from generalresearch.models.thl.locales import CountryISO
class StreakPeriod(StrEnum):
diff --git a/generalresearch/models/thl/wallet/cashout_method.py b/generalresearch/models/thl/wallet/cashout_method.py
index 6158afd..1db85e8 100644
--- a/generalresearch/models/thl/wallet/cashout_method.py
+++ b/generalresearch/models/thl/wallet/cashout_method.py
@@ -4,7 +4,7 @@ import hashlib
import logging
from datetime import UTC, datetime
from enum import StrEnum
-from typing import Any, Literal, Self
+from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import (
BaseModel,
@@ -17,19 +17,22 @@ from pydantic import (
model_validator,
)
-from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import (
- AwareDatetimeISO,
- HttpsUrlStr,
- UUIDStr,
-)
from generalresearch.models.legacy.api_status import StatusResponse
from generalresearch.models.thl.definitions import PayoutStatus
-from generalresearch.models.thl.locales import CountryISO
-from generalresearch.models.thl.user import BPUIDStr, User
-from generalresearch.models.thl.wallet import Currency, PayoutType
+from generalresearch.models.thl.wallet import PayoutType
from generalresearch.utils.enum import ReprEnumMeta
+if TYPE_CHECKING:
+ from generalresearch.currency import USDCent
+ from generalresearch.models.custom_types import (
+ AwareDatetimeISO,
+ HttpsUrlStr,
+ UUIDStr,
+ )
+ from generalresearch.models.thl.locales import CountryISO
+ from generalresearch.models.thl.user import BPUIDStr, User
+ from generalresearch.models.thl.wallet import Currency
+
logger = logging.getLogger()
example_cashout_method = {
diff --git a/generalresearch/models/thl/wallet/payout.py b/generalresearch/models/thl/wallet/payout.py
index d43807d..7301b31 100644
--- a/generalresearch/models/thl/wallet/payout.py
+++ b/generalresearch/models/thl/wallet/payout.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import json
from collections.abc import Collection
from datetime import UTC, datetime
-from typing import Any
+from typing import TYPE_CHECKING, Any
from uuid import uuid4
from pydantic import (
@@ -15,12 +15,14 @@ from pydantic import (
)
from generalresearch.currency import USDCent
-from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
from generalresearch.models.thl.definitions import PayoutStatus
from generalresearch.models.thl.wallet import PayoutType
-from generalresearch.models.thl.wallet.cashout_method import (
- CashMailOrderData,
-)
+
+if TYPE_CHECKING:
+ from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
+ from generalresearch.models.thl.wallet.cashout_method import (
+ CashMailOrderData,
+ )
class PayoutEvent(BaseModel, validate_assignment=True):
diff --git a/generalresearch/models/thl/wallet/user_wallet.py b/generalresearch/models/thl/wallet/user_wallet.py
index dbe66fa..625fd52 100644
--- a/generalresearch/models/thl/wallet/user_wallet.py
+++ b/generalresearch/models/thl/wallet/user_wallet.py
@@ -1,15 +1,20 @@
from __future__ import annotations
import logging
+from typing import TYPE_CHECKING
from pydantic import BaseModel, ConfigDict, Field, NonNegativeInt
from generalresearch.models.legacy.api_status import StatusResponse
from generalresearch.models.thl.payout_format import (
PayoutFormatField,
- PayoutFormatType,
)
+if TYPE_CHECKING:
+ from generalresearch.models.thl.payout_format import (
+ PayoutFormatType,
+ )
+
logger = logging.getLogger()
example_wallet_balance = {
diff --git a/generalresearch/wall_status_codes/cint.py b/generalresearch/wall_status_codes/cint.py
index c31c0ba..13028dc 100644
--- a/generalresearch/wall_status_codes/cint.py
+++ b/generalresearch/wall_status_codes/cint.py
@@ -1,8 +1,10 @@
-from typing import Any
+from typing import TYPE_CHECKING, Any
-from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.wall_status_codes import lucid
+if TYPE_CHECKING:
+ from generalresearch.models.thl.definitions import Status, StatusCode1
+
def annotate_status_code(
ext_status_code_1: str,
diff --git a/test_utils/conftest.py b/test_utils/conftest.py
index 041caf2..f55fe11 100644
--- a/test_utils/conftest.py
+++ b/test_utils/conftest.py
@@ -180,7 +180,7 @@ def git_key_path(
yield Path(fn)
- # os.unlink(fn)
+ os.unlink(fn)
@pytest.fixture(scope="session")
diff --git a/test_utils/managers/gr/conftest.py b/test_utils/managers/gr/conftest.py
index 69f3e9a..40bd7b3 100644
--- a/test_utils/managers/gr/conftest.py
+++ b/test_utils/managers/gr/conftest.py
@@ -1,8 +1,11 @@
from __future__ import annotations
-from collections.abc import Callable
+import subprocess
+from collections.abc import Callable, Generator
+from random import randint
import pytest
+import redis
import redis.asyncio as redis_async
from pydantic import PostgresDsn
from redis import Redis
@@ -20,8 +23,15 @@ from generalresearch.redis_helper import RedisConfig
# === Msc ===
@pytest.fixture(scope="session")
+def gr_redis_config_db() -> str:
+ return str(randint(99, 1_023))
+
+
+@pytest.fixture(scope="session")
def gr_redis(settings: GRLBaseSettings) -> Redis:
- assert "unittest" in str(settings.gr_redis) or "127.0.0.1" in str(settings.gr_redis)
+ assert "unittest" in str(settings.testing_redis) or "127.0.0.1" in str(
+ settings.testing_redis
+ )
return Redis.from_url(
url=str(settings.gr_redis),
decode_responses=True,
@@ -32,10 +42,12 @@ def gr_redis(settings: GRLBaseSettings) -> Redis:
@pytest.fixture
def gr_redis_async(settings: GRLBaseSettings) -> redis_async.Redis:
- assert "unittest" in str(settings.gr_redis) or "127.0.0.1" in str(settings.gr_redis)
+ assert "unittest" in str(settings.testing_redis) or "127.0.0.1" in str(
+ settings.testing_redis
+ )
return redis_async.Redis.from_url(
- str(settings.gr_redis),
+ str(settings.testing_redis),
decode_responses=True,
socket_timeout=0.20,
socket_connect_timeout=0.20,
@@ -43,21 +55,39 @@ def gr_redis_async(settings: GRLBaseSettings) -> redis_async.Redis:
@pytest.fixture(scope="session")
-def gr_redis_config(settings: GRLBaseSettings) -> RedisConfig:
- assert "unittest" in str(settings.gr_redis) or "127.0.0.1" in str(settings.gr_redis)
+def gr_redis_config(
+ settings: GRLBaseSettings, gr_redis_config_db: str
+) -> Generator[RedisConfig]:
+ assert "unittest" in str(settings.testing_redis) or "127.0.0.1" in str(
+ settings.testing_redis
+ )
- return RedisConfig(
- dsn=settings.gr_redis,
+ uri = f"redis://{settings.testing_redis}/{gr_redis_config_db}"
+
+ res = subprocess.run(
+ ["redis-cli", "-u", uri, "SET", "jenkins_lock", "1", "NX", "EX", "3600"],
+ check=True,
+ text=True,
+ capture_output=True,
+ )
+
+ if res.stdout.strip() != "OK":
+ raise ValueError("Redis already locked... aborting.")
+
+ yield RedisConfig(
+ dsn=uri,
decode_responses=True,
socket_timeout=settings.redis_timeout,
socket_connect_timeout=settings.redis_timeout,
)
+ r = redis.from_url(uri)
+ r.flushdb()
+
@pytest.fixture(scope="session")
def gr_db(django_db_factory: Callable[..., PostgresDsn]) -> PostgresConfig:
_dsn = django_db_factory("gr.common")
- print("DDDD:", _dsn)
return PostgresConfig(
dsn=_dsn,
diff --git a/test_utils/models/conftest.py b/test_utils/models/conftest.py
index 5570b40..3a10ea3 100644
--- a/test_utils/models/conftest.py
+++ b/test_utils/models/conftest.py
@@ -22,12 +22,6 @@ from generalresearch.pg_helper import PostgresConfig
if TYPE_CHECKING:
from generalresearch.currency import USDCent
- from generalresearch.managers.gr.business import (
- BusinessAddressManager,
- BusinessBankAccountManager,
- BusinessManager,
- )
- from generalresearch.managers.gr.team import TeamManager
from generalresearch.managers.thl.buyer import BuyerManager
from generalresearch.managers.thl.ipinfo import (
IPGeonameManager,
@@ -45,8 +39,6 @@ if TYPE_CHECKING:
from generalresearch.managers.thl.wall import WallManager
from generalresearch.models.gr.business import (
Business,
- BusinessAddress,
- BusinessBankAccount,
)
from generalresearch.models.gr.team import Team
from generalresearch.models.thl.ipinfo import IPGeoname, IPInformation
@@ -407,35 +399,6 @@ def bp_payout_factory(
return _inner
-# === GR ===
-
-
-@pytest.fixture
-def business(request, business_manager: BusinessManager) -> Business:
- return business_manager.create_dummy()
-
-
-@pytest.fixture
-def business_address(
- request, business: Business, business_address_manager: BusinessAddressManager
-) -> BusinessAddress:
- return business_address_manager.create_dummy(business_id=business.id)
-
-
-@pytest.fixture
-def business_bank_account(
- request,
- business: Business,
- business_bank_account_manager: BusinessBankAccountManager,
-) -> BusinessBankAccount:
- return business_bank_account_manager.create_dummy(business_id=business.id)
-
-
-@pytest.fixture
-def team(request, team_manager: TeamManager) -> Team:
- return team_manager.create_dummy()
-
-
@pytest.fixture
def audit_log(audit_log_manager: AuditLogManager, user: User) -> AuditLog:
diff --git a/test_utils/models/gr/conftest.py b/test_utils/models/gr/conftest.py
index 90b86aa..b623255 100644
--- a/test_utils/models/gr/conftest.py
+++ b/test_utils/models/gr/conftest.py
@@ -1,6 +1,7 @@
from __future__ import annotations
from collections.abc import Callable
+from random import randint
from uuid import uuid4
import pytest
@@ -20,7 +21,6 @@ from generalresearch.models.gr.business import (
Business,
BusinessAddress,
BusinessBankAccount,
- BusinessType,
TransferMethod,
)
from generalresearch.models.gr.team import Membership, Team
@@ -134,27 +134,38 @@ def gr_business_address_factory(
@pytest.fixture
def gr_business_factory(
- gr_bm: BusinessManager,
+ gr_business_manager: BusinessManager,
) -> Callable[..., Business]:
def _inner(
- uuid: UUIDStr | None = None,
- name: str | None = None,
- team: Team | None = None,
- kind: BusinessType | None = None,
- tax_number: str | None = None,
+ save: bool = True, name: str | None = None, team: Team | None = None, **kwargs
) -> Business:
- from random import randint
+ name = name or f"<Unknown {uuid4().hex[:12]}>"
+ tax_number = str(randint(1, 999_999_999))
+
+ if save:
+ return gr_business_manager.create(
+ name=name,
+ kind="c",
+ uuid=uuid4().hex,
+ team=team,
+ tax_number=tax_number,
+ **kwargs,
+ )
+ else:
+ raise ValueError("Unsaved Business not supported yet")
- uuid = uuid or uuid4().hex
- name = name or "< Unknown >"
- tax_number = tax_number or str(randint(1, 999_999_999))
+ return _inner
- return gr_bm.create(
- uuid=uuid, name=name, team=team, kind=kind, tax_number=tax_number
- )
- return _inner
+@pytest.fixture
+def gr_business(gr_business_factory: Callable[..., Business]) -> Business:
+ return gr_business_factory(save=True)
+
+
+@pytest.fixture
+def unsaved_gr_business(gr_business_factory: Callable[..., Business]) -> Business:
+ return gr_business_factory(save=False)
@pytest.fixture
@@ -183,6 +194,21 @@ def gr_user_token(
return res
+@pytest.fixture
+def business_address(
+ gr_business: Business, business_address_manager: BusinessAddressManager
+) -> BusinessAddress:
+ return business_address_manager.create_dummy(business_id=gr_business.id)
+
+
+@pytest.fixture
+def business_bank_account(
+ gr_business: Business,
+ business_bank_account_manager: BusinessBankAccountManager,
+) -> BusinessBankAccount:
+ return business_bank_account_manager.create_dummy(business_id=gr_business.id)
+
+
@pytest.fixture()
def gr_user_token_header(gr_user_token: GRToken) -> dict[str, str]:
return gr_user_token.auth_header
diff --git a/tests/models/gr/test_business.py b/tests/models/gr/test_business.py
index f0107de..9310d2c 100644
--- a/tests/models/gr/test_business.py
+++ b/tests/models/gr/test_business.py
@@ -5,6 +5,7 @@ from collections.abc import Callable
from datetime import UTC, datetime, timedelta
from decimal import Decimal
from pathlib import Path
+from typing import TYPE_CHECKING
from uuid import uuid4
import pandas as pd
@@ -43,18 +44,22 @@ from generalresearch.models.thl.finance import (
BusinessBalances,
ProductBalances,
)
-from generalresearch.models.thl.product import BrokerageProductPayoutEvent, Product
-from generalresearch.models.thl.session import Session
+from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user import User
from generalresearch.pg_helper import PostgresConfig
from generalresearch.redis_helper import RedisConfig
+if TYPE_CHECKING:
+ from generalresearch.managers.thl.product import ProductManager
+ from generalresearch.models.thl.product import BrokerageProductPayoutEvent
+ from generalresearch.models.thl.session import Session
+
class TestBusinessBankAccount:
def test_init(
self,
- business: Business,
+ gr_business: Business,
business_bank_account_manager: BusinessBankAccountManager,
):
from generalresearch.models.gr.business import (
@@ -63,7 +68,7 @@ class TestBusinessBankAccount:
)
instance = business_bank_account_manager.create(
- business_id=business.id,
+ business_id=gr_business.id,
uuid=uuid4().hex,
transfer_method=TransferMethod.ACH,
)
@@ -72,7 +77,7 @@ class TestBusinessBankAccount:
def test_business(
self,
business_bank_account: BusinessBankAccount,
- business: Business,
+ gr_business: Business,
gr_db: PostgresConfig,
gr_redis_config: RedisConfig,
):
@@ -84,7 +89,7 @@ class TestBusinessBankAccount:
pg_config=gr_db, redis_config=gr_redis_config
)
assert isinstance(business_bank_account.business, Business)
- assert business_bank_account.business.uuid == business.uuid
+ assert business_bank_account.business.uuid == gr_business.uuid
class TestBusinessAddress:
@@ -122,11 +127,12 @@ class TestBusiness:
def test_str_and_repr(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
thl_web_rr: PostgresConfig,
ledger_manager: LedgerManager,
thl_ledger_manager: ThlLedgerManager,
+ product_manager: ProductManager,
business_payout_event_manager: BusinessPayoutEventManager,
bp_payout_factory: Callable[..., BusinessPayoutEventManager],
start: datetime,
@@ -139,28 +145,28 @@ class TestBusiness:
create_main_accounts: Callable[..., None],
):
create_main_accounts()
- p1 = product_factory(business=business)
+ p1 = product_factory(business=gr_business)
u1 = user_factory(product=p1)
- p2 = product_factory(business=business)
+ p2 = product_factory(business=gr_business)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p1)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p2)
- res1 = repr(business)
+ res1 = repr(gr_business)
- assert business.uuid in res1
+ assert gr_business.uuid in res1
assert "<Business: " in res1
- res2 = str(business)
+ res2 = str(gr_business)
- assert business.uuid in res2
+ assert gr_business.uuid in res2
assert "Name:" in res2
assert "Not Loaded" in res2
- business.prefetch_products(thl_pg_config=thl_web_rr)
- business.prefetch_bp_accounts(
- thl_lm=thl_ledger_manager, thl_pg_config=thl_web_rr
+ gr_business.prefetch_products(product_manager=product_manager)
+ gr_business.prefetch_bp_accounts(
+ thl_lm=thl_ledger_manager, product_manager=product_manager
)
- res3 = str(business)
+ res3 = str(gr_business)
assert "Products: 2" in res3
assert "Ledger Accounts: 2" in res3
@@ -184,26 +190,23 @@ class TestBusiness:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.prebuild_payouts(
- thl_pg_config=thl_web_rr,
- thl_lm=thl_ledger_manager,
+ gr_business.prebuild_payouts(
bpem=business_payout_event_manager,
)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
client=client_no_amm,
pop_ledger=pop_ledger_merge,
)
- res4 = str(business)
+ res4 = str(gr_business)
assert "Payouts: 1" in res4
assert "Available Balance: 141" in res4
def test_addresses(
self,
business: Business,
- business_address: BusinessAddress,
gr_db: PostgresConfig,
):
from generalresearch.models.gr.business import BusinessAddress
@@ -237,13 +240,13 @@ class TestBusiness:
self,
business: Business,
product_factory: Callable[..., Product],
- thl_web_rr: PostgresConfig,
+ product_manager: ProductManager,
):
p1 = product_factory(business=business)
assert business.products is None
- business.prefetch_products(thl_pg_config=thl_web_rr)
+ business.prefetch_products(product_manager=product_manager)
assert isinstance(business.products, list)
assert len(business.products) == 1
assert isinstance(business.products[0], Product)
@@ -255,30 +258,36 @@ class TestBusiness:
product_factory(business=business)
assert len(business.products) == 1
- business.prefetch_products(thl_pg_config=thl_web_rr)
+ business.prefetch_products(product_manager=product_manager)
assert len(business.products) == 3
- def test_bank_accounts(self, business: Business, gr_db: PostgresConfig):
- assert business.products is None
+ def test_bank_accounts(
+ self,
+ gr_business: Business,
+ business_bank_account_manager: BusinessBankAccountManager,
+ ):
+ assert gr_business.products is None
# It's an empty list after prefetch
- business.prefetch_bank_accounts(pg_config=gr_db)
- assert isinstance(business.bank_accounts, list)
- assert len(business.bank_accounts) == 1
+ gr_business.prefetch_bank_accounts(
+ business_bank_account_manager=business_bank_account_manager
+ )
+ assert isinstance(gr_business.bank_accounts, list)
+ assert len(gr_business.bank_accounts) == 1
def test_balance(
self,
- business: Business,
+ gr_business: Business,
mnt_filepath: GRLDatasets,
client_no_amm: DaskClient,
thl_web_rr: PostgresConfig,
ledger_manager: LedgerManager,
pop_ledger_merge: PopLedgerMerge,
):
- assert business.balance is None
+ assert gr_business.balance is None
with pytest.raises(expected_exception=AssertionError) as cm:
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -286,43 +295,41 @@ class TestBusiness:
pop_ledger=pop_ledger_merge,
)
assert "Cannot build Business Balance" in str(cm.value)
- assert business.balance is None
+ assert gr_business.balance is None
# TODO: Add parquet building so that this doesn't fail and we can
# properly assign a business.balance
def test_payouts_no_accounts(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
thl_web_rr: PostgresConfig,
thl_ledger_manager: ThlLedgerManager,
business_payout_event_manager: BusinessPayoutEventManager,
):
- assert business.payouts is None
+ assert gr_business.payouts is None
with pytest.raises(expected_exception=AssertionError) as cm:
- business.prebuild_payouts(
- thl_pg_config=thl_web_rr,
- thl_lm=thl_ledger_manager,
+ gr_business.prebuild_payouts(
bpem=business_payout_event_manager,
)
assert "Must provide product_uuids" in str(cm.value)
- p = product_factory(business=business)
+ p = product_factory(business=gr_business)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p)
- business.prebuild_payouts(
+ gr_business.prebuild_payouts(
thl_pg_config=thl_web_rr,
thl_lm=thl_ledger_manager,
bpem=business_payout_event_manager,
)
- assert isinstance(business.payouts, list)
- assert len(business.payouts) == 0
+ assert isinstance(gr_business.payouts, list)
+ assert len(gr_business.payouts) == 0
def test_payouts(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
bp_payout_factory: Callable[..., BrokerageProductPayoutEvent],
thl_ledger_manager: ThlLedgerManager,
@@ -331,7 +338,7 @@ class TestBusiness:
create_main_accounts: Callable[..., None],
):
create_main_accounts()
- p = product_factory(business=business)
+ p = product_factory(business=gr_business)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p)
business_payout_event_manager.set_account_lookup_table(
thl_lm=thl_ledger_manager
@@ -341,13 +348,13 @@ class TestBusiness:
product=p, amount=USDCent(123), skip_wallet_balance_check=True
)
- business.prebuild_payouts(
+ gr_business.prebuild_payouts(
thl_pg_config=thl_web_rr,
thl_lm=thl_ledger_manager,
bpem=business_payout_event_manager,
)
- assert len(business.payouts) == 1
- assert sum([p.amount for p in business.payouts]) == 123
+ assert len(gr_business.payouts) == 1
+ assert sum([p.amount for p in gr_business.payouts]) == 123
# Add another!
bp_payout_factory(
@@ -359,19 +366,17 @@ class TestBusiness:
business_payout_event_manager.set_account_lookup_table(
thl_lm=thl_ledger_manager
)
- business.prebuild_payouts(
- thl_pg_config=thl_web_rr,
- thl_lm=thl_ledger_manager,
+ gr_business.prebuild_payouts(
bpem=business_payout_event_manager,
)
- assert isinstance(business.payouts, list)
- assert len(business.payouts) == 1
- assert len(business.payouts[0].bp_payouts) == 2
- assert sum([p.amount for p in business.payouts]) == 246
+ assert isinstance(gr_business.payouts, list)
+ assert len(gr_business.payouts) == 1
+ assert len(gr_business.payouts[0].bp_payouts) == 2
+ assert sum([p.amount for p in gr_business.payouts]) == 246
def test_payouts_totals(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
bp_payout_factory: Callable[..., BrokerageProductPayoutEvent],
thl_ledger_manager: ThlLedgerManager,
@@ -382,7 +387,7 @@ class TestBusiness:
create_main_accounts()
- p1: Product = product_factory(business=business)
+ p1: Product = product_factory(business=gr_business)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p1)
business_payout_event_manager.set_account_lookup_table(
thl_lm=thl_ledger_manager
@@ -409,57 +414,58 @@ class TestBusiness:
skip_one_per_day_check=True,
)
- business.prebuild_payouts(
+ gr_business.prebuild_payouts(
thl_pg_config=thl_web_rr,
thl_lm=thl_ledger_manager,
bpem=business_payout_event_manager,
)
- assert isinstance(business.payouts, list)
- assert len(business.payouts) == 1
- assert len(business.payouts[0].bp_payouts) == 3
- assert business.payouts_total == USDCent(76)
- assert business.payouts_total_str == "$0.76"
+ assert isinstance(gr_business.payouts, list)
+ assert len(gr_business.payouts) == 1
+ assert len(gr_business.payouts[0].bp_payouts) == 3
+ assert gr_business.payouts_total == USDCent(76)
+ assert gr_business.payouts_total_str == "$0.76"
def test_pop_financial(
self,
- business: Business,
+ gr_business: Business,
thl_web_rr: PostgresConfig,
thl_ledger_manager: ThlLedgerManager,
mnt_filepath: GRLDatasets,
client_no_amm: DaskClient,
pop_ledger_merge: PopLedgerMerge,
):
- assert business.pop_financial is None
- business.prebuild_pop_financial(
+ assert gr_business.pop_financial is None
+ gr_business.prebuild_pop_financial(
thl_pg_config=thl_web_rr,
thl_lm=thl_ledger_manager,
ds=mnt_filepath,
client=client_no_amm,
pop_ledger=pop_ledger_merge,
)
- assert business.pop_financial == []
+ assert gr_business.pop_financial == []
def test_bp_accounts(
self,
- business: Business,
+ gr_business: Business,
thl_web_rr: PostgresConfig,
product_factory: Callable[..., Product],
thl_ledger_manager: ThlLedgerManager,
+ product_manager: ProductManager,
):
- assert business.bp_accounts is None
- business.prefetch_bp_accounts(
- thl_lm=thl_ledger_manager, thl_pg_config=thl_web_rr
+ assert gr_business.bp_accounts is None
+ gr_business.prefetch_bp_accounts(
+ thl_lm=thl_ledger_manager, product_manager=product_manager
)
- assert business.bp_accounts == []
+ assert gr_business.bp_accounts == []
- p1: Product = product_factory(business=business)
+ p1: Product = product_factory(business=gr_business)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p1)
- business.prefetch_bp_accounts(
- thl_lm=thl_ledger_manager, thl_pg_config=thl_web_rr
+ gr_business.prefetch_bp_accounts(
+ thl_lm=thl_ledger_manager, product_manager=product_manager
)
- assert len(business.bp_accounts) == 1
+ assert len(gr_business.bp_accounts) == 1
class TestBusinessBalance:
@@ -484,7 +490,7 @@ class TestBusinessBalance:
def test_single_product(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
user_factory: Callable[..., User],
mnt_filepath,
@@ -503,7 +509,7 @@ class TestBusinessBalance:
create_main_accounts()
delete_df_collection(coll=ledger_collection)
- p1: Product = product_factory(business=business)
+ p1: Product = product_factory(business=gr_business)
u1: User = user_factory(product=p1)
u2: User = user_factory(product=p1)
@@ -522,30 +528,30 @@ class TestBusinessBalance:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
client=client_no_amm,
pop_ledger=pop_ledger_merge,
)
- assert isinstance(business.balance, BusinessBalances)
- assert business.balance.payout == 190
- assert business.balance.adjustment == 0
- assert business.balance.net == 190
- assert business.balance.retainer == 47
- assert business.balance.available_balance == 143
+ assert isinstance(gr_business.balance, BusinessBalances)
+ assert gr_business.balance.payout == 190
+ assert gr_business.balance.adjustment == 0
+ assert gr_business.balance.net == 190
+ assert gr_business.balance.retainer == 47
+ assert gr_business.balance.available_balance == 143
- assert len(business.balance.product_balances) == 1
- pb = business.balance.product_balances[0]
+ assert len(gr_business.balance.product_balances) == 1
+ pb = gr_business.balance.product_balances[0]
assert isinstance(pb, ProductBalances)
- assert pb.balance == business.balance.balance
- assert pb.available_balance == business.balance.available_balance
+ assert pb.balance == gr_business.balance.balance
+ assert pb.available_balance == gr_business.balance.available_balance
assert pb.adjustment_percent == 0.0
def test_multi_product(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
user_factory: Callable[..., User],
mnt_filepath: GRLDatasets,
@@ -564,8 +570,8 @@ class TestBusinessBalance:
create_main_accounts()
delete_df_collection(coll=ledger_collection)
- u1: User = user_factory(product=product_factory(business=business))
- u2: User = user_factory(product=product_factory(business=business))
+ u1: User = user_factory(product=product_factory(business=gr_business))
+ u2: User = user_factory(product=product_factory(business=gr_business))
session_with_tx_factory(
user=u1,
@@ -582,33 +588,33 @@ class TestBusinessBalance:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
client=client_no_amm,
pop_ledger=pop_ledger_merge,
)
- assert isinstance(business.balance, BusinessBalances)
- assert business.balance.payout == 190
- assert business.balance.balance == 190
- assert business.balance.adjustment == 0
- assert business.balance.net == 190
- assert business.balance.retainer == 46
- assert business.balance.available_balance == 144
+ assert isinstance(gr_business.balance, BusinessBalances)
+ assert gr_business.balance.payout == 190
+ assert gr_business.balance.balance == 190
+ assert gr_business.balance.adjustment == 0
+ assert gr_business.balance.net == 190
+ assert gr_business.balance.retainer == 46
+ assert gr_business.balance.available_balance == 144
- assert len(business.balance.product_balances) == 2
+ assert len(gr_business.balance.product_balances) == 2
- pb1 = business.balance.product_balances[0]
- pb2 = business.balance.product_balances[1]
+ pb1 = gr_business.balance.product_balances[0]
+ pb2 = gr_business.balance.product_balances[1]
assert isinstance(pb1, ProductBalances)
assert pb1.product_id == u1.product_id
assert isinstance(pb2, ProductBalances)
assert pb2.product_id == u2.product_id
for pb in [pb1, pb2]:
- assert pb.balance != business.balance.balance
- assert pb.available_balance != business.balance.available_balance
+ assert pb.balance != gr_business.balance.balance
+ assert pb.available_balance != gr_business.balance.available_balance
assert pb.adjustment_percent == 0.0
assert pb1.product_id in [u1.product_id, u2.product_id]
@@ -629,7 +635,7 @@ class TestBusinessBalance:
def test_multi_product_multi_payout(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
user_factory: Callable[..., User],
mnt_filepath: GRLDatasets,
@@ -651,8 +657,8 @@ class TestBusinessBalance:
create_main_accounts()
delete_df_collection(coll=ledger_collection)
- u1: User = user_factory(product=product_factory(business=business))
- u2: User = user_factory(product=product_factory(business=business))
+ u1: User = user_factory(product=product_factory(business=gr_business))
+ u2: User = user_factory(product=product_factory(business=gr_business))
session_with_tx_factory(
user=u1,
@@ -687,7 +693,7 @@ class TestBusinessBalance:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -695,15 +701,15 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
)
- assert isinstance(business.balance, BusinessBalances)
- assert business.balance.payout == 190
- assert business.balance.net == 190
+ assert isinstance(gr_business.balance, BusinessBalances)
+ assert gr_business.balance.payout == 190
+ assert gr_business.balance.net == 190
- assert business.balance.balance == 135
+ assert gr_business.balance.balance == 135
def test_multi_product_multi_payout_adjustment(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
user_factory: Callable[..., User],
mnt_filepath: GRLDatasets,
@@ -744,9 +750,9 @@ class TestBusinessBalance:
delete_df_collection(coll=ledger_collection)
delete_df_collection(coll=task_adj_collection)
- u1: User = user_factory(product=product_factory(business=business))
- u2: User = user_factory(product=product_factory(business=business))
- u3: User = user_factory(product=product_factory(business=business))
+ u1: User = user_factory(product=product_factory(business=gr_business))
+ u2: User = user_factory(product=product_factory(business=gr_business))
+ u3: User = user_factory(product=product_factory(business=gr_business))
s1 = session_with_tx_factory(
user=u1,
@@ -799,7 +805,7 @@ class TestBusinessBalance:
df = client_no_amm.compute(pop_ledger_merge.ddf(), sync=True)
assert df.shape == (20, 28)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -807,26 +813,28 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
)
- assert isinstance(business.balance, BusinessBalances)
- assert business.balance.payout == 714
- assert business.balance.adjustment == -238
+ assert isinstance(gr_business.balance, BusinessBalances)
+ assert gr_business.balance.payout == 714
+ assert gr_business.balance.adjustment == -238
- assert business.balance.product_balances[0].adjustment == -238
- assert business.balance.product_balances[1].adjustment == 0
- assert business.balance.product_balances[2].adjustment == 0
+ assert gr_business.balance.product_balances[0].adjustment == -238
+ assert gr_business.balance.product_balances[1].adjustment == 0
+ assert gr_business.balance.product_balances[2].adjustment == 0
- assert business.balance.expense == 0
- assert business.balance.net == 714 - 238
- assert business.balance.balance == business.balance.payout - (250 + 50 + 238)
+ assert gr_business.balance.expense == 0
+ assert gr_business.balance.net == 714 - 238
+ assert gr_business.balance.balance == gr_business.balance.payout - (
+ 250 + 50 + 238
+ )
predicted_retainer = sum(
[
pb.balance * 0.25
- for pb in business.balance.product_balances
+ for pb in gr_business.balance.product_balances
if pb.balance > 0
]
)
- assert business.balance.retainer == approx(predicted_retainer, rel=0.01)
+ assert gr_business.balance.retainer == approx(predicted_retainer, rel=0.01)
def test_neg_balance_cache(
self,
@@ -837,7 +845,7 @@ class TestBusinessBalance:
create_main_accounts: Callable[..., None],
delete_df_collection: Callable[..., None],
ledger_collection,
- business: Business,
+ gr_business: Business,
user_factory: Callable[..., User],
product_factory: Callable[..., Product],
session_with_tx_factory: Callable[..., Session],
@@ -858,8 +866,8 @@ class TestBusinessBalance:
create_main_accounts()
delete_df_collection(coll=ledger_collection)
- p1: Product = product_factory(business=business)
- p2: Product = product_factory(business=business)
+ p1: Product = product_factory(business=gr_business)
+ p2: Product = product_factory(business=gr_business)
u1: User = user_factory(product=p1)
u2: User = user_factory(product=p2)
thl_ledger_manager.get_account_or_create_bp_wallet(product=p1)
@@ -901,7 +909,7 @@ class TestBusinessBalance:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -910,8 +918,8 @@ class TestBusinessBalance:
)
# Check Product 1
- assert isinstance(business.balance, BusinessBalances)
- pb1 = business.balance.product_balances[0]
+ assert isinstance(gr_business.balance, BusinessBalances)
+ pb1 = gr_business.balance.product_balances[0]
assert pb1.product_id == p1.uuid
assert pb1.payout == 71
assert pb1.adjustment == -71
@@ -921,7 +929,7 @@ class TestBusinessBalance:
assert pb1.available_balance == 0
# Check Product 2
- pb2 = business.balance.product_balances[1]
+ pb2 = gr_business.balance.product_balances[1]
assert pb2.product_id == p2.uuid
assert pb2.payout == 71 * 2
assert pb2.adjustment == 0
@@ -931,7 +939,7 @@ class TestBusinessBalance:
assert pb2.available_balance == 107
# Check Business
- bb1 = business.balance
+ bb1 = gr_business.balance
assert isinstance(bb1, BusinessBalances)
assert bb1.payout == (71 * 3) # Raw total of completes
assert bb1.adjustment == -71 # 1 Complete >> Failure
@@ -950,7 +958,7 @@ class TestBusinessBalance:
def test_multi_product_multi_payout_adjustment_at_timestamp(
self,
- business: Business,
+ gr_business: Business,
product_factory: Callable[..., Product],
user_factory: Callable[..., User],
mnt_filepath: GRLDatasets,
@@ -1008,9 +1016,9 @@ class TestBusinessBalance:
delete_df_collection(coll=ledger_collection)
delete_df_collection(coll=task_adj_collection)
- u1: User = user_factory(product=product_factory(business=business))
- u2: User = user_factory(product=product_factory(business=business))
- u3: User = user_factory(product=product_factory(business=business))
+ u1: User = user_factory(product=product_factory(business=gr_business))
+ u2: User = user_factory(product=product_factory(business=gr_business))
+ u3: User = user_factory(product=product_factory(business=gr_business))
s1 = session_with_tx_factory(
user=u1,
@@ -1063,7 +1071,7 @@ class TestBusinessBalance:
df = client_no_amm.compute(pop_ledger_merge.ddf(), sync=True)
assert df.shape == (20, 28)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1071,7 +1079,7 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
)
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1079,9 +1087,9 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=1, hours=1),
)
- day1_bal = business.balance
+ day1_bal = gr_business.balance
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1089,9 +1097,9 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=2, hours=1),
)
- day2_bal = business.balance
+ day2_bal = gr_business.balance
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1099,9 +1107,9 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=3, hours=1),
)
- day3_bal = business.balance
+ day3_bal = gr_business.balance
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1109,9 +1117,9 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=4, hours=1),
)
- day4_bal = business.balance
+ day4_bal = gr_business.balance
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1119,9 +1127,9 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=5, hours=1),
)
- day5_bal = business.balance
+ day5_bal = gr_business.balance
- business.prebuild_balance(
+ gr_business.prebuild_balance(
thl_pg_config=thl_web_rr,
lm=ledger_manager,
ds=mnt_filepath,
@@ -1129,7 +1137,7 @@ class TestBusinessBalance:
pop_ledger=pop_ledger_merge,
at_timestamp=start + timedelta(days=6, hours=1),
)
- day6_bal = business.balance
+ day6_bal = gr_business.balance
assert isinstance(day1_bal, BusinessBalances)
assert isinstance(day2_bal, BusinessBalances)
@@ -1187,7 +1195,7 @@ class TestBusinessMethods:
def test_set_cache(
self,
- business: Business,
+ gr_business: Business,
gr_redis: RedisConfig,
gr_db: PostgresConfig,
thl_web_rr: PostgresConfig,
@@ -1208,9 +1216,9 @@ class TestBusinessMethods:
gr_redis_config: RedisConfig,
mnt_gr_api_dir: Path,
):
- assert gr_redis.get(name=business.cache_key) is None
+ assert gr_redis.get(name=gr_business.cache_key) is None
- p1 = product_factory(team=team, business=business)
+ p1 = product_factory(team=team, business=gr_business)
u1 = user_factory(product=p1)
# Business needs tx & incite to build balance
@@ -1221,7 +1229,7 @@ class TestBusinessMethods:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.set_cache(
+ gr_business.set_cache(
pg_config=gr_db,
thl_web_rr=thl_web_rr,
redis_config=gr_redis_config,
@@ -1234,14 +1242,14 @@ class TestBusinessMethods:
mnt_gr_api=mnt_gr_api_dir,
)
- assert gr_redis.hgetall(name=business.cache_key) is not None
+ assert gr_redis.hgetall(name=gr_business.cache_key) is not None
from generalresearch.models.gr.business import Business
# We're going to pull only a specific year, but make sure that
# it's being assigned to the field regardless
year = datetime.now(tz=UTC).year
res = Business.from_redis(
- uuid=business.uuid,
+ uuid=gr_business.uuid,
fields=[f"pop_financial:{year}"],
gr_redis_config=gr_redis_config,
)
@@ -1249,7 +1257,7 @@ class TestBusinessMethods:
def test_set_cache_business(
self,
- business: Business,
+ gr_business: Business,
gr_db: PostgresConfig,
thl_web_rr: PostgresConfig,
product_factory: Callable[..., Product],
@@ -1272,9 +1280,9 @@ class TestBusinessMethods:
):
from generalresearch.models.gr.business import Business
- p1 = product_factory(team=team, business=business)
+ p1 = product_factory(team=team, business=gr_business)
u1 = user_factory(product=p1)
- team_manager.add_business(team=team, business=business)
+ team_manager.add_business(team=team, business=gr_business)
# Business needs tx & incite to build balance
delete_ledger_db()
@@ -1284,7 +1292,7 @@ class TestBusinessMethods:
ledger_collection.initial_load(client=None, sync=True)
pop_ledger_merge.build(client=client_no_amm, ledger_coll=ledger_collection)
- business.set_cache(
+ gr_business.set_cache(
pg_config=gr_db,
thl_web_rr=thl_web_rr,
redis_config=gr_redis_config,
@@ -1299,7 +1307,7 @@ class TestBusinessMethods:
# keys: List = Business.required_fields() + ["products", "bp_accounts"]
business2 = Business.from_redis(
- uuid=business.uuid,
+ uuid=gr_business.uuid,
fields=[
"id",
"tax_number",
@@ -1319,7 +1327,7 @@ class TestBusinessMethods:
)
assert isinstance(business2, Business)
- assert business.model_dump_json() == business2.model_dump_json()
+ assert gr_business.model_dump_json() == business2.model_dump_json()
# assert isinstance(business2.balance, BusinessBalances)
assert isinstance(business2.products, list)
assert isinstance(business2.teams, list)
@@ -1413,7 +1421,7 @@ class TestBusinessMethods:
session_factory: Callable[..., Session],
product_factory: Callable[..., Product],
delete_df_collection: Callable[..., None],
- business: Business,
+ gr_business: Business,
mnt_filepath: GRLDatasets,
mnt_gr_api_dir: Path,
):
@@ -1421,8 +1429,8 @@ class TestBusinessMethods:
delete_df_collection(coll=wall_collection)
delete_df_collection(coll=session_collection)
- p1 = product_factory(business=business)
- p2 = product_factory(business=business)
+ p1 = product_factory(business=gr_business)
+ p2 = product_factory(business=gr_business)
for p in [p1, p2]:
u = user_factory(product=p)
@@ -1443,7 +1451,7 @@ class TestBusinessMethods:
pg_config=thl_web_rr,
)
- business.prebuild_enriched_wall_parquet(
+ gr_business.prebuild_enriched_wall_parquet(
thl_pg_config=thl_web_rr,
ds=mnt_filepath,
client=client_no_amm,
@@ -1453,6 +1461,6 @@ class TestBusinessMethods:
# Now try to read from path
df = pd.read_parquet(
- os.path.join(mnt_gr_api_dir, "pop_event", f"{business.file_key}.parquet")
+ os.path.join(mnt_gr_api_dir, "pop_event", f"{gr_business.file_key}.parquet")
)
assert isinstance(df, pd.DataFrame)