aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generalresearch/currency.py4
-rw-r--r--generalresearch/grliq/managers/event_plotter.py1
-rw-r--r--generalresearch/grliq/managers/forensic_events.py34
-rw-r--r--generalresearch/grliq/managers/forensic_results.py4
-rw-r--r--generalresearch/grliq/managers/forensic_summary.py4
-rw-r--r--generalresearch/grliq/models/__init__.py4
-rw-r--r--generalresearch/grliq/models/decider.py8
-rw-r--r--generalresearch/grliq/models/events.py3
-rw-r--r--generalresearch/grliq/models/forensic_data.py13
-rw-r--r--generalresearch/grliq/models/forensic_result.py4
-rw-r--r--generalresearch/grliq/models/forensic_summary.py11
-rw-r--r--generalresearch/grliq/models/useragents.py12
-rw-r--r--generalresearch/incite/collections/__init__.py4
-rw-r--r--generalresearch/incite/mergers/__init__.py10
-rw-r--r--generalresearch/incite/mergers/ym_wall_summary.py2
-rw-r--r--generalresearch/incite/schemas/__init__.py2
-rw-r--r--generalresearch/incite/schemas/mergers/foundations/enriched_task_adjust.py2
-rw-r--r--generalresearch/locales/__init__.py1
-rw-r--r--generalresearch/managers/thl/wallet/__init__.py2
-rw-r--r--generalresearch/managers/thl/wallet/tango.py2
-rw-r--r--generalresearch/models/__init__.py16
-rw-r--r--generalresearch/models/cint/question.py6
-rw-r--r--generalresearch/models/cint/survey.py4
-rw-r--r--generalresearch/models/cint/task_collection.py2
-rw-r--r--generalresearch/models/dynata/__init__.py4
-rw-r--r--generalresearch/models/dynata/question.py4
-rw-r--r--generalresearch/models/dynata/survey.py4
-rw-r--r--generalresearch/models/events.py11
-rw-r--r--generalresearch/models/gr/business.py6
-rw-r--r--generalresearch/models/innovate/__init__.py8
-rw-r--r--generalresearch/models/innovate/question.py4
-rw-r--r--generalresearch/models/innovate/survey.py3
-rw-r--r--generalresearch/models/legacy/definitions.py4
-rw-r--r--generalresearch/models/lucid/question.py4
-rw-r--r--generalresearch/models/morning/__init__.py4
-rw-r--r--generalresearch/models/morning/question.py6
-rw-r--r--generalresearch/models/morning/survey.py8
-rw-r--r--generalresearch/models/network/nmap/result.py2
-rw-r--r--generalresearch/models/pollfish/question.py4
-rw-r--r--generalresearch/models/precision/__init__.py4
-rw-r--r--generalresearch/models/precision/question.py4
-rw-r--r--generalresearch/models/precision/survey.py4
-rw-r--r--generalresearch/models/precision/task_collection.py2
-rw-r--r--generalresearch/models/prodege/__init__.py6
-rw-r--r--generalresearch/models/prodege/question.py6
-rw-r--r--generalresearch/models/prodege/survey.py4
-rw-r--r--generalresearch/models/prodege/task_collection.py2
-rw-r--r--generalresearch/models/repdata/__init__.py4
-rw-r--r--generalresearch/models/repdata/question.py4
-rw-r--r--generalresearch/models/repdata/survey.py4
-rw-r--r--generalresearch/models/sago/__init__.py4
-rw-r--r--generalresearch/models/sago/question.py4
-rw-r--r--generalresearch/models/sago/survey.py4
-rw-r--r--generalresearch/models/spectrum/question.py8
-rw-r--r--generalresearch/models/spectrum/survey.py4
-rw-r--r--generalresearch/models/thl/contest/definitions.py16
-rw-r--r--generalresearch/models/thl/definitions.py22
-rw-r--r--generalresearch/models/thl/demographics.py4
-rw-r--r--generalresearch/models/thl/leaderboard.py8
-rw-r--r--generalresearch/models/thl/ledger.py14
-rw-r--r--generalresearch/models/thl/offerwall/__init__.py6
-rw-r--r--generalresearch/models/thl/product.py6
-rw-r--r--generalresearch/models/thl/profiling/upk_property.py6
-rw-r--r--generalresearch/models/thl/profiling/upk_question.py8
-rw-r--r--generalresearch/models/thl/supplier_tag.py4
-rw-r--r--generalresearch/models/thl/survey/__init__.py1
-rw-r--r--generalresearch/models/thl/user_quality_event.py6
-rw-r--r--generalresearch/models/thl/user_streak.py10
-rw-r--r--generalresearch/models/thl/userhealth.py4
-rw-r--r--generalresearch/models/thl/wallet/__init__.py6
-rw-r--r--generalresearch/models/thl/wallet/cashout_method.py19
-rw-r--r--generalresearch/utils/aggregation.py2
-rw-r--r--generalresearch/utils/enum.py1
-rw-r--r--generalresearch/wall_status_codes/__init__.py2
-rw-r--r--generalresearch/wall_status_codes/cint.py2
-rw-r--r--generalresearch/wall_status_codes/dynata.py2
-rw-r--r--generalresearch/wall_status_codes/fullcircle.py2
-rw-r--r--generalresearch/wall_status_codes/innovate.py2
-rw-r--r--generalresearch/wall_status_codes/lucid.py2
-rw-r--r--generalresearch/wall_status_codes/morning.py2
-rw-r--r--generalresearch/wall_status_codes/precision.py2
-rw-r--r--generalresearch/wall_status_codes/prodege.py2
-rw-r--r--generalresearch/wall_status_codes/repdata.py2
-rw-r--r--generalresearch/wall_status_codes/sago.py2
-rw-r--r--generalresearch/wall_status_codes/spectrum.py2
-rw-r--r--generalresearch/wall_status_codes/wxet.py1
-rw-r--r--generalresearch/wxet/models/definitions.py15
-rw-r--r--generalresearch/wxet/models/finish_type.py5
-rw-r--r--tests/incite/schemas/test_admin_responses.py3
89 files changed, 222 insertions, 268 deletions
diff --git a/generalresearch/currency.py b/generalresearch/currency.py
index c76b266..9402e04 100644
--- a/generalresearch/currency.py
+++ b/generalresearch/currency.py
@@ -1,6 +1,6 @@
import warnings
from decimal import Decimal
-from enum import Enum
+from enum import StrEnum
from typing import Any
from pydantic import GetCoreSchemaHandler, NonNegativeInt
@@ -9,7 +9,7 @@ from pydantic_core import CoreSchema, core_schema
from generalresearch.utils.enum import ReprEnumMeta
-class LedgerCurrency(str, Enum, metaclass=ReprEnumMeta):
+class LedgerCurrency(StrEnum, metaclass=ReprEnumMeta):
USD = "USD"
USDCent = "USDCent"
USDMill = "USDMill"
diff --git a/generalresearch/grliq/managers/event_plotter.py b/generalresearch/grliq/managers/event_plotter.py
index ed01d2e..0bba7c5 100644
--- a/generalresearch/grliq/managers/event_plotter.py
+++ b/generalresearch/grliq/managers/event_plotter.py
@@ -1,6 +1,5 @@
import html
import webbrowser
-from typing import List
import numpy as np
from more_itertools import windowed
diff --git a/generalresearch/grliq/managers/forensic_events.py b/generalresearch/grliq/managers/forensic_events.py
index 85e9620..c847d4d 100644
--- a/generalresearch/grliq/managers/forensic_events.py
+++ b/generalresearch/grliq/managers/forensic_events.py
@@ -1,7 +1,7 @@
import json
-from datetime import datetime
-from typing import Any, Dict, List, Optional
from collections.abc import Collection
+from datetime import datetime
+from typing import Any
from uuid import uuid4
from psycopg import sql
@@ -40,15 +40,13 @@ class GrlIqEventManager:
with conn.cursor() as c:
c.execute("SELECT pg_advisory_xact_lock(hashtext(%s))", (session_uuid,))
# Try to update first
- update_query = sql.SQL(
- """
+ update_query = sql.SQL("""
UPDATE grliq_forensicevents
SET timing_data = %(timing_data)s
WHERE session_uuid = %(session_uuid)s
AND timing_data IS NULL
RETURNING id
- """
- )
+ """)
c.execute(update_query, data)
result = c.fetchone()
@@ -58,15 +56,13 @@ class GrlIqEventManager:
return pk
# No matching row to update. Do an insert
- insert_query = sql.SQL(
- """
+ insert_query = sql.SQL("""
INSERT INTO grliq_forensicevents
(uuid, session_uuid, timing_data)
VALUES
(%(uuid)s, %(session_uuid)s, %(timing_data)s)
RETURNING id
- """
- )
+ """)
c.execute(insert_query, data)
pk = c.fetchone()["id"]
conn.commit()
@@ -96,8 +92,7 @@ class GrlIqEventManager:
with conn.cursor() as c:
c.execute("SELECT pg_advisory_xact_lock(hashtext(%s))", (session_uuid,))
# Try to update first
- update_query = sql.SQL(
- """
+ update_query = sql.SQL("""
UPDATE grliq_forensicevents
SET events = %(events)s,
mouse_events = %(mouse_events)s,
@@ -106,8 +101,7 @@ class GrlIqEventManager:
WHERE session_uuid = %(session_uuid)s
AND events IS NULL
RETURNING id
- """
- )
+ """)
c.execute(update_query, data)
result = c.fetchone()
@@ -117,8 +111,7 @@ class GrlIqEventManager:
return pk
# No matching row to update. Do an insert
- insert_query = sql.SQL(
- """
+ insert_query = sql.SQL("""
INSERT INTO grliq_forensicevents
(uuid, session_uuid, events, mouse_events,
event_start, event_end)
@@ -126,8 +119,7 @@ class GrlIqEventManager:
(%(uuid)s, %(session_uuid)s, %(events)s, %(mouse_events)s,
%(event_start)s, %(event_end)s)
RETURNING id
- """
- )
+ """)
c.execute(insert_query, data)
pk = c.fetchone()["id"]
conn.commit()
@@ -202,8 +194,7 @@ class GrlIqEventManager:
session_uuids: Collection[str],
) -> list[dict[str, Any]]:
params = {"session_uuids": list(session_uuids)}
- query = sql.SQL(
- """
+ query = sql.SQL("""
SELECT DISTINCT ON (fe.session_uuid)
timing_data,
fe.session_uuid,
@@ -214,8 +205,7 @@ class GrlIqEventManager:
WHERE fe.session_uuid = ANY(%(session_uuids)s)
AND timing_data IS NOT NULL
ORDER BY session_uuid, fe.id DESC;
- """
- )
+ """)
with self.postgres_config.make_connection() as conn:
with conn.cursor() as c:
c.execute(query, params)
diff --git a/generalresearch/grliq/managers/forensic_results.py b/generalresearch/grliq/managers/forensic_results.py
index 52bde99..706a7db 100644
--- a/generalresearch/grliq/managers/forensic_results.py
+++ b/generalresearch/grliq/managers/forensic_results.py
@@ -1,6 +1,6 @@
-from datetime import datetime
-from typing import Any, Dict, List, Optional, Tuple
from collections.abc import Collection
+from datetime import datetime
+from typing import Any
from generalresearch.grliq.models.forensic_result import (
GrlIqForensicCategoryResult,
diff --git a/generalresearch/grliq/managers/forensic_summary.py b/generalresearch/grliq/managers/forensic_summary.py
index 5039a38..98e00d8 100644
--- a/generalresearch/grliq/managers/forensic_summary.py
+++ b/generalresearch/grliq/managers/forensic_summary.py
@@ -2,8 +2,8 @@ from __future__ import annotations
import statistics
from collections import defaultdict
-from datetime import datetime, timedelta, timezone, UTC
-from typing import Any, Dict, List
+from datetime import UTC, datetime, timedelta
+from typing import Any
import numpy as np
diff --git a/generalresearch/grliq/models/__init__.py b/generalresearch/grliq/models/__init__.py
index 998de2d..fabbca2 100644
--- a/generalresearch/grliq/models/__init__.py
+++ b/generalresearch/grliq/models/__init__.py
@@ -1,10 +1,10 @@
from __future__ import annotations
import json
-from enum import Enum
+from enum import StrEnum
-class RiskWeighting(str, Enum):
+class RiskWeighting(StrEnum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
diff --git a/generalresearch/grliq/models/decider.py b/generalresearch/grliq/models/decider.py
index d24e150..579c39f 100644
--- a/generalresearch/grliq/models/decider.py
+++ b/generalresearch/grliq/models/decider.py
@@ -1,14 +1,14 @@
from __future__ import annotations
-from datetime import datetime, timezone, UTC
-from enum import Enum
+from datetime import UTC, datetime
+from enum import StrEnum
from pydantic import BaseModel, ConfigDict, Field
from generalresearch.models.custom_types import AwareDatetimeISO
-class Decider(str, Enum):
+class Decider(StrEnum):
# This decision was made in the thl-core: pre-offerwall-entry view
PRE_ENTRY = "pre_entry"
# This decision made by grl-iq (synchronously)
@@ -17,7 +17,7 @@ class Decider(str, Enum):
YM_USER = "ym_user"
-class AttemptDecision(str, Enum):
+class AttemptDecision(StrEnum):
# This attempt should be allowed to continue
PASS = "pass"
# This attempt is deemed fraudulent
diff --git a/generalresearch/grliq/models/events.py b/generalresearch/grliq/models/events.py
index 5daa032..69b67e5 100644
--- a/generalresearch/grliq/models/events.py
+++ b/generalresearch/grliq/models/events.py
@@ -3,7 +3,7 @@ from __future__ import annotations
from collections import namedtuple
from dataclasses import dataclass, fields
from functools import cached_property
-from typing import Any, Dict, List, Optional
+from typing import Any, Self
import numpy as np
from pydantic import (
@@ -14,7 +14,6 @@ from pydantic import (
NonNegativeInt,
PositiveFloat,
)
-from typing import Self
from generalresearch.models.custom_types import AwareDatetimeISO, IPvAnyAddressStr
diff --git a/generalresearch/grliq/models/forensic_data.py b/generalresearch/grliq/models/forensic_data.py
index eda7186..8d65696 100644
--- a/generalresearch/grliq/models/forensic_data.py
+++ b/generalresearch/grliq/models/forensic_data.py
@@ -3,10 +3,10 @@ from __future__ import annotations
import hashlib
import re
from collections import Counter
-from datetime import datetime, timedelta, timezone, UTC
-from enum import Enum
+from datetime import UTC, datetime, timedelta
+from enum import StrEnum
from functools import cached_property
-from typing import Any, Literal
+from typing import Annotated, Any, Literal, Self
from uuid import uuid4
import pycountry
@@ -23,7 +23,6 @@ from pydantic import (
)
from pydantic.json_schema import SkipJsonSchema
from pydantic_extra_types.timezone_name import TimeZoneName
-from typing import Annotated, Self
from generalresearch.grliq.models import (
AUDIO_CODEC_NAMES,
@@ -60,7 +59,7 @@ from generalresearch.models.thl.session import Session
fake = Faker()
-class Platform(str, Enum):
+class Platform(StrEnum):
MAC_INTEL = "MacIntel"
ARM = "ARM"
IPAD = "iPad"
@@ -75,7 +74,7 @@ class Platform(str, Enum):
OTHER = "Other"
-class PassFailError(str, Enum):
+class PassFailError(StrEnum):
PASS = "pass"
FAIL = "fail"
ERROR = "error"
@@ -96,7 +95,7 @@ class PassFailError(str, Enum):
return {2: cls.PASS, 1: cls.FAIL, 0: cls.ERROR, -1: cls.ERROR}[int(v)]
-class SupportLevel(str, Enum):
+class SupportLevel(StrEnum):
# Used for checking if certain features are available in the browser
FULL = "full"
PARTIAL = "partial"
diff --git a/generalresearch/grliq/models/forensic_result.py b/generalresearch/grliq/models/forensic_result.py
index 3fe6481..1fd99cc 100644
--- a/generalresearch/grliq/models/forensic_result.py
+++ b/generalresearch/grliq/models/forensic_result.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from enum import Enum
+from enum import StrEnum
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field, computed_field
@@ -14,7 +14,7 @@ from generalresearch.grliq.models.decider import (
from generalresearch.models.custom_types import AwareDatetimeISO, UUIDStr
-class Phase(str, Enum):
+class Phase(StrEnum):
# The 'phase' of a THL-Session experience. grliq may be collected in
# multiple places multiple times within one session
diff --git a/generalresearch/grliq/models/forensic_summary.py b/generalresearch/grliq/models/forensic_summary.py
index 5ecf1a4..6f80768 100644
--- a/generalresearch/grliq/models/forensic_summary.py
+++ b/generalresearch/grliq/models/forensic_summary.py
@@ -2,13 +2,12 @@ from __future__ import annotations
import random
from typing import (
- List,
Literal,
+ Optional,
Union,
get_args,
get_origin,
get_type_hints,
- Optional,
)
import numpy as np
@@ -57,9 +56,7 @@ class UserForensicSummary(BaseModel):
)
# These must be nullable in case a user has 0 attempts!
- category_result_summary: GrlIqForensicCategorySummary | None= Field(
- default=None
- )
+ category_result_summary: GrlIqForensicCategorySummary | None = Field(default=None)
checker_result_summary: GrlIqCheckerResultsSummary | None = Field(default=None)
country_timing_data_summary: dict[CountryISO, TimingDataCountrySummary] = Field(
@@ -211,13 +208,13 @@ class CountryRTTDistribution(BaseModel):
description="Country client_ip is located in", examples=["fr"]
)
# For users marked as fraud or not
- is_fraud: bool| None = Field(
+ is_fraud: bool | None = Field(
default=None,
description="If timing data from sessions determined to be fraud are included",
)
# we could split by this optionally
- user_type: UserType|None = Field(
+ user_type: UserType | None = Field(
default=None,
description="user_type of the client_ip as determined by MaxMind",
examples=[UserType.RESIDENTIAL],
diff --git a/generalresearch/grliq/models/useragents.py b/generalresearch/grliq/models/useragents.py
index 4bb340e..de63a67 100644
--- a/generalresearch/grliq/models/useragents.py
+++ b/generalresearch/grliq/models/useragents.py
@@ -1,15 +1,15 @@
from __future__ import annotations
import hashlib
-from enum import Enum
+from enum import StrEnum
+from typing import Self
from pydantic import BaseModel, ConfigDict, Field, field_validator
-from typing import Self
from user_agents import parse as ua_parse
from user_agents.parsers import UserAgent
-class BrowserFamily(str, Enum):
+class BrowserFamily(StrEnum):
CHROME_MOBILE = "Chrome Mobile"
CHROME = "Chrome"
CHROME_MOBILE_WEBVIEW = "Chrome Mobile WebView"
@@ -32,7 +32,7 @@ class BrowserFamily(str, Enum):
OTHER = "Other"
-class OSFamily(str, Enum):
+class OSFamily(StrEnum):
ANDROID = "Android"
WINDOWS = "Windows"
IOS = "iOS"
@@ -43,7 +43,7 @@ class OSFamily(str, Enum):
OTHER = "Other"
-class DeviceBrand(str, Enum):
+class DeviceBrand(StrEnum):
GENERIC_ANDROID = "Generic_Android"
NONE = "None"
APPLE = "Apple"
@@ -65,7 +65,7 @@ class DeviceBrand(str, Enum):
OTHER = "Other"
-class DeviceModelFamily(str, Enum):
+class DeviceModelFamily(StrEnum):
NONE = "None"
OTHER = "Other"
K = "K"
diff --git a/generalresearch/incite/collections/__init__.py b/generalresearch/incite/collections/__init__.py
index 17c119a..38749b3 100644
--- a/generalresearch/incite/collections/__init__.py
+++ b/generalresearch/incite/collections/__init__.py
@@ -5,7 +5,7 @@ import os
import subprocess
import time
from datetime import datetime
-from enum import Enum
+from enum import StrEnum
from sys import platform
from typing import Any
@@ -56,7 +56,7 @@ LOG = logging.getLogger("incite")
DT_STR = "%Y-%m-%d %H:%M:%S"
-class DFCollectionType(str, Enum):
+class DFCollectionType(StrEnum):
TEST = "test"
USER = "thl_user"
diff --git a/generalresearch/incite/mergers/__init__.py b/generalresearch/incite/mergers/__init__.py
index 9c5276c..45d3e2d 100644
--- a/generalresearch/incite/mergers/__init__.py
+++ b/generalresearch/incite/mergers/__init__.py
@@ -1,17 +1,16 @@
import logging
import os.path
import subprocess
-from datetime import datetime, timezone, UTC
-from enum import Enum
+from datetime import UTC, datetime
+from enum import StrEnum
from sys import platform
-from typing import List, Optional, Type
+from typing import Self
import dask.dataframe as dd
import pandas as pd
from dask.distributed import Client
from pandera.pandas import DataFrameSchema
from pydantic import Field, ValidationInfo, field_validator, model_validator
-from typing import Self
from generalresearch.incite.base import CollectionBase, CollectionItemBase
from generalresearch.incite.schemas import PARTITION_ON
@@ -27,7 +26,6 @@ from generalresearch.incite.schemas.mergers.foundations.enriched_wall import (
from generalresearch.incite.schemas.mergers.foundations.user_id_product import (
UserIdProductSchema,
)
-
from generalresearch.incite.schemas.mergers.pop_ledger import (
PopLedgerSchema,
)
@@ -42,7 +40,7 @@ from generalresearch.models.custom_types import AwareDatetimeISO
LOG = logging.getLogger("incite")
-class MergeType(str, Enum):
+class MergeType(StrEnum):
TEST = "test"
YM_SURVEY_WALL = "ym_survey_wall"
YM_WALL_SUMMARY = "ym_wall_summary"
diff --git a/generalresearch/incite/mergers/ym_wall_summary.py b/generalresearch/incite/mergers/ym_wall_summary.py
index 4816c05..618b810 100644
--- a/generalresearch/incite/mergers/ym_wall_summary.py
+++ b/generalresearch/incite/mergers/ym_wall_summary.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from datetime import datetime, time, timedelta
-from typing import Literal, Type
+from typing import Literal
import dask.dataframe as dd
import pandas as pd
diff --git a/generalresearch/incite/schemas/__init__.py b/generalresearch/incite/schemas/__init__.py
index 6fc83b0..9d24f17 100644
--- a/generalresearch/incite/schemas/__init__.py
+++ b/generalresearch/incite/schemas/__init__.py
@@ -1,5 +1,3 @@
-from typing import List
-
import pandas as pd
import pandera.pandas as pa
diff --git a/generalresearch/incite/schemas/mergers/foundations/enriched_task_adjust.py b/generalresearch/incite/schemas/mergers/foundations/enriched_task_adjust.py
index 97e73a3..ead42d9 100644
--- a/generalresearch/incite/schemas/mergers/foundations/enriched_task_adjust.py
+++ b/generalresearch/incite/schemas/mergers/foundations/enriched_task_adjust.py
@@ -1,5 +1,3 @@
-from typing import Set
-
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
diff --git a/generalresearch/locales/__init__.py b/generalresearch/locales/__init__.py
index 813966e..38c1832 100644
--- a/generalresearch/locales/__init__.py
+++ b/generalresearch/locales/__init__.py
@@ -12,7 +12,6 @@ https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
import json
import pkgutil
-from typing import Set
class Localelator:
diff --git a/generalresearch/managers/thl/wallet/__init__.py b/generalresearch/managers/thl/wallet/__init__.py
index 9f3ae85..05e700d 100644
--- a/generalresearch/managers/thl/wallet/__init__.py
+++ b/generalresearch/managers/thl/wallet/__init__.py
@@ -1,5 +1,5 @@
from decimal import Decimal
-from typing import Any, Dict, Optional, Union
+from typing import Any
from generalresearch.managers.thl.ledger_manager.thl_ledger import (
ThlLedgerManager,
diff --git a/generalresearch/managers/thl/wallet/tango.py b/generalresearch/managers/thl/wallet/tango.py
index 445719d..a4ebf22 100644
--- a/generalresearch/managers/thl/wallet/tango.py
+++ b/generalresearch/managers/thl/wallet/tango.py
@@ -1,4 +1,4 @@
-from typing import Any, Dict
+from typing import Any
from generalresearch.config import (
is_debug,
diff --git a/generalresearch/models/__init__.py b/generalresearch/models/__init__.py
index 9a2bb9c..c0348d7 100644
--- a/generalresearch/models/__init__.py
+++ b/generalresearch/models/__init__.py
@@ -1,11 +1,11 @@
from __future__ import annotations
-from enum import Enum
+from enum import IntEnum, StrEnum
from generalresearch.utils.enum import ReprEnumMeta
-class Source(str, Enum, metaclass=ReprEnumMeta):
+class Source(StrEnum, metaclass=ReprEnumMeta):
# The external marketplace, or the source of the survey / work.
# Max length of the value is 2.
GRS = "g"
@@ -31,7 +31,7 @@ class Source(str, Enum, metaclass=ReprEnumMeta):
WXET = "w"
-class DebitKey(int, Enum, metaclass=ReprEnumMeta):
+class DebitKey(IntEnum, metaclass=ReprEnumMeta):
# The debit key for marketplaces
CINT = 8
DALIA = 9
@@ -50,21 +50,21 @@ class DebitKey(int, Enum, metaclass=ReprEnumMeta):
# WXET = None
-class DeviceType(int, Enum, metaclass=ReprEnumMeta):
+class DeviceType(IntEnum, metaclass=ReprEnumMeta):
UNKNOWN = 0
MOBILE = 1
DESKTOP = 2
TABLET = 3
-class LogicalOperator(str, Enum, metaclass=ReprEnumMeta):
+class LogicalOperator(StrEnum, metaclass=ReprEnumMeta):
OR = "OR"
AND = "AND"
# There is currently no use case for NOT. See MarketplaceCondition.explain_not
NOT = "NOT"
-class TaskStatus(str, Enum, metaclass=ReprEnumMeta):
+class TaskStatus(StrEnum, metaclass=ReprEnumMeta):
# A survey is live if it is open and, given all conditions are met, is
# possible to send in traffic. All other statuses are just variants of
# NOT Live (not accepting traffic)
@@ -80,7 +80,7 @@ class TaskStatus(str, Enum, metaclass=ReprEnumMeta):
NOT_FOUND = "NOT_FOUND"
-class TaskCalculationType(str, Enum):
+class TaskCalculationType(StrEnum):
COMPLETES = "COMPLETES"
STARTS = "STARTS"
@@ -105,7 +105,7 @@ class TaskCalculationType(str, Enum):
return {0: cls.COMPLETES, 1: cls.STARTS}[v]
-class URLQueryKey(str, Enum, metaclass=ReprEnumMeta):
+class URLQueryKey(StrEnum, metaclass=ReprEnumMeta):
PRODUCT_ID = "39057c8b"
PRODUCT_USER_ID = "c184efc0"
SESSION_ID = "0bb50182"
diff --git a/generalresearch/models/cint/question.py b/generalresearch/models/cint/question.py
index 5959141..f8a287a 100644
--- a/generalresearch/models/cint/question.py
+++ b/generalresearch/models/cint/question.py
@@ -1,8 +1,8 @@
from __future__ import annotations
import json
-from datetime import UTC, datetime, timezone
-from enum import Enum
+from datetime import UTC, datetime
+from enum import StrEnum
from typing import TYPE_CHECKING, Any, Literal, Self
from uuid import UUID
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
)
-class CintQuestionType(str, Enum):
+class CintQuestionType(StrEnum):
SINGLE_SELECT = "s"
MULTI_SELECT = "m"
# Dummy means they're calculated
diff --git a/generalresearch/models/cint/survey.py b/generalresearch/models/cint/survey.py
index 01615f6..cfc91ef 100644
--- a/generalresearch/models/cint/survey.py
+++ b/generalresearch/models/cint/survey.py
@@ -2,9 +2,9 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, datetime, timezone
+from datetime import UTC, datetime
from decimal import Decimal
-from typing import Annotated, Any, Literal, Self, Type
+from typing import Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
diff --git a/generalresearch/models/cint/task_collection.py b/generalresearch/models/cint/task_collection.py
index efb6e95..4ae8de4 100644
--- a/generalresearch/models/cint/task_collection.py
+++ b/generalresearch/models/cint/task_collection.py
@@ -1,7 +1,5 @@
from __future__ import annotations
-from typing import List
-
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
diff --git a/generalresearch/models/dynata/__init__.py b/generalresearch/models/dynata/__init__.py
index c6d3a67..0f3dfe7 100644
--- a/generalresearch/models/dynata/__init__.py
+++ b/generalresearch/models/dynata/__init__.py
@@ -1,7 +1,7 @@
-from enum import Enum
+from enum import StrEnum
-class DynataStatus(str, Enum):
+class DynataStatus(StrEnum):
OPEN = "OPEN"
PAUSED = "PAUSED"
CLOSED = "CLOSED"
diff --git a/generalresearch/models/dynata/question.py b/generalresearch/models/dynata/question.py
index 7288588..b95f7c6 100644
--- a/generalresearch/models/dynata/question.py
+++ b/generalresearch/models/dynata/question.py
@@ -5,7 +5,7 @@ import json
import logging
import re
from datetime import timedelta
-from enum import Enum
+from enum import StrEnum
from functools import cached_property
from typing import Any, Literal
@@ -51,7 +51,7 @@ class DynataQuestionOption(BaseModel):
return clean_text(s)
-class DynataQuestionType(str, Enum):
+class DynataQuestionType(StrEnum):
"""
From the API: {'geo', 'multi_select', 'multi_select_searchable', 'none',
'single_select', 'single_select_grid', 'single_select_searchable', 'zip'}
diff --git a/generalresearch/models/dynata/survey.py b/generalresearch/models/dynata/survey.py
index 097eea2..9adac42 100644
--- a/generalresearch/models/dynata/survey.py
+++ b/generalresearch/models/dynata/survey.py
@@ -2,10 +2,10 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, timezone
+from datetime import UTC
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal, Self, Type
+from typing import Any, Literal, Self
from more_itertools import flatten
from pydantic import (
diff --git a/generalresearch/models/events.py b/generalresearch/models/events.py
index 5efd4f6..70f699b 100644
--- a/generalresearch/models/events.py
+++ b/generalresearch/models/events.py
@@ -1,6 +1,6 @@
-from datetime import UTC, datetime, timedelta, timezone
+from datetime import UTC, datetime, timedelta
from enum import StrEnum
-from typing import Annotated, Dict, Literal, Optional, Union
+from typing import Annotated, Literal
from uuid import uuid4
from pydantic import (
@@ -263,17 +263,14 @@ class SubscribeMessage(BaseModel):
product_id: UUIDStr = Field(examples=["4fe381fb7186416cb443a38fa66c6557"])
-ServerToClientMessage = Union[EventMessage, StatsMessage, PingMessage]
+ServerToClientMessage = EventMessage | StatsMessage | PingMessage
ServerToClientMessageField = Annotated[
ServerToClientMessage,
Field(discriminator="kind"),
]
ServerToClientMessageAdapter = TypeAdapter(ServerToClientMessageField)
-ClientToServerMessage = Union[
- SubscribeMessage,
- PongMessage,
-]
+ClientToServerMessage = SubscribeMessage | PongMessage
ClientToServerMessageField = Annotated[
ClientToServerMessage,
Field(discriminator="kind"),
diff --git a/generalresearch/models/gr/business.py b/generalresearch/models/gr/business.py
index a67cf48..534b23f 100644
--- a/generalresearch/models/gr/business.py
+++ b/generalresearch/models/gr/business.py
@@ -3,8 +3,8 @@ from __future__ import annotations
import json
import logging
import os
-from datetime import UTC, datetime, timezone
-from enum import Enum
+from datetime import UTC, datetime
+from enum import Enum, StrEnum
from pathlib import Path
from typing import TYPE_CHECKING, Self
from uuid import uuid4
@@ -63,7 +63,7 @@ class TransferMethod(Enum, metaclass=ReprEnumMeta):
WIRE = 1
-class BusinessType(str, Enum, metaclass=ReprEnumMeta):
+class BusinessType(StrEnum, metaclass=ReprEnumMeta):
INDIVIDUAL = "i"
COMPANY = "c"
diff --git a/generalresearch/models/innovate/__init__.py b/generalresearch/models/innovate/__init__.py
index 26946e9..9d7ea75 100644
--- a/generalresearch/models/innovate/__init__.py
+++ b/generalresearch/models/innovate/__init__.py
@@ -1,4 +1,4 @@
-from enum import Enum
+from enum import StrEnum
from typing import Annotated
from pydantic import StringConstraints
@@ -9,17 +9,17 @@ InnovateQuestionID = Annotated[
]
-class InnovateStatus(str, Enum):
+class InnovateStatus(StrEnum):
LIVE = "LIVE"
NOT_LIVE = "NOT_LIVE"
-class InnovateQuotaStatus(str, Enum):
+class InnovateQuotaStatus(StrEnum):
OPEN = "OPEN"
CLOSED = "CLOSED"
-class InnovateDuplicateCheckLevel(str, Enum):
+class InnovateDuplicateCheckLevel(StrEnum):
# How we should check for de-dupes / survey exclusions.
# https://innovatemr.stoplight.io/docs/supplier-api/ZG9jOjEzNzYxMTg2-statuses-term-reasons-and-categories
# #duplicatedtoken
diff --git a/generalresearch/models/innovate/question.py b/generalresearch/models/innovate/question.py
index 306274f..89310a2 100644
--- a/generalresearch/models/innovate/question.py
+++ b/generalresearch/models/innovate/question.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import json
import logging
-from enum import Enum
+from enum import StrEnum
from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, field_validator, model_validator
@@ -50,7 +50,7 @@ class InnovateQuestionOption(BaseModel):
order: int = Field()
-class InnovateQuestionType(str, Enum):
+class InnovateQuestionType(StrEnum):
# API response: {'Multipunch', 'Numeric Open Ended', 'Single Punch'}
# "Numeric Open Ended" must be wrong... It can't be numeric, as UK's
# postcode question is marked as this, but it wants alphanumeric
diff --git a/generalresearch/models/innovate/survey.py b/generalresearch/models/innovate/survey.py
index 0359bd6..3c37fe3 100644
--- a/generalresearch/models/innovate/survey.py
+++ b/generalresearch/models/innovate/survey.py
@@ -2,7 +2,7 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, date, timezone
+from datetime import UTC, date
from decimal import Decimal
from functools import cached_property
from typing import (
@@ -10,7 +10,6 @@ from typing import (
Any,
Literal,
Self,
- Type,
)
from more_itertools import flatten
diff --git a/generalresearch/models/legacy/definitions.py b/generalresearch/models/legacy/definitions.py
index 1755d2a..b3a6687 100644
--- a/generalresearch/models/legacy/definitions.py
+++ b/generalresearch/models/legacy/definitions.py
@@ -1,7 +1,7 @@
-from enum import Enum
+from enum import StrEnum
-class OfferwallReason(str, Enum):
+class OfferwallReason(StrEnum):
USER_BLOCKED = "USER_BLOCKED"
HIGH_RECON_RATE = "HIGH_RECON_RATE"
UNCOMMON_DEMOGRAPHICS = "UNCOMMON_DEMOGRAPHICS"
diff --git a/generalresearch/models/lucid/question.py b/generalresearch/models/lucid/question.py
index 6cbcb73..af3420e 100644
--- a/generalresearch/models/lucid/question.py
+++ b/generalresearch/models/lucid/question.py
@@ -1,7 +1,7 @@
from __future__ import annotations
import logging
-from enum import Enum
+from enum import StrEnum
from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import BaseModel, Field, field_validator, model_validator
@@ -40,7 +40,7 @@ class LucidQuestionOption(BaseModel):
order: int = Field()
-class LucidQuestionType(str, Enum):
+class LucidQuestionType(StrEnum):
SINGLE_SELECT = "s"
MULTI_SELECT = "m"
TEXT_ENTRY = "t"
diff --git a/generalresearch/models/morning/__init__.py b/generalresearch/models/morning/__init__.py
index 1bc15a7..e747586 100644
--- a/generalresearch/models/morning/__init__.py
+++ b/generalresearch/models/morning/__init__.py
@@ -1,4 +1,4 @@
-from enum import Enum
+from enum import StrEnum
from typing import Annotated
from pydantic import StringConstraints
@@ -9,7 +9,7 @@ MorningQuestionID = Annotated[
]
-class MorningStatus(str, Enum):
+class MorningStatus(StrEnum):
DRAFT = "draft"
ACTIVE = "active" # aka LIVE
PAUSED = "paused"
diff --git a/generalresearch/models/morning/question.py b/generalresearch/models/morning/question.py
index 8a1f729..b64a44a 100644
--- a/generalresearch/models/morning/question.py
+++ b/generalresearch/models/morning/question.py
@@ -1,6 +1,6 @@
import json
-from enum import Enum
-from typing import Any, Dict, List, Literal, Optional, Self
+from enum import StrEnum
+from typing import Any, Literal, Self
from uuid import UUID
from pydantic import BaseModel, Field, field_validator, model_validator
@@ -36,7 +36,7 @@ class MorningQuestionOption(BaseModel, frozen=True):
order: int = Field()
-class MorningQuestionType(str, Enum):
+class MorningQuestionType(StrEnum):
# The db stores these as a single letter
# Geographic questions represent geographic areas within a country.
diff --git a/generalresearch/models/morning/survey.py b/generalresearch/models/morning/survey.py
index 3c5a0e0..5011698 100644
--- a/generalresearch/models/morning/survey.py
+++ b/generalresearch/models/morning/survey.py
@@ -2,20 +2,14 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, timezone
+from datetime import UTC
from decimal import Decimal
from functools import cached_property
from typing import (
Annotated,
Any,
- Dict,
- List,
Literal,
- Optional,
Self,
- Set,
- Tuple,
- Type,
)
from pydantic import (
diff --git a/generalresearch/models/network/nmap/result.py b/generalresearch/models/network/nmap/result.py
index e6a0fd3..55c2109 100644
--- a/generalresearch/models/network/nmap/result.py
+++ b/generalresearch/models/network/nmap/result.py
@@ -4,7 +4,7 @@ import json
from datetime import timedelta
from enum import StrEnum
from functools import cached_property
-from typing import Any, Literal, Set
+from typing import Any, Literal
from pydantic import BaseModel, Field, computed_field
diff --git a/generalresearch/models/pollfish/question.py b/generalresearch/models/pollfish/question.py
index ae0dc5a..3b658fd 100644
--- a/generalresearch/models/pollfish/question.py
+++ b/generalresearch/models/pollfish/question.py
@@ -3,7 +3,7 @@ from __future__ import annotations
# https://wss.pollfish.com/mediation/documentation
import json
import logging
-from enum import Enum
+from enum import StrEnum
from typing import TYPE_CHECKING, Any, Literal, Self
from pydantic import BaseModel, Field, model_validator
@@ -39,7 +39,7 @@ class PollfishQuestionOption(BaseModel):
order: int = Field()
-class PollfishQuestionType(str, Enum):
+class PollfishQuestionType(StrEnum):
"""
From the API: {'single_punch', 'multi_punch', 'open_ended'}
"""
diff --git a/generalresearch/models/precision/__init__.py b/generalresearch/models/precision/__init__.py
index 089c34a..07deb8e 100644
--- a/generalresearch/models/precision/__init__.py
+++ b/generalresearch/models/precision/__init__.py
@@ -1,10 +1,10 @@
-from enum import Enum
+from enum import StrEnum
from typing import Annotated
from pydantic import StringConstraints
-class PrecisionStatus(str, Enum):
+class PrecisionStatus(StrEnum):
# I made this up. They use isactive: "Yes" or "no", which I think is stupid
OPEN = "open"
CLOSED = "closed"
diff --git a/generalresearch/models/precision/question.py b/generalresearch/models/precision/question.py
index 4030509..a2189d5 100644
--- a/generalresearch/models/precision/question.py
+++ b/generalresearch/models/precision/question.py
@@ -3,7 +3,7 @@ from __future__ import annotations
# https://integrations.precisionsample.com/api.html#Get%20Questions
import json
import logging
-from enum import Enum
+from enum import StrEnum
from typing import TYPE_CHECKING, Any, Literal
from pydantic import BaseModel, Field, field_validator, model_validator
@@ -43,7 +43,7 @@ class PrecisionQuestionOption(BaseModel):
order: int = Field()
-class PrecisionQuestionType(str, Enum):
+class PrecisionQuestionType(StrEnum):
"""
From the API: {'Drop Down', 'Multi Select', 'Single Select', 'Single Select Matrix', 'Vertical Question'}
Of course undocumented. And there doesn't seem to be a text entry option?
diff --git a/generalresearch/models/precision/survey.py b/generalresearch/models/precision/survey.py
index be98a79..f515552 100644
--- a/generalresearch/models/precision/survey.py
+++ b/generalresearch/models/precision/survey.py
@@ -1,9 +1,9 @@
from __future__ import annotations
import json
-from datetime import UTC, timezone
+from datetime import UTC
from functools import cached_property
-from typing import Annotated, Any, Dict, List, Literal, Optional, Self, Set, Tuple, Type
+from typing import Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import (
diff --git a/generalresearch/models/precision/task_collection.py b/generalresearch/models/precision/task_collection.py
index daea448..c8db2af 100644
--- a/generalresearch/models/precision/task_collection.py
+++ b/generalresearch/models/precision/task_collection.py
@@ -1,4 +1,4 @@
-from typing import Any, Dict, List
+from typing import Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
diff --git a/generalresearch/models/prodege/__init__.py b/generalresearch/models/prodege/__init__.py
index 5c6659a..64b148a 100644
--- a/generalresearch/models/prodege/__init__.py
+++ b/generalresearch/models/prodege/__init__.py
@@ -1,4 +1,4 @@
-from enum import Enum
+from enum import StrEnum
from typing import Annotated, Literal
from pydantic import Field
@@ -8,7 +8,7 @@ ProdegeQuestionIdType = Annotated[
]
-class ProdegeStatus(str, Enum):
+class ProdegeStatus(StrEnum):
LIVE = "LIVE"
# We need another status to mark if a survey we thought was live does not come back
# from the API, we'll mark it as NOT_FOUND
@@ -18,7 +18,7 @@ class ProdegeStatus(str, Enum):
INELIGIBLE = "INELIGIBLE"
-class ProdegePastParticipationType(str, Enum):
+class ProdegePastParticipationType(StrEnum):
# These come from the "participation_types" key in the survey API response
# which is how we filter by users' past_participation.
CLICK = "click"
diff --git a/generalresearch/models/prodege/question.py b/generalresearch/models/prodege/question.py
index 3ef4772..574c4fd 100644
--- a/generalresearch/models/prodege/question.py
+++ b/generalresearch/models/prodege/question.py
@@ -3,8 +3,8 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, datetime, timezone
-from enum import Enum
+from datetime import UTC, datetime
+from enum import StrEnum
from functools import cached_property
from typing import TYPE_CHECKING, Any, Literal
@@ -90,7 +90,7 @@ class ProdegeQuestionOption(BaseModel):
is_exclusive: bool = Field(default=False)
-class ProdegeQuestionType(str, Enum):
+class ProdegeQuestionType(StrEnum):
"""
{'Derived', 'Multi Punch', 'Numeric - Open End', 'Single Punch', 'Zip Code'}
"""
diff --git a/generalresearch/models/prodege/survey.py b/generalresearch/models/prodege/survey.py
index 1601fa3..3f4c88f 100644
--- a/generalresearch/models/prodege/survey.py
+++ b/generalresearch/models/prodege/survey.py
@@ -4,10 +4,10 @@ from __future__ import annotations
import json
import logging
from collections import defaultdict
-from datetime import UTC, datetime, timezone
+from datetime import UTC, datetime
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal, Type
+from typing import Any, Literal
from pydantic import (
BaseModel,
diff --git a/generalresearch/models/prodege/task_collection.py b/generalresearch/models/prodege/task_collection.py
index d3e4a20..4544050 100644
--- a/generalresearch/models/prodege/task_collection.py
+++ b/generalresearch/models/prodege/task_collection.py
@@ -1,4 +1,4 @@
-from typing import Any, Dict, List
+from typing import Any
import pandas as pd
from pandera.pandas import Check, Column, DataFrameSchema, Index
diff --git a/generalresearch/models/repdata/__init__.py b/generalresearch/models/repdata/__init__.py
index 9706b28..4a3d8d0 100644
--- a/generalresearch/models/repdata/__init__.py
+++ b/generalresearch/models/repdata/__init__.py
@@ -1,7 +1,7 @@
-from enum import Enum
+from enum import StrEnum
-class RepDataStatus(str, Enum):
+class RepDataStatus(StrEnum):
LIVE = "LIVE"
DRAFT = "DRAFT"
PAUSED = "PAUSED"
diff --git a/generalresearch/models/repdata/question.py b/generalresearch/models/repdata/question.py
index 8d0da13..9dda97f 100644
--- a/generalresearch/models/repdata/question.py
+++ b/generalresearch/models/repdata/question.py
@@ -2,7 +2,7 @@ from __future__ import annotations
import json
import logging
-from enum import Enum
+from enum import StrEnum
from functools import cached_property
from typing import TYPE_CHECKING, Any, Literal
from uuid import UUID
@@ -86,7 +86,7 @@ class RepDataQuestionOption(BaseModel):
order: int = Field()
-class RepDataQuestionType(str, Enum):
+class RepDataQuestionType(StrEnum):
"""
{'Derived', 'Multi Punch', 'Numeric - Open End', 'Single Punch', 'Zip Code'}
"""
diff --git a/generalresearch/models/repdata/survey.py b/generalresearch/models/repdata/survey.py
index fa71c04..43a592c 100644
--- a/generalresearch/models/repdata/survey.py
+++ b/generalresearch/models/repdata/survey.py
@@ -3,10 +3,10 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, datetime, timezone
+from datetime import UTC, datetime
from decimal import Decimal
from functools import cached_property
-from typing import Any, Literal, Self, Type
+from typing import Any, Literal, Self
from uuid import UUID
from pydantic import (
diff --git a/generalresearch/models/sago/__init__.py b/generalresearch/models/sago/__init__.py
index 19e7b6d..1059a6f 100644
--- a/generalresearch/models/sago/__init__.py
+++ b/generalresearch/models/sago/__init__.py
@@ -1,4 +1,4 @@
-from enum import Enum
+from enum import StrEnum
from typing import Annotated
from pydantic import Field
@@ -8,6 +8,6 @@ SagoQuestionIdType = Annotated[
]
-class SagoStatus(str, Enum):
+class SagoStatus(StrEnum):
LIVE = "LIVE"
NOT_LIVE = "NOT_LIVE"
diff --git a/generalresearch/models/sago/question.py b/generalresearch/models/sago/question.py
index f911854..474543d 100644
--- a/generalresearch/models/sago/question.py
+++ b/generalresearch/models/sago/question.py
@@ -4,7 +4,7 @@ from __future__ import annotations
# -answers-lanaguge-languageid
import json
import logging
-from enum import Enum
+from enum import StrEnum
from functools import cached_property
from typing import TYPE_CHECKING, Any, Literal
@@ -57,7 +57,7 @@ class SagoQuestionOption(BaseModel):
return string_utils.remove_nbsp(s)
-class SagoQuestionType(str, Enum):
+class SagoQuestionType(StrEnum):
"""
From the API:
{1: 'Single Punch', 2: 'Multi Punch', 3: 'Open Ended', 4: 'Dummy',
diff --git a/generalresearch/models/sago/survey.py b/generalresearch/models/sago/survey.py
index 0b5830b..83aad8c 100644
--- a/generalresearch/models/sago/survey.py
+++ b/generalresearch/models/sago/survey.py
@@ -2,10 +2,10 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, timezone
+from datetime import UTC
from decimal import Decimal
from functools import cached_property
-from typing import Annotated, Any, Literal, Self, Type
+from typing import Annotated, Any, Literal, Self
from more_itertools import flatten
from pydantic import BaseModel, ConfigDict, Field, computed_field, model_validator
diff --git a/generalresearch/models/spectrum/question.py b/generalresearch/models/spectrum/question.py
index 81f8655..c8eea4a 100644
--- a/generalresearch/models/spectrum/question.py
+++ b/generalresearch/models/spectrum/question.py
@@ -3,8 +3,8 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, datetime, timezone
-from enum import Enum
+from datetime import UTC, datetime
+from enum import IntEnum, StrEnum
from functools import cached_property
from typing import TYPE_CHECKING, Any, Literal, Self
from uuid import UUID
@@ -93,7 +93,7 @@ class SpectrumQuestionOption(BaseModel):
return string_utils.remove_nbsp(s)
-class SpectrumQuestionType(str, Enum):
+class SpectrumQuestionType(StrEnum):
# The documentation defines 4 types (1,2,3,4), however 2 is the same as 1
# and never comes back in the api, and we also get back 5, 6, and 7,
# which are all undocumented.
@@ -135,7 +135,7 @@ class SpectrumQuestionType(str, Enum):
return api_type_map[a] if a in api_type_map else None
-class SpectrumQuestionClass(int, Enum):
+class SpectrumQuestionClass(IntEnum):
CORE = 1
EXTENDED = 2
CUSTOM = 3
diff --git a/generalresearch/models/spectrum/survey.py b/generalresearch/models/spectrum/survey.py
index f842f46..aaf182e 100644
--- a/generalresearch/models/spectrum/survey.py
+++ b/generalresearch/models/spectrum/survey.py
@@ -2,9 +2,9 @@ from __future__ import annotations
import json
import logging
-from datetime import UTC, timezone
+from datetime import UTC
from decimal import Decimal
-from typing import Any, Literal, Self, Type
+from typing import Any, Literal, Self
from more_itertools import flatten
from pydantic import BaseModel, ConfigDict, Field, computed_field, model_validator
diff --git a/generalresearch/models/thl/contest/definitions.py b/generalresearch/models/thl/contest/definitions.py
index 1a71408..cc0ee05 100644
--- a/generalresearch/models/thl/contest/definitions.py
+++ b/generalresearch/models/thl/contest/definitions.py
@@ -1,17 +1,17 @@
from __future__ import annotations
-from enum import Enum
+from enum import StrEnum
from generalresearch.utils.enum import ReprEnumMeta
-class ContestStatus(str, Enum):
+class ContestStatus(StrEnum):
ACTIVE = "active"
COMPLETED = "completed"
CANCELLED = "cancelled"
-class ContestType(str, Enum, metaclass=ReprEnumMeta):
+class ContestType(StrEnum, metaclass=ReprEnumMeta):
"""There are 3 contest types. They have a common base, with some unique
configurations and behaviors for each.
"""
@@ -26,7 +26,7 @@ class ContestType(str, Enum, metaclass=ReprEnumMeta):
MILESTONE = "milestone"
-class ContestEndReason(str, Enum):
+class ContestEndReason(StrEnum):
"""
Defines why a contest ended
"""
@@ -44,7 +44,7 @@ class ContestEndReason(str, Enum):
MAX_WINNERS = "max_winners"
-class ContestPrizeKind(str, Enum, metaclass=ReprEnumMeta):
+class ContestPrizeKind(StrEnum, metaclass=ReprEnumMeta):
# A physical prize (e.g. a iPhone, cash in the mail, dinner with Max)
PHYSICAL = "physical"
@@ -56,7 +56,7 @@ class ContestPrizeKind(str, Enum, metaclass=ReprEnumMeta):
CASH = "cash"
-class ContestEntryTrigger(str, Enum):
+class ContestEntryTrigger(StrEnum):
"""
Defines what action/event triggers a (possible) entry into the contest (automatically).
This only is valid on milestone contests
@@ -67,7 +67,7 @@ class ContestEntryTrigger(str, Enum):
REFERRAL = "referral"
-class ContestEntryType(str, Enum, metaclass=ReprEnumMeta):
+class ContestEntryType(StrEnum, metaclass=ReprEnumMeta):
"""
All entries into a contest must be of the same type, and match
the entry_type of the Contest itself.
@@ -83,7 +83,7 @@ class ContestEntryType(str, Enum, metaclass=ReprEnumMeta):
CASH = "cash"
-class LeaderboardTieBreakStrategy(str, Enum):
+class LeaderboardTieBreakStrategy(StrEnum):
"""
Strategies for resolving ties in leaderboard-based contests.
"""
diff --git a/generalresearch/models/thl/definitions.py b/generalresearch/models/thl/definitions.py
index 22ca4b9..0217a80 100644
--- a/generalresearch/models/thl/definitions.py
+++ b/generalresearch/models/thl/definitions.py
@@ -1,10 +1,10 @@
import copy
-from enum import Enum
+from enum import IntEnum, StrEnum
from generalresearch.utils.enum import ReprEnumMeta
-class ReservedQueryParameters(str, Enum, metaclass=ReprEnumMeta):
+class ReservedQueryParameters(StrEnum, metaclass=ReprEnumMeta):
PRODUCT_ID = "product_id"
PRODUCT_USER_ID = "bp_user_id"
BPUID = "bpuid"
@@ -48,7 +48,7 @@ class ReservedQueryParameters(str, Enum, metaclass=ReprEnumMeta):
N_BINS = "n_bins"
-class THLPaths(str, Enum, metaclass=ReprEnumMeta):
+class THLPaths(StrEnum, metaclass=ReprEnumMeta):
# Endpoints on thl-fsb
TASK_ADJUSTMENT = "f4484dbdf144451ab60cda256ce14266"
@@ -65,7 +65,7 @@ class THLPaths(str, Enum, metaclass=ReprEnumMeta):
GET_GRLIQ_JS_ATTR = "4a2954b34cc24f93be3e8b218e323b88"
-class Status(str, Enum, metaclass=ReprEnumMeta):
+class Status(StrEnum, metaclass=ReprEnumMeta):
"""
The outcome of a session or wall event. If the session is still in
progress, the status will be NULL.
@@ -85,7 +85,7 @@ class Status(str, Enum, metaclass=ReprEnumMeta):
TIMEOUT = "t"
-class WallAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
+class WallAdjustedStatus(StrEnum, metaclass=ReprEnumMeta):
# Task was reconciled to complete
ADJUSTED_TO_COMPLETE = "ac"
# Task was reconciled to incomplete
@@ -100,7 +100,7 @@ class WallAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
CONFIRMED_COMPLETE = "cc"
-class SessionAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
+class SessionAdjustedStatus(StrEnum, metaclass=ReprEnumMeta):
"""An adjusted_status is set if a session is adjusted by the marketplace
after the original return. A session can be adjusted multiple times.
This is the most recent status. If a session was originally a complete,
@@ -117,7 +117,7 @@ class SessionAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
PAYOUT_ADJUSTMENT = "pa"
-class StatusCode1(int, Enum, metaclass=ReprEnumMeta):
+class StatusCode1(IntEnum, metaclass=ReprEnumMeta):
"""
__High level status code for outcome of the session.__
This should only be NULL if the Status is ABANDON or TIMEOUT
@@ -177,7 +177,7 @@ class StatusCode1(int, Enum, metaclass=ReprEnumMeta):
SESSION_CONTINUE_QUALITY_FAIL = 19
-class SessionStatusCode2(int, Enum, metaclass=ReprEnumMeta):
+class SessionStatusCode2(IntEnum, metaclass=ReprEnumMeta):
"""
__Status Detail__
This should be set if the Session.status_code_1 is SESSION_XXX_FAIL
@@ -217,7 +217,7 @@ class SessionStatusCode2(int, Enum, metaclass=ReprEnumMeta):
GRLIQ_MISSING = 13
-class WallStatusCode2(int, Enum, metaclass=ReprEnumMeta):
+class WallStatusCode2(IntEnum, metaclass=ReprEnumMeta):
"""
This should be set if the Wall.status_code_1 is MARKETPLACE_FAIL
"""
@@ -289,7 +289,7 @@ WALL_ALLOWED_STATUS_CODE_1_2 = {
}
-class ReportValue(int, Enum, metaclass=ReprEnumMeta):
+class ReportValue(IntEnum, metaclass=ReprEnumMeta):
"""
The reason a user reported a task.
"""
@@ -316,7 +316,7 @@ class ReportValue(int, Enum, metaclass=ReprEnumMeta):
DIDNT_LIKE = 7
-class PayoutStatus(str, Enum, metaclass=ReprEnumMeta):
+class PayoutStatus(StrEnum, metaclass=ReprEnumMeta):
"""The max size of the db field that holds this value is 20, so please
don't add new values longer than that!
"""
diff --git a/generalresearch/models/thl/demographics.py b/generalresearch/models/thl/demographics.py
index 4d4c8c2..b6a8be1 100644
--- a/generalresearch/models/thl/demographics.py
+++ b/generalresearch/models/thl/demographics.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import copy
from collections import Counter, defaultdict
from dataclasses import dataclass
-from enum import Enum
+from enum import Enum, StrEnum
from typing import TYPE_CHECKING, Any, Literal
import numpy as np
@@ -35,7 +35,7 @@ class DemographicTarget:
}
-class Gender(str, Enum):
+class Gender(StrEnum):
"""
The respondent's gender
"""
diff --git a/generalresearch/models/thl/leaderboard.py b/generalresearch/models/thl/leaderboard.py
index dce3280..4d116a5 100644
--- a/generalresearch/models/thl/leaderboard.py
+++ b/generalresearch/models/thl/leaderboard.py
@@ -2,8 +2,8 @@ from __future__ import annotations
import logging
import math
-from datetime import UTC, datetime, timedelta, timezone
-from enum import Enum
+from datetime import UTC, datetime, timedelta
+from enum import StrEnum
from typing import Literal
from uuid import UUID, uuid3
from zoneinfo import ZoneInfo
@@ -27,7 +27,7 @@ from generalresearch.utils.enum import ReprEnumMeta
logger = logging.getLogger()
-class LeaderboardCode(str, Enum, metaclass=ReprEnumMeta):
+class LeaderboardCode(StrEnum, metaclass=ReprEnumMeta):
"""
The type of leaderboard. What the "values" represent.
"""
@@ -40,7 +40,7 @@ class LeaderboardCode(str, Enum, metaclass=ReprEnumMeta):
SUM_PAYOUTS = "sum_user_payout"
-class LeaderboardFrequency(str, Enum, metaclass=ReprEnumMeta):
+class LeaderboardFrequency(StrEnum, metaclass=ReprEnumMeta):
"""
The time period range for the leaderboard.
"""
diff --git a/generalresearch/models/thl/ledger.py b/generalresearch/models/thl/ledger.py
index dd37d98..19dde20 100644
--- a/generalresearch/models/thl/ledger.py
+++ b/generalresearch/models/thl/ledger.py
@@ -1,8 +1,8 @@
from __future__ import annotations
-from datetime import UTC, datetime, timezone
-from enum import Enum
-from typing import Annotated, Any, Literal, Self, Union
+from datetime import UTC, datetime
+from enum import StrEnum
+from typing import Annotated, Any, Literal, Self
from uuid import uuid4
from pydantic import (
@@ -50,13 +50,13 @@ class Direction(int, Enum, metaclass=ReprEnumMeta):
DEBIT = 1
-class OrderBy(str, Enum, metaclass=ReprEnumMeta):
+class OrderBy(StrEnum, metaclass=ReprEnumMeta):
ASC = "ASC"
DESC = "DESC"
-class AccountType(str, Enum, metaclass=ReprEnumMeta):
+class AccountType(StrEnum, metaclass=ReprEnumMeta):
# Revenue from BP payment commission
BP_COMMISSION = "bp_commission"
# BP wallets (owed balance)
@@ -83,7 +83,7 @@ class AccountType(str, Enum, metaclass=ReprEnumMeta):
WA_CREDIT_LINE = "wa_credit_line"
-class TransactionMetadataColumns(str, Enum):
+class TransactionMetadataColumns(StrEnum):
BONUS = "bonus_id"
# Note: EVENT & EVENT2 represent the same concept. I accidentally made
# this inconsistent.
@@ -102,7 +102,7 @@ class TransactionMetadataColumns(str, Enum):
CONTEST = "contest"
-class TransactionType(str, Enum):
+class TransactionType(StrEnum):
"""These are used in the Ledger to annotate the type of transaction (in
metadata: tx_type)
"""
diff --git a/generalresearch/models/thl/offerwall/__init__.py b/generalresearch/models/thl/offerwall/__init__.py
index 3acc592..e7c8e03 100644
--- a/generalresearch/models/thl/offerwall/__init__.py
+++ b/generalresearch/models/thl/offerwall/__init__.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import hashlib
import json
from decimal import Decimal
-from enum import Enum
+from enum import StrEnum
from typing import Any, Literal, Self
from pydantic import (
@@ -31,7 +31,7 @@ from generalresearch.models.thl.product import (
from generalresearch.models.thl.user import User
-class OfferWallType(str, Enum):
+class OfferWallType(StrEnum):
"""
The specific offerwall type
"""
@@ -56,7 +56,7 @@ class OfferWallType(str, Enum):
STARWALL = "b59a2d2b"
-class OfferWallTypeClass(str, Enum):
+class OfferWallTypeClass(StrEnum):
"""
A higher level "class" to organize similar offerwall types.
For e.g. STARWALL_PLUS_BLOCK, STARWALL_PLUS, STARWALL all use the same
diff --git a/generalresearch/models/thl/product.py b/generalresearch/models/thl/product.py
index 8377e45..5b7ab9a 100644
--- a/generalresearch/models/thl/product.py
+++ b/generalresearch/models/thl/product.py
@@ -8,7 +8,7 @@ import warnings
from collections import defaultdict
from collections.abc import Callable
from decimal import Decimal
-from enum import Enum
+from enum import StrEnum
from functools import cached_property, partial
from typing import (
TYPE_CHECKING,
@@ -628,13 +628,13 @@ class SourceConfig(BaseModel):
)
-class Scope(str, Enum):
+class Scope(StrEnum):
GLOBAL = "global"
TEAM = "team"
PRODUCT = "product"
-class IntegrationMode(str, Enum):
+class IntegrationMode(StrEnum):
# We handle integration, get paid
PLATFORM = "platform"
# "external" credentials, we do not get paid for this activity
diff --git a/generalresearch/models/thl/profiling/upk_property.py b/generalresearch/models/thl/profiling/upk_property.py
index 9e78692..e46e00a 100644
--- a/generalresearch/models/thl/profiling/upk_property.py
+++ b/generalresearch/models/thl/profiling/upk_property.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from enum import Enum
+from enum import StrEnum
from functools import cached_property
from uuid import uuid4
@@ -11,7 +11,7 @@ from generalresearch.models.thl.category import Category
from generalresearch.utils.enum import ReprEnumMeta
-class PropertyType(str, Enum, metaclass=ReprEnumMeta):
+class PropertyType(StrEnum, metaclass=ReprEnumMeta):
# UserProfileKnowledge Item
UPK_ITEM = "i"
# UserProfileKnowledge Numerical
@@ -25,7 +25,7 @@ class PropertyType(str, Enum, metaclass=ReprEnumMeta):
# UPK_DATE = "d"
-class Cardinality(str, Enum, metaclass=ReprEnumMeta):
+class Cardinality(StrEnum, metaclass=ReprEnumMeta):
# Zero or More
ZERO_OR_MORE = "*"
# Zero or One
diff --git a/generalresearch/models/thl/profiling/upk_question.py b/generalresearch/models/thl/profiling/upk_question.py
index 78f9511..08ea350 100644
--- a/generalresearch/models/thl/profiling/upk_question.py
+++ b/generalresearch/models/thl/profiling/upk_question.py
@@ -3,9 +3,9 @@ from __future__ import annotations
import hashlib
import json
import re
-from enum import Enum
+from enum import StrEnum
from functools import cached_property
-from typing import Annotated, Any, List, Literal, Union
+from typing import Annotated, Any, Literal
from pydantic import (
BaseModel,
@@ -98,7 +98,7 @@ class UpkQuestionChoiceOut(UpkQuestionChoice):
# importance: Optional[UPKImportance] = Field(default=None, exclude=True)
-class UpkQuestionType(str, Enum):
+class UpkQuestionType(StrEnum):
# The question has options that the user must select from. A MC question
# can be e.g. Selector.SINGLE_ANSWER or Selector.MULTIPLE_ANSWER to
# indicate only 1 or more than 1 option can be selected respectively.
@@ -111,7 +111,7 @@ class UpkQuestionType(str, Enum):
HIDDEN = "HIDDEN"
-class UpkQuestionSelector(str, Enum):
+class UpkQuestionSelector(StrEnum):
pass
diff --git a/generalresearch/models/thl/supplier_tag.py b/generalresearch/models/thl/supplier_tag.py
index ad84c9b..739b895 100644
--- a/generalresearch/models/thl/supplier_tag.py
+++ b/generalresearch/models/thl/supplier_tag.py
@@ -1,7 +1,7 @@
-from enum import Enum
+from enum import StrEnum
-class SupplierTag(str, Enum):
+class SupplierTag(StrEnum):
"""Available tags which can be used to annotate supplier traffic
Note: should not include commas!
diff --git a/generalresearch/models/thl/survey/__init__.py b/generalresearch/models/thl/survey/__init__.py
index d6ba895..bc3d699 100644
--- a/generalresearch/models/thl/survey/__init__.py
+++ b/generalresearch/models/thl/survey/__init__.py
@@ -3,7 +3,6 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from decimal import Decimal
from itertools import product
-from typing import Type
from more_itertools import flatten
from pydantic import BaseModel, Field
diff --git a/generalresearch/models/thl/user_quality_event.py b/generalresearch/models/thl/user_quality_event.py
index 52903e3..cfb4ff3 100644
--- a/generalresearch/models/thl/user_quality_event.py
+++ b/generalresearch/models/thl/user_quality_event.py
@@ -1,8 +1,8 @@
from __future__ import annotations
-from datetime import UTC, datetime, timezone
+from datetime import UTC, datetime
from decimal import Decimal
-from enum import Enum
+from enum import StrEnum
from typing import Literal
from pydantic import BaseModel, Field, PositiveInt
@@ -18,7 +18,7 @@ Typically used internally. These affect a user's quality standing.
"""
-class QualityEventType(str, Enum, metaclass=ReprEnumMeta):
+class QualityEventType(StrEnum, metaclass=ReprEnumMeta):
"""
Currently, the grpc call SendUserQualityEvents handles both the
recons/task adj, access control, and "security/hash failure" events.
diff --git a/generalresearch/models/thl/user_streak.py b/generalresearch/models/thl/user_streak.py
index 278809b..cc4d643 100644
--- a/generalresearch/models/thl/user_streak.py
+++ b/generalresearch/models/thl/user_streak.py
@@ -1,7 +1,8 @@
from __future__ import annotations
from datetime import date, datetime, timedelta
-from enum import Enum
+from enum import StrEnum
+from zoneinfo import ZoneInfo
import pandas as pd
from pydantic import (
@@ -15,14 +16,13 @@ from pydantic import (
model_validator,
)
from pydantic.json_schema import SkipJsonSchema
-from zoneinfo import ZoneInfo
from generalresearch.managers.leaderboard import country_timezone
from generalresearch.models import MAX_INT32
from generalresearch.models.thl.locales import CountryISO
-class StreakPeriod(str, Enum):
+class StreakPeriod(StrEnum):
# Midnight to midnight in the tz associated with the user's country
DAY = "day"
# Sunday midnight - sunday midnight
@@ -31,7 +31,7 @@ class StreakPeriod(str, Enum):
MONTH = "month"
-class StreakFulfillment(str, Enum):
+class StreakFulfillment(StrEnum):
"""
What has to happen for a user to fulfill a period for a streak
"""
@@ -42,7 +42,7 @@ class StreakFulfillment(str, Enum):
COMPLETE = "complete"
-class StreakState(str, Enum):
+class StreakState(StrEnum):
# The activity for today was completed!
ACTIVE = "active"
# They had activity yesterday, but not today, and can still continue today
diff --git a/generalresearch/models/thl/userhealth.py b/generalresearch/models/thl/userhealth.py
index fb15572..f0b7473 100644
--- a/generalresearch/models/thl/userhealth.py
+++ b/generalresearch/models/thl/userhealth.py
@@ -1,8 +1,8 @@
from __future__ import annotations
-from datetime import UTC, datetime, timezone
+from datetime import UTC, datetime
from enum import Enum
-from typing import Dict, Optional, Self
+from typing import Self
from pydantic import BaseModel, Field, NonNegativeFloat, PositiveInt
diff --git a/generalresearch/models/thl/wallet/__init__.py b/generalresearch/models/thl/wallet/__init__.py
index 1403ddf..2d1eb8d 100644
--- a/generalresearch/models/thl/wallet/__init__.py
+++ b/generalresearch/models/thl/wallet/__init__.py
@@ -1,9 +1,9 @@
-from enum import Enum
+from enum import StrEnum
from generalresearch.utils.enum import ReprEnumMeta
-class PayoutType(str, Enum, metaclass=ReprEnumMeta):
+class PayoutType(StrEnum, metaclass=ReprEnumMeta):
"""
The method in which the requested payout is delivered.
"""
@@ -35,7 +35,7 @@ class PayoutType(str, Enum, metaclass=ReprEnumMeta):
AMT_ASSIGNMENT = "AMT_ASSIGNMENT"
-class Currency(str, Enum):
+class Currency(StrEnum):
# United States Dollar
USD = "USD"
# Canadian Dollar
diff --git a/generalresearch/models/thl/wallet/cashout_method.py b/generalresearch/models/thl/wallet/cashout_method.py
index 4757eba..40c4717 100644
--- a/generalresearch/models/thl/wallet/cashout_method.py
+++ b/generalresearch/models/thl/wallet/cashout_method.py
@@ -2,9 +2,9 @@ from __future__ import annotations
import hashlib
import logging
-from datetime import datetime, timezone, UTC
-from enum import Enum
-from typing import Any, Literal
+from datetime import UTC, datetime
+from enum import StrEnum
+from typing import Any, Literal, Self
from pydantic import (
BaseModel,
@@ -16,7 +16,6 @@ from pydantic import (
field_validator,
model_validator,
)
-from typing import Self
from generalresearch.currency import USDCent
from generalresearch.models.custom_types import (
@@ -144,9 +143,7 @@ class CashoutMethod(CashoutMethodBase):
"a user may have a paypal cashout method with their paypal"
"email associated.",
)
- last_updated: AwareDatetimeISO = Field(
- default_factory=lambda: datetime.now(tz=UTC)
- )
+ last_updated: AwareDatetimeISO = Field(default_factory=lambda: datetime.now(tz=UTC))
is_live: bool = Field(default=True)
@model_validator(mode="after")
@@ -249,7 +246,7 @@ class CashoutMethodsResponse(StatusResponse):
cashout_methods: list[CashoutMethodOut] = Field()
-class DeliveryStatus(str, Enum):
+class DeliveryStatus(StrEnum):
PENDING = "Pending"
SHIPPED = "Shipped"
IN_TRANSIT = "In Transit"
@@ -261,14 +258,14 @@ class DeliveryStatus(str, Enum):
LOST = "Lost"
-class ShippingCarrier(str, Enum):
+class ShippingCarrier(StrEnum):
USPS = "USPS"
FEDEX = "FedEx"
UPS = "UPS"
DHL = "DHL"
-class ShippingMethod(str, Enum):
+class ShippingMethod(StrEnum):
STANDARD = "Standard"
EXPRESS = "Express"
TWO_DAY = "Two-Day"
@@ -394,7 +391,7 @@ example_foreign_value = {
}
-class RedemptionCurrency(str, Enum, metaclass=ReprEnumMeta):
+class RedemptionCurrency(StrEnum, metaclass=ReprEnumMeta):
"""
Supported Currencies for Foreign Redemptions
"""
diff --git a/generalresearch/utils/aggregation.py b/generalresearch/utils/aggregation.py
index bd962f1..ef3a52d 100644
--- a/generalresearch/utils/aggregation.py
+++ b/generalresearch/utils/aggregation.py
@@ -1,5 +1,5 @@
from collections import defaultdict
-from typing import Any, Dict, List
+from typing import Any
def group_by_year(records: list[dict], datetime_field: str) -> dict[int, list[Any]]:
diff --git a/generalresearch/utils/enum.py b/generalresearch/utils/enum.py
index 56706ba..e59a383 100644
--- a/generalresearch/utils/enum.py
+++ b/generalresearch/utils/enum.py
@@ -3,7 +3,6 @@ from __future__ import annotations
import inspect
import re
from enum import EnumMeta
-from typing import Dict
class ReprEnumMeta(EnumMeta):
diff --git a/generalresearch/wall_status_codes/__init__.py b/generalresearch/wall_status_codes/__init__.py
index 1d80924..cfccb35 100644
--- a/generalresearch/wall_status_codes/__init__.py
+++ b/generalresearch/wall_status_codes/__init__.py
@@ -1,5 +1,3 @@
-from typing import Optional, Tuple
-
from generalresearch.models import Source
from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.models.thl.session import Wall
diff --git a/generalresearch/wall_status_codes/cint.py b/generalresearch/wall_status_codes/cint.py
index ecb6219..c31c0ba 100644
--- a/generalresearch/wall_status_codes/cint.py
+++ b/generalresearch/wall_status_codes/cint.py
@@ -1,4 +1,4 @@
-from typing import Any, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.wall_status_codes import lucid
diff --git a/generalresearch/wall_status_codes/dynata.py b/generalresearch/wall_status_codes/dynata.py
index 69f3e74..53eebe7 100644
--- a/generalresearch/wall_status_codes/dynata.py
+++ b/generalresearch/wall_status_codes/dynata.py
@@ -4,7 +4,7 @@ checked by Greg 2023-10-10
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/fullcircle.py b/generalresearch/wall_status_codes/fullcircle.py
index f37ffda..aeaa4c7 100644
--- a/generalresearch/wall_status_codes/fullcircle.py
+++ b/generalresearch/wall_status_codes/fullcircle.py
@@ -7,7 +7,7 @@ we'll try to infer based on the time spent in survey.
from collections import defaultdict
from datetime import timedelta
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/innovate.py b/generalresearch/wall_status_codes/innovate.py
index fba3f54..936ee6c 100644
--- a/generalresearch/wall_status_codes/innovate.py
+++ b/generalresearch/wall_status_codes/innovate.py
@@ -9,7 +9,7 @@ can map directly, and some we have to look at the category.
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/lucid.py b/generalresearch/wall_status_codes/lucid.py
index 3ce89b0..05b75fb 100644
--- a/generalresearch/wall_status_codes/lucid.py
+++ b/generalresearch/wall_status_codes/lucid.py
@@ -5,7 +5,7 @@ https://support.lucidhq.com/s/article/Collecting-Data-From-Redirects
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/morning.py b/generalresearch/wall_status_codes/morning.py
index 42e34b3..bac9669 100644
--- a/generalresearch/wall_status_codes/morning.py
+++ b/generalresearch/wall_status_codes/morning.py
@@ -1,5 +1,5 @@
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/precision.py b/generalresearch/wall_status_codes/precision.py
index d3c4471..b033cf2 100644
--- a/generalresearch/wall_status_codes/precision.py
+++ b/generalresearch/wall_status_codes/precision.py
@@ -7,7 +7,7 @@ f - client approved the Preliminary complete as Final Complete
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/prodege.py b/generalresearch/wall_status_codes/prodege.py
index aaac376..2876ba9 100644
--- a/generalresearch/wall_status_codes/prodege.py
+++ b/generalresearch/wall_status_codes/prodege.py
@@ -3,7 +3,7 @@ https://developer.prodege.com/surveys-feed/term-reasons
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/repdata.py b/generalresearch/wall_status_codes/repdata.py
index 8b690b5..ad64338 100644
--- a/generalresearch/wall_status_codes/repdata.py
+++ b/generalresearch/wall_status_codes/repdata.py
@@ -3,7 +3,7 @@ Status codes are in a xlsx file. See thl-repdata readme
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/sago.py b/generalresearch/wall_status_codes/sago.py
index 028192b..b66190c 100644
--- a/generalresearch/wall_status_codes/sago.py
+++ b/generalresearch/wall_status_codes/sago.py
@@ -3,7 +3,7 @@ https://developer-beta.market-cube.com/api-details#api=definition-api&operation=
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/spectrum.py b/generalresearch/wall_status_codes/spectrum.py
index cf200a9..610e239 100644
--- a/generalresearch/wall_status_codes/spectrum.py
+++ b/generalresearch/wall_status_codes/spectrum.py
@@ -3,7 +3,7 @@ https://purespectrum.atlassian.net/wiki/spaces/PA/pages/33613201/Minimizing+Clic
"""
from collections import defaultdict
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any
from generalresearch.models.thl.definitions import Status, StatusCode1
diff --git a/generalresearch/wall_status_codes/wxet.py b/generalresearch/wall_status_codes/wxet.py
index 1b7c514..6b3f67c 100644
--- a/generalresearch/wall_status_codes/wxet.py
+++ b/generalresearch/wall_status_codes/wxet.py
@@ -1,5 +1,4 @@
from collections import defaultdict
-from typing import Dict, List, Optional, Tuple
from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.wxet.models.definitions import (
diff --git a/generalresearch/wxet/models/definitions.py b/generalresearch/wxet/models/definitions.py
index b08e178..ea0b51f 100644
--- a/generalresearch/wxet/models/definitions.py
+++ b/generalresearch/wxet/models/definitions.py
@@ -1,11 +1,10 @@
-from enum import Enum
-from typing import Optional, Tuple
+from enum import IntEnum, StrEnum
from generalresearch.currency import USDMill
from generalresearch.utils.enum import ReprEnumMeta
-class IncExcFilterType(str, Enum, metaclass=ReprEnumMeta):
+class IncExcFilterType(StrEnum, metaclass=ReprEnumMeta):
INCLUDE = "include"
EXCLUDE = "exclude"
@@ -13,7 +12,7 @@ class IncExcFilterType(str, Enum, metaclass=ReprEnumMeta):
# Note: This is exactly the same as the generalresearch:models/thl/definitions.py:Status.
# Keeping this because the comments (and as a result, the documentation)
# is slightly different, and specific to wxet.
-class WXETStatus(str, Enum, metaclass=ReprEnumMeta):
+class WXETStatus(StrEnum, metaclass=ReprEnumMeta):
"""
The outcome of a task attempt. If the attempt is still in progress, the status will be NULL.
"""
@@ -36,7 +35,7 @@ class WXETStatus(str, Enum, metaclass=ReprEnumMeta):
# Basically same note as for WxetStatus for WallAdjustedStatus
-class WXETAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
+class WXETAdjustedStatus(StrEnum, metaclass=ReprEnumMeta):
# Task was reconciled to complete
ADJUSTED_TO_COMPLETE = "ac"
@@ -52,7 +51,7 @@ class WXETAdjustedStatus(str, Enum, metaclass=ReprEnumMeta):
POSTBACK_COMPLETE = "pc"
-class WXETStatusCode1(int, Enum, metaclass=ReprEnumMeta):
+class WXETStatusCode1(IntEnum, metaclass=ReprEnumMeta):
"""
__High level status code for outcome of the attempt.__
This should only be NULL if the WXETStatus is ABANDON or TIMEOUT
@@ -103,10 +102,10 @@ class WXETStatusCode1(int, Enum, metaclass=ReprEnumMeta):
"""This property helper indicates if the WXET Attempt made it into
the WXET Account's (eg: the "buyer"'s) Task.
"""
- return False if self.value > 10 else True
+ return not self.value > 10
-class WXETStatusCode2(int, Enum, metaclass=ReprEnumMeta):
+class WXETStatusCode2(IntEnum, metaclass=ReprEnumMeta):
"""
__Status Detail__
These are generally only set if the StatusCode1 is WXET_FAIL,
diff --git a/generalresearch/wxet/models/finish_type.py b/generalresearch/wxet/models/finish_type.py
index a57dce8..17923d6 100644
--- a/generalresearch/wxet/models/finish_type.py
+++ b/generalresearch/wxet/models/finish_type.py
@@ -1,11 +1,10 @@
-from enum import Enum
-from typing import Optional, Set
+from enum import StrEnum
from generalresearch.utils.enum import ReprEnumMeta
from generalresearch.wxet.models.definitions import WXETStatus, WXETStatusCode1
-class FinishType(str, Enum, metaclass=ReprEnumMeta):
+class FinishType(StrEnum, metaclass=ReprEnumMeta):
"""A Task can be classified as "finished" based on different outcomes.
<br/>
This controls how the `Task.required_finish_count` value
diff --git a/tests/incite/schemas/test_admin_responses.py b/tests/incite/schemas/test_admin_responses.py
index 29d93fe..e98eecd 100644
--- a/tests/incite/schemas/test_admin_responses.py
+++ b/tests/incite/schemas/test_admin_responses.py
@@ -1,6 +1,5 @@
-from datetime import UTC, datetime, timedelta, timezone
+from datetime import UTC, datetime, timedelta
from random import sample
-from typing import List
import numpy as np
import pandas as pd