import logging
from enum import Enum
[docs]class StatusType(Enum):
SUCCESS = 'success'
FAILED = 'failed'
WARNING = 'warning'
INFO = 'info'
CRITICAL = 'critical'
IN_PROGRESS = 'in_progress'
COMPLETE = 'complete'
PAUSED = 'paused'
RUNNING = 'running'
ERROR = 'error'
RETRYING = 'retrying'
STOPPED = 'stopped'
QUEUED = 'queued'
CANCELED = 'canceled'
APPROVED = 'approved'
REJECTED = 'rejected'
SCHEDULED = 'scheduled'
MAINTENANCE = 'maintenance'
UPDATE = 'update'
[docs]class ICONPRepStatus:
PREP_STATUS_ACTIVE = 0
PREP_STATUS_UNREGISTERED = 1
PREP_STATUS_DISQUALIFIED = 2
PREP_LAST_STATE_NONE = 0
PREP_LAST_STATE_READY = 1
PREP_LAST_STATE_SUCCESS = 2
PREP_LAST_STATE_FAILURE = 3
PREP_STATUS_DESCRIPTIONS = {
PREP_STATUS_ACTIVE: "active",
PREP_STATUS_UNREGISTERED: "unregistered",
PREP_STATUS_DISQUALIFIED: "disqualified"
}
PREP_LAST_STATE_DESCRIPTIONS = {
PREP_LAST_STATE_NONE: None,
PREP_LAST_STATE_READY: "Ready",
PREP_LAST_STATE_SUCCESS: "Success",
PREP_LAST_STATE_FAILURE: "Failure"
}
[docs] @classmethod
def get_status(cls, status_type):
"""Return the description of the given P-Rep status type."""
return cls.PREP_STATUS_DESCRIPTIONS.get(status_type, "Unknown P-Rep status")
[docs] @classmethod
def get_last_state(cls, state):
"""Return the description of the given P-Rep last state type."""
return cls.PREP_LAST_STATE_DESCRIPTIONS.get(state, "Unknown P-Rep last state")
[docs]class ICONPenaltyType:
PENALTY_TYPE_NO_PENALTY = 0
PENALTY_TYPE_PREP_DISQUALIFICATION = 1
PENALTY_TYPE_ACCUMULATED_BLOCK_VALIDATION_FAILURE = 2
PENALTY_TYPE_VALIDATION_FAILURE = 3
PENALTY_TYPE_MISSED_NETWORK_PROPOSAL_VOTE = 4
PENALTY_TYPE_DOUBLE_SIGN = 5
PENALTY_TYPE_DESCRIPTIONS = {
PENALTY_TYPE_NO_PENALTY: "No penalty",
PENALTY_TYPE_PREP_DISQUALIFICATION: "P-Rep disqualification penalty",
PENALTY_TYPE_ACCUMULATED_BLOCK_VALIDATION_FAILURE: "Accumulated block validation failure penalty",
PENALTY_TYPE_VALIDATION_FAILURE: "Validation failure penalty",
PENALTY_TYPE_MISSED_NETWORK_PROPOSAL_VOTE: "Missed Network Proposal vote penalty",
PENALTY_TYPE_DOUBLE_SIGN: "Double sign penalty"
}
[docs] @staticmethod
def get_penalty(penalty_type: int = 0):
"""
Return the description of the given penalty type.
:param penalty_type: The penalty type ID.
:return: Description string of the penalty type.
"""
penalty_type = ICONPenaltyType.convert_to_int(penalty_type)
return ICONPenaltyType.PENALTY_TYPE_DESCRIPTIONS.get(
penalty_type, "Unknown penalty type"
)
[docs] @staticmethod
def convert_to_int(value):
if isinstance(value, str) and value.startswith("0x"):
return int(value, 16)
return value
[docs]class ICONJailFlags:
ICON_IN_JAIL = 1
ICON_UN_JAILING = 2
ICON_ACCUMULATED_VALIDATION_FAILURE = 4
ICON_DOUBLE_SIGN = 8
FLAGS = {
'inJail': ICON_IN_JAIL,
'unJailing': ICON_UN_JAILING,
'accumulatedValidationFailure': ICON_ACCUMULATED_VALIDATION_FAILURE,
'doubleSign': ICON_DOUBLE_SIGN
}
[docs] @classmethod
def get_jail_flags(cls, value: int = 0, return_type="list"):
"""
Analyze the given value for jail flags and return the result as a list or string.
:param value: Integer value representing the jail flags.
:param return_type: Return type, either "list" (default) or "str".
:return: A list of flag names or a comma-separated string.
"""
value = ICONPenaltyType.convert_to_int(value)
analysis_result = [flag_name for flag_name, flag_value in cls.FLAGS.items() if value & flag_value]
if return_type == "str":
return ", ".join(analysis_result)
return analysis_result
[docs]class SpecialCharacterConstants:
SPECIAL_CHARACTERS = r"_*[]()~`>#+-=|{}.!\\"
ALL_SPECIAL_CHARACTERS = r"!@#$%^&*()_+-=[]{}|;:'\",.<>?/"
[docs]class HTTPConstants:
[docs] class MIMEType:
APPLICATION_JSON = "application/json"
APPLICATION_XML = "application/xml"
APPLICATION_PDF = "application/pdf"
APPLICATION_OCTET_STREAM = "application/octet-stream"
TEXT_PLAIN = "text/plain"
TEXT_HTML = "text/html"
TEXT_CSS = "text/css"
TEXT_JAVASCRIPT = "text/javascript"
IMAGE_JPEG = "image/jpeg"
IMAGE_PNG = "image/png"
IMAGE_GIF = "image/gif"
IMAGE_SVG = "image/svg+xml"
AUDIO_MP3 = "audio/mpeg"
AUDIO_WAV = "audio/wav"
VIDEO_MP4 = "video/mp4"
VIDEO_WEBM = "video/webm"
MULTIPART_FORM_DATA = "multipart/form-data"
APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded"
[docs] class HTTPStatusCodes:
OK = 200
CREATED = 201
ACCEPTED = 202
NO_CONTENT = 204
BAD_REQUEST = 400
UNAUTHORIZED = 401
FORBIDDEN = 403
NOT_FOUND = 404
METHOD_NOT_ALLOWED = 405
CONFLICT = 409
INTERNAL_SERVER_ERROR = 500
BAD_GATEWAY = 502
SERVICE_UNAVAILABLE = 503
[docs]class StringConstants:
EMPTY_STRING = ""
SPACE = " "
UNDERSCORE = "_"
DASH = "-"
COLON = ":"
SEMICOLON = ";"
COMMA = ","
PERIOD = "."
PIPE = "|"
NEWLINE = "\n"
TAB = "\t"
[docs]class FilePermissionConstants:
READ_ONLY = "r"
WRITE_ONLY = "w"
READ_WRITE = "r+"
APPEND = "a"
BINARY_READ = "rb"
BINARY_WRITE = "wb"
BINARY_READ_WRITE = "r+b"
BINARY_APPEND = "ab"
[docs]class RegexPatternConstants:
PATTERN_EMAIL = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
PATTERN_URL = r"^(https?|ftp)://[^\s/$.?#].[^\s]*$"
PATTERN_PHONE = r"^\+?1?\d{9,15}$"
PATTERN_POSTAL_CODE = r"^\d{5}(?:[-\s]\d{4})?$"
PATTERN_IP_ADDRESS = r"^(?!.*\.$)(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d|0)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d|0)){3}$"
PATTERN_IP_ADDRESS_IN_LOG = r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b"
PATTERN_CREDIT_CARD = r"^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$"
PATTERN_IPV6_ADDRESS = r"^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$"
PATTERN_HTML_TAG = r"<(\"[^\"]*\"|'[^']*'|[^'\">])*>"
PATTERN_SLUG = r"^[a-z0-9]+(?:-[a-z0-9]+)*$" # Matches URL slugs (e.g., valid-slug, another-slug)
PATTERN_INTEGER = r"^-?\d+$" # Matches integers, both positive and negative (e.g., 123, -456)
PATTERN_FLOAT = r"^-?\d*(\.\d+)?$" # Matches floating point numbers, both positive and negative (e.g., 123.45, -678.90)
PATTERN_DATE_YYYY_MM_DD = r"^\d{4}-\d{2}-\d{2}$" # Matches date format YYYY-MM-DD (e.g., 2023-09-10)
PATTERN_TIME_HH_MM_SS = r"^\d{2}:\d{2}:\d{2}$" # Matches time format HH:MM:SS (e.g., 14:32:00)
[docs]class TimeConstants:
MINUTE_IN_SECONDS = 60
HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS
DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS
WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS
MONTH_IN_SECONDS = 30 * DAY_IN_SECONDS
YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS
MILLISECOND_IN_SECONDS = 0.001
MICROSECOND_IN_SECONDS = 0.000001
NANOSECOND_IN_SECONDS = 0.000000001
HOUR_IN_MINUTES = 60
DAY_IN_MINUTES = HOUR_IN_MINUTES * 24
WEEK_IN_MINUTES = 7 * DAY_IN_MINUTES
MONTH_IN_MINUTES = 30 * DAY_IN_MINUTES
YEAR_IN_MINUTES = 365 * DAY_IN_MINUTES
[docs]class BooleanConstants:
TRUE = 1
FALSE = 0
[docs]class NumericConstants:
TINT = 10 ** 18
ICX_IN_LOOP = 10**18
EXA = 10 ** 18
PETA = 10 ** 15
TERA = 10 ** 12
GIGA = 10 ** 9
MEGA = 10 ** 6
KILO = 10 ** 3
MILLI = 10 ** -3
MICRO = 10 ** -6
NANO = 10 ** -9
SQRT_2 = 2 ** 0.5
EULER_MASCHERONI = 0.57721 # Euler-Mascheroni
PI = 3.14159
E = 2.71828
GOLDEN_RATIO = (1 + 5 ** 0.5) / 2
[docs]class UnitMultiplierConstants:
"""
Constants for data transfer units with standardized multipliers for conversions.
"""
BPS = 1
KBPS = 1024
MBPS = 1024 ** 2
GBPS = 1024 ** 3
TBPS = 1024 ** 4
BITS_PER_SECOND = 1 / 8
KILOBITS_PER_SECOND = 1024 / 8
MEGABITS_PER_SECOND = (1024 ** 2) / 8
GIGABITS_PER_SECOND = (1024 ** 3) / 8
TERABITS_PER_SECOND = (1024 ** 4) / 8
UNIT_MULTIPLIERS = {
"B/s": BPS,
"KB/s": KBPS,
"MB/s": MBPS,
"GB/s": GBPS,
"TB/s": TBPS,
"bps": BITS_PER_SECOND,
"Kbps": KILOBITS_PER_SECOND,
"Mbps": MEGABITS_PER_SECOND,
"Gbps": GIGABITS_PER_SECOND,
"Tbps": TERABITS_PER_SECOND,
}
[docs] @classmethod
def get_unit_multiplier(cls, unit: str) -> float:
"""
Retrieve the multiplier for the specified unit.
:param unit: The unit (e.g., "MB/s", "Kbps").
:return: Multiplier for converting to bytes.
"""
return cls.UNIT_MULTIPLIERS.get(unit, cls.BPS)
[docs]class AddressConstants:
ICON_ADDRESS = 42
ICON_ADDRESS_WITHOUT_PREFIX = 40
# CHAIN_SCORE_ADDRESS = f"cx{'0'*39}0"
# GOVERNANCE_ADDRESS = f"cx{'0'*39}1"
CHAIN_SCORE_ADDRESS = "cx0000000000000000000000000000000000000000"
GOVERNANCE_ADDRESS = "cx0000000000000000000000000000000000000001"
ETH_ADDRESS = 40 # Ethereum address length without '0x' prefix
ETH_ADDRESS_WITH_PREFIX = 42 # Ethereum address length with '0x' prefix
BTC_ADDRESS_P2PKH = 34 # Bitcoin P2PKH address length
BTC_ADDRESS_BECH32 = 42 # Bitcoin Bech32 address length
[docs]class TimeStampDigits:
SECONDS_DIGITS = 10
MILLI_SECONDS_DIGITS = 13
MICRO_SECONDS_DIGITS = 16
NANO_SECONDS_DIGITS = 19
PICO_SECONDS_DIGITS = 22
FEMTO_SECONDS_DIGITS = 25
[docs]class ICONConstants:
ICON_METHODS = {
"cx0000000000000000000000000000000000000001": [
"getRevision", "getVersion", "getStepPrice", "getStepCosts", "getMaxStepLimit",
"getScoreStatus", "acceptScore", "rejectScore", "addAuditor", "removeAuditor", "isInScoreBlackList",
"getProposal", "getProposals", "registerProposal", "voteProposal", "applyProposal",
"cancelProposal", "onTimer"
],
"cx0000000000000000000000000000000000000000": [
"disableScore", "enableScore", "acceptScore", "rejectScore", "blockScore", "unblockScore",
"getBlockedScores", "blockAccount", "unblockAccount", "isBlocked", "setRevision", "setStepPrice",
"setStepCost", "setMaxStepLimit", "getRevision", "getStepPrice", "getStepCost", "getStepCosts",
"getMaxStepLimit", "getScoreStatus", "getServiceConfig", "getFeeSharingConfig", "getNetworkInfo",
"getIISSInfo", "setStake", "getStake", "setDelegation", "getDelegation", "claimIScore",
"queryIScore", "registerPRep", "getPRep", "unregisterPRep", "setPRep", "getPReps", "getMainPReps",
"getSubPReps", "setBond", "getBond", "setBonderList", "getBonderList", "estimateUnstakeLockPeriod",
"getPRepTerm", "getPRepStats", "getPRepStatsOf", "disqualifyPRep", "burn", "validateRewardFund",
"setRewardFund", "setRewardFundAllocation2", "getScoreOwner", "setScoreOwner", "setNetworkScore",
"getNetworkScores", "addTimer", "removeTimer", "penalizeNonvoters", "setSlashingRates",
"getSlashingRates", "setUseSystemDeposit", "getUseSystemDeposit", "getBTPNetworkTypeID",
"getPRepNodePublicKey", "setPRepNodePublicKey", "registerPRepNodePublicKey", "openBTPNetwork",
"closeBTPNetwork", "sendBTPMessage", "getMinimumBond", "setMinimumBond", "initCommissionRate",
"setCommissionRate", "requestUnjail", "handleDoubleSignReport", "setPRepCountConfig",
"getPRepCountConfig", "setBondRequirementRate"
]
}
[docs]class HAVAHConstants:
HAVAH_METHODS = {
"cx0000000000000000000000000000000000000001": [
"setRevision", "setStepPrice", "setStepCost", "setMaxStepLimit", "grantValidator",
"revokeValidator", "setTimestampThreshold", "setRoundLimitFactor", "setUSDTPrice",
"setUSDTPriceOracle", "getUSDTPriceOracle", "addPlanetManager", "removePlanetManager",
"startRewardIssue", "setPrivateClaimableRate", "withdrawLostTo", "registerValidator",
"enableValidator", "unregisterValidator", "setBlockVoteCheckParameters", "setActiveValidatorCount",
"name", "openBTPNetwork", "delegate", "setDelegate"
],
"cx0000000000000000000000000000000000000000": [
"setRevision", "setStepPrice", "setStepCost", "setMaxStepLimit", "getRevision",
"getStepPrice", "getStepCost", "getStepCosts", "getMaxStepLimit", "getServiceConfig",
"getScoreOwner", "setScoreOwner", "setRoundLimitFactor", "getRoundLimitFactor", "setUSDTPrice",
"getUSDTPrice", "getIssueInfo", "startRewardIssue", "addPlanetManager", "removePlanetManager",
"isPlanetManager", "registerPlanet", "unregisterPlanet", "setPlanetOwner", "getPlanetInfo",
"reportPlanetWork", "claimPlanetReward", "getRewardInfoOf", "getRewardInfo",
"setPrivateClaimableRate", "getPrivateClaimableRate", "addDeployer", "removeDeployer", "isDeployer",
"getDeployers", "setTimestampThreshold", "getTimestampThreshold", "grantValidator",
"revokeValidator", "getValidators", "getRewardInfosOf", "withdrawLostTo", "getLost",
"getBTPNetworkTypeID", "getBTPPublicKey", "openBTPNetwork", "closeBTPNetwork", "sendBTPMessage",
"setBTPPublicKey", "setBlockVoteCheckParameters", "getBlockVoteCheckParameters",
"registerValidator", "unregisterValidator", "getNetworkStatus", "setValidatorInfo",
"setNodePublicKey", "enableValidator", "getValidatorInfo", "getValidatorStatus",
"setActiveValidatorCount", "getActiveValidatorCount", "getValidatorsOf", "getValidatorsInfo",
"getDisqualifiedValidatorsInfo"
]
}
[docs]class CryptographicConstants:
SHA256_DIGEST_SIZE = 32
SHA3_256_DIGEST_SIZE = 32
KECCAK_256_DIGEST_SIZE = 32
SECP256K1_PRIVATE_KEY_SIZE = 32
SECP256K1_PUBLIC_KEY_SIZE = 64
SECP256K1_SIGNATURE_SIZE = 64
ED25519_PRIVATE_KEY_SIZE = 32
ED25519_PUBLIC_KEY_SIZE = 32
ED25519_SIGNATURE_SIZE = 64
[docs]class NetworkConstants:
DEFAULT_HTTP_PORT = 80
DEFAULT_HTTPS_PORT = 443
DEFAULT_ICON_RPC_PORT = 9000
DEFAULT_ICON_P2P_PORT = 7100
DEFAULT_ETHEREUM_PORT = 8545
DEFAULT_BITCOIN_PORT = 8333
LOCALHOST = "127.0.0.1"
LOCALHOST_IPV6 = "::1"
IPV4_LOOPBACK = "127.0.0.1"
IPV6_LOOPBACK = "::1"
IPV4_BROADCAST = "255.255.255.255"
IPV6_BROADCAST = "ff02::1"
MAC_ADDRESS_BROADCAST = "ff:ff:ff:ff:ff:ff"
METADATA_IP = "169.254.169.254"
[docs]class AWSRegionConstants:
REGIONS = {
"us-east-1": "US East (N. Virginia)",
"us-east-2": "US East (Ohio)",
"us-west-1": "US West (N. California)",
"us-west-2": "US West (Oregon)",
"ca-central-1": "Canada (Central)",
"eu-west-1": "EU (Ireland)",
"eu-west-2": "EU (London)",
"eu-west-3": "EU (Paris)",
"eu-central-1": "EU (Frankfurt)",
"eu-north-1": "EU (Stockholm)",
"eu-south-1": "EU (Milan)",
"ap-southeast-1": "Asia Pacific (Singapore)",
"ap-southeast-2": "Asia Pacific (Sydney)",
"ap-northeast-1": "Asia Pacific (Tokyo)",
"ap-northeast-2": "Asia Pacific (Seoul)",
"ap-northeast-3": "Asia Pacific (Osaka)",
"ap-east-1": "Asia Pacific (Hong Kong)",
"ap-south-1": "Asia Pacific (Mumbai)",
"sa-east-1": "South America (São Paulo)",
"me-south-1": "Middle East (Bahrain)",
"af-south-1": "Africa (Cape Town)",
}
[docs] @staticmethod
def region_name(code: str) -> str:
"""
Get the human-readable name of an AWS region based on its code.
:param code: AWS region code (e.g., "us-east-1").
:return: Human-readable region name (e.g., "US East (N. Virginia)").
"""
return AWSRegionConstants.REGIONS.get(code, "Unknown region")
[docs] @staticmethod
def region_list() -> list:
"""
Get a list of all AWS region codes.
:return: List of AWS region codes.
"""
print(AWSRegionConstants.REGIONS.keys())
return list(AWSRegionConstants.REGIONS.keys())
[docs]class GradeMappingConstants:
GRADE_MAPPING = {
"0x0": {"name": "Main", "color": "[blue]\[Main][/blue]"},
"0x1": {"name": "Sub", "color": "[green]\[Sub][/green]"},
"0x2": {"name": "Cand", "color": "[Cand]"}
}
[docs] @staticmethod
def grade_name(grade_code: str) -> str:
"""
Get the name associated with the grade code.
:param grade_code: Grade code (e.g., "0x0").
:return: Grade name (e.g., "Main").
"""
return GradeMappingConstants.GRADE_MAPPING.get(grade_code, {}).get("name", "Unknown grade")
[docs] @staticmethod
def grade_color(grade_code: str) -> str:
"""
Get the color representation associated with the grade code.
:param grade_code: Grade code (e.g., "0x0").
:return: Color representation (e.g., "[blue]\\[Main][/blue]").
"""
return GradeMappingConstants.GRADE_MAPPING.get(grade_code, {}).get("color", "Unknown color")
[docs]class YesNoConstants:
YES_NO_MAPPING = {
"0x0": "no",
"0x1": "yes"
}
[docs] @staticmethod
def yes_no(grade_code: str) -> str:
"""
Get 'yes' or 'no' based on the grade code.
:param grade_code: Grade code (e.g., "0x0" for 'no', "0x1" for 'yes').
:return: 'yes' or 'no'.
"""
return YesNoConstants.YES_NO_MAPPING.get(grade_code, "Unknown code")
[docs]class LoggingConstants:
"""
Constants related to logging levels and verbosity mappings.
"""
VERBOSE_LEVELS = {
# 0: logging.CRITICAL,
# 1: logging.ERROR,
0: logging.WARNING,
1: logging.INFO,
2: logging.DEBUG,
3: 5
}
VERBOSE_LEVEL_STRINGS = {
# 0: logging.CRITICAL,
# 1: logging.ERROR,
0: "WARNING",
1: "INFO",
2: "DEBUG",
3: "TRACE",
}
LOG_LEVELS = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL,
"TRACE": 5,
}
LEVEL_NAMES = {v: k for k, v in LOG_LEVELS.items()}
[docs] @staticmethod
def get_level(name: str) -> logging.Logger:
return LoggingConstants.LOG_LEVELS.get(str(name).upper())
[docs] @staticmethod
def get_level_keys() -> list:
return list(LoggingConstants.LOG_LEVELS.keys())
# @staticmethod
# def get_level_name(level: int) -> str:
# """Return the string representation of a log level."""
# return LoggingConstants.LEVEL_NAMES.get(level, "UNKNOWN")
[docs] @staticmethod
def get_level_name(verbose: int) -> str:
"""
Retrieve the log level string for a given verbosity level.
- If the key is less than 0 or not found, return the 0's value.
- If the key exceeds the maximum, return the maximum key's value.
"""
log_level_string = LoggingConstants.VERBOSE_LEVEL_STRINGS
if verbose < 0:
return log_level_string[0]
max_key = max(log_level_string.keys())
return log_level_string.get(verbose, log_level_string[max_key])
[docs]class TerminalColor:
"""
Extended ANSI escape sequences for coloring terminal text with more color options.
"""
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
GREEN = '\033[32;40m'
CYAN = '\033[96m'
WARNING = '\033[93m'
FAIL = '\033[91m'
RESET = '\033[0m'
ENDC = '\033[0m'
BOLD = '\033[1m'
ITALIC = '\033[1;3m'
UNDERLINE = '\033[4m'
WHITE = '\033[97m'
DARK_GREY = '\033[38;5;243m'
LIGHT_GREY = '\033[37m'
# More colorful options
RED = '\033[31m'
BLUE = '\033[34m'
YELLOW = '\033[33m'
MAGENTA = '\033[35m'
PURPLE = '\033[35;1m'
ORANGE = '\033[38;5;214m'
BRIGHT_GREEN = '\033[92;1m'
BRIGHT_CYAN = '\033[96;1m'
BRIGHT_MAGENTA = '\033[95;1m'
DARK_BLUE = '\033[34;2m'
LIGHT_BLUE = '\033[94;1m'
LIGHT_YELLOW = '\033[93m'
[docs] @staticmethod
def get_color(color_name):
"""
Return the color escape sequence based on the given color name.
:param color_name: The name of the color (as a string).
:return: The ANSI color code string.
"""
return getattr(TerminalColor, color_name.upper(), TerminalColor.RESET)
[docs]def apply_terminal_color(text, color="WHITE", bold=False, underline=False, width=None):
"""
Apply the given color and style to the text and return the formatted string.
:param text: The text to be styled.
:param color: The color to apply (e.g., 'GREEN', 'RED', etc.).
:param bold: Whether to apply bold formatting.
:param underline: Whether to apply underline formatting.
:param width: The width to center the text (optional).
:return: The styled text as a string.
"""
if width and len(text) < width:
text = text.center(width, ' ')
color_code = TerminalColor.get_color(color)
if bold:
text = f"{TerminalColor.BOLD}{text}"
if underline:
text = f"{TerminalColor.UNDERLINE}{text}"
return f"{color_code}{text}{TerminalColor.ENDC}"
[docs]class HTTPMethodConstants:
ALLOWS_HTTP_METHOD = ["GET", "POST", "PATCH", "DELETE", "HEAD", "PUT", "CONNECT", "OPTIONS", "TRACE"]
[docs] @classmethod
def get_http_methods(cls, lowercase: bool = False):
"""
Returns the list of allowed HTTP methods.
:param lowercase: If True, return methods in lowercase.
:return: List of allowed HTTP methods in uppercase or lowercase.
"""
if lowercase:
return [method.lower() for method in cls.ALLOWS_HTTP_METHOD]
return cls.ALLOWS_HTTP_METHOD
[docs] @classmethod
def is_valid_http_method(cls, method: str) -> bool:
"""
Check if the given method is a valid HTTP method (case-insensitive).
:param method: HTTP method to validate.
:return: True if the method is valid, False otherwise.
"""
return method.upper() in cls.ALLOWS_HTTP_METHOD
[docs]class OperatorConstants:
ALLOW_OPERATOR = ["!=", "==", ">=", "<=", ">", "<", "include", "exclude"]
[docs] @classmethod
def get_allowed_operators(cls):
"""Returns the list of allowed operators."""
return cls.ALLOW_OPERATOR
[docs] @classmethod
def is_valid_operator(cls, operator: str) -> bool:
"""Check if the given operator is valid."""
return operator in cls.ALLOW_OPERATOR
[docs]class SecretPatternConstants:
"""Constants for detecting secret keys and tokens in text."""
SECRET_PATTERNS = {
"slack_token": r"xox[bp]-[0-9]{10,}-[a-zA-Z0-9]{20,}",
"aws_access_key": r"AKIA[0-9A-Z]{16}",
"aws_secret_key": r"\b[A-Za-z0-9+/]{40}\b",
"generic_key": r"(?:key|token|secret)\s*=\s*['\"]?[a-zA-Z0-9\-]{20,}['\"]?",
"github_pat": r"ghp_[0-9A-Za-z]{36}",
"google_api_key": r"AIza[0-9A-Za-z-_]{35}",
"stripe_api_key": r"(sk|pk|rk)_[live|test]_[0-9A-Za-z]{24}",
"jwt_token": r"eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+",
"ssh_private_key": r"-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----[\s\S]+-----END (RSA|OPENSSH|EC) PRIVATE KEY-----",
"db_connection_string": r"(mysql|postgres|mongodb|redis)://[a-zA-Z0-9_]+:[a-zA-Z0-9_]+@[a-zA-Z0-9\-.]+:\d+(/[a-zA-Z0-9_]+)?",
"discord_bot_token": r"[A-Za-z0-9]{24}\.[A-Za-z0-9]{6}\.[A-Za-z0-9-_]{27}",
"twilio_api_key": r"SK[0-9a-f]{32}",
# "general_api_key": r"[A-Za-z0-9]{32,64}",
"general_api_key": r"(?!hx|cx)[A-Za-z0-9]{32,64}",
"env_style_key": r"[A-Z_]+_KEY=[A-Za-z0-9\-]{20,}"
}
SECRET_DESCRIPTIONS = {
"slack_token": "Slack API Token (Bot or User)",
"aws_access_key": "AWS Access Key ID",
"aws_secret_key": "AWS Secret Access Key",
"generic_key": "Generic key, token, or secret pattern",
"github_pat": "GitHub Personal Access Token",
"google_api_key": "Google API Key",
"stripe_api_key": "Stripe API Key (Secret, Publishable, or Restricted)",
"jwt_token": "JSON Web Token (JWT)",
"ssh_private_key": "SSH Private Key (RSA, OpenSSH, or EC)",
"db_connection_string": "Database Connection String (MySQL, PostgreSQL, MongoDB, Redis)",
"discord_bot_token": "Discord Bot Token",
"twilio_api_key": "Twilio API Secret Key",
"general_api_key": "General-purpose API Key (32-64 characters)",
"env_style_key": "Environment Variable Style Key (e.g., API_KEY=xxx)"
}
[docs] @classmethod
def get_pattern(cls, secret_type: str) -> str:
"""
Retrieve the regex pattern for the specified secret type.
:param secret_type: Type of secret (e.g., 'slack_token').
:return: Regex pattern string.
"""
return cls.SECRET_PATTERNS.get(secret_type, "")
[docs] @classmethod
def get_description(cls, secret_type: str) -> str:
"""
Retrieve the description for the specified secret type.
:param secret_type: Type of secret (e.g., 'slack_token').
:return: Description string.
"""
return cls.SECRET_DESCRIPTIONS.get(secret_type, "Unknown secret type")
[docs] @classmethod
def list_patterns(cls) -> dict:
"""
Return all secret patterns and their descriptions.
:return: Dictionary of patterns and descriptions.
"""
return {key: {"pattern": cls.SECRET_PATTERNS[key], "description": cls.SECRET_DESCRIPTIONS[key]}
for key in cls.SECRET_PATTERNS}
[docs]class AllConstants(
ICONPRepStatus,
ICONJailFlags,
SpecialCharacterConstants,
# HTTPStatusCodes,
RegexPatternConstants,
HTTPConstants,
DateFormatConstants,
StringConstants,
FilePermissionConstants,
TimeConstants,
# MediaTypeConstants,
BooleanConstants,
NumericConstants,
UnitMultiplierConstants,
AddressConstants,
TimeStampDigits,
ICONConstants,
HAVAHConstants,
CryptographicConstants,
NetworkConstants,
AWSRegionConstants,
GradeMappingConstants,
YesNoConstants,
LoggingConstants,
HTTPMethodConstants,
OperatorConstants,
SecretPatternConstants,
):
__slots__ = ()
def __setattr__(self, name, value):
raise TypeError("Constants are read-only")
def __getattr__(self, name):
if name in globals():
return globals()[name]
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
[docs] def get_aws_region_name(self, code: str = "") -> str:
return self.region_name(code)
[docs] def get_aws_region_list(self) -> list:
return self.region_list()
[docs] @staticmethod
def get_colored_text(text, color="WHITE", bold=False, underline=False, width=None):
"""
Helper method to get colored text using the ANSI color codes.
"""
return apply_terminal_color(text, color, bold, underline, width)
[docs] @staticmethod
def available_colors():
"""
Return a list of all available color names.
"""
return [color for color in dir(TerminalColor) if not color.startswith('__') and color.isupper()]
const = AllConstants()