From 2cc79204bf824d611eec9ed1e0b512e777c539bc Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 22 Mar 2026 21:06:21 +0000 Subject: [PATCH] Initial upload: mockapi - OpenAPI Mock Server Generator --- src/mockapi/core/config.py | 160 +++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/mockapi/core/config.py diff --git a/src/mockapi/core/config.py b/src/mockapi/core/config.py new file mode 100644 index 0000000..e14c829 --- /dev/null +++ b/src/mockapi/core/config.py @@ -0,0 +1,160 @@ +"""Configuration management for MockAPI.""" + +import os +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Dict, Optional + +import yaml + + +@dataclass +class Config: + """MockAPI configuration.""" + + port: int = 8080 + host: str = "0.0.0.0" + delay: int = 0 + random_delay: bool = False + seed: Optional[int] = 42 + validate_requests: bool = True + validate_responses: bool = False + strict_validation: bool = False + error_probability: float = 0.0 + error_code: int = 500 + + config_path: Optional[str] = None + + @classmethod + def load(cls, config_path: Optional[str] = None) -> "Config": + """Load configuration from file and environment. + + Args: + config_path: Path to mockapi.yaml config file + + Returns: + Config instance with loaded values + """ + config = cls() + + if config_path: + config.config_path = config_path + file_config = cls._load_from_file(config_path) + for key, value in file_config.items(): + if value is not None: + setattr(config, key, value) + else: + default_paths = ["mockapi.yaml", "mockapi.yml"] + for path in default_paths: + if Path(path).exists(): + file_config = cls._load_from_file(path) + for key, value in file_config.items(): + if value is not None: + setattr(config, key, value) + break + + env_config = cls._load_from_env() + for key, value in env_config.items(): + if value is not None: + setattr(config, key, value) + + return config + + @classmethod + def _load_from_env(cls) -> Dict[str, Any]: + """Load configuration from environment variables. + + Returns: + Dictionary of configuration values + """ + config = {} + + if port := os.environ.get("MOCKAPI_PORT"): + try: + config["port"] = int(port) + except ValueError: + pass + + if host := os.environ.get("MOCKAPI_HOST"): + config["host"] = host + + if seed := os.environ.get("MOCKAPI_SEED"): + try: + config["seed"] = int(seed) + except ValueError: + pass + + return config + + @classmethod + def _load_from_file(cls, config_path: str) -> Dict[str, Any]: + """Load configuration from YAML file. + + Args: + config_path: Path to the config file + + Returns: + Dictionary of configuration values + """ + try: + with open(config_path, "r") as f: + data = yaml.safe_load(f) or {} + + config = {} + + if "port" in data: + config["port"] = data["port"] + if "host" in data: + config["host"] = data["host"] + if "delay" in data: + config["delay"] = data["delay"] + if "random_delay" in data: + config["random_delay"] = data["random_delay"] + if "seed" in data: + config["seed"] = data["seed"] + if "validate_requests" in data: + config["validate_requests"] = data["validate_requests"] + if "validate_responses" in data: + config["validate_responses"] = data["validate_responses"] + if "strict_validation" in data: + config["strict_validation"] = data["strict_validation"] + if "error_probability" in data: + config["error_probability"] = data["error_probability"] + if "error_code" in data: + config["error_code"] = data["error_code"] + + return config + + except Exception: + return {} + + def to_dict(self) -> Dict[str, Any]: + """Convert config to dictionary. + + Returns: + Dictionary representation of config + """ + return { + "port": self.port, + "host": self.host, + "delay": self.delay, + "random_delay": self.random_delay, + "seed": self.seed, + "validate_requests": self.validate_requests, + "validate_responses": self.validate_responses, + "strict_validation": self.strict_validation, + "error_probability": self.error_probability, + "error_code": self.error_code, + } + + +def load_config(config_path: Optional[str] = None) -> Config: + """Load configuration from file and environment. + + Args: + config_path: Optional path to config file + + Returns: + Config instance + """ + return Config.load(config_path)