Перейти к содержанию

Расширение библиотеки

В этом разделе описано, как расширить функциональность библиотеки FUCKTAR, создавая собственные паттерны, генераторы и другие компоненты.

Создание пользовательских паттернов

Самый распространенный способ расширения библиотеки - создание собственных паттернов для генерации специфических данных.

Базовый паттерн

Для создания пользовательского паттерна нужно унаследоваться от BasePattern:

from fucktar.generator import BasePattern
from fucktar.config import PatternConfig

@dataclass
class Product:
    name: str
    price: float
    category: str
    in_stock: bool

class ProductPatterns(BasePattern[Product]):
    # Пользовательские регулярные выражения
    name = r"^[A-Z][a-z]{5,20} [A-Z][a-z]{3,15}$"
    price = r"^\d{1,4}\.\d{2}$"  # Цена в формате 0.00 - 9999.99
    category = r"^(electronics|clothing|books|home)$"
    in_stock = r"^(True|False)$"  # Булево значение как строка

    pattern_config = PatternConfig(
        scope="products",
        unique_fields=["name"]  # Уникальность по названию продукта
    )

Комбинирование с встроенными паттернами

Вы можете комбинировать собственные паттерны с встроенными:

from fucktar.default_patterns.users import UserRuPatterns
from fucktar.default_patterns.network import NetworkPatterns

class CustomUserPatterns(BasePattern[User]):
    # Используем встроенные паттерны
    first_name = UserRuPatterns.first_name
    last_name = UserRuPatterns.last_name
    email = UserRuPatterns.email
    phone = UserRuPatterns.phone
    ipv4 = NetworkPatterns.ipv4

    # Добавляем собственные паттерны
    custom_field = r"^[A-Z]{3}-\d{3}$"

    pattern_config = PatternConfig(
        scope="custom_users",
        unique_fields=["email", "custom_field"]
    )

Создание пользовательских встроенных паттернов

Вы можете создать собственный модуль с встроенными паттернами:

# my_patterns/company.py
class CompanyPatterns:
    """Паттерны для данных компании."""

    company_name = r"^[A-Z][a-z]{5,20} (LLC|Inc|Corp)$"
    ein = r"^\d{2}-\d{7}$"  # Employer Identification Number
    industry = r"^(technology|finance|healthcare|education|retail)$"

# my_patterns/finance.py
class FinancePatterns:
    """Финансовые паттерны."""

    currency_code = r"^(USD|EUR|RUB|GBP|JPY)$"
    account_number = r"^\d{10,15}$"
    routing_number = r"^\d{9}$"

Использование:

from my_patterns.company import CompanyPatterns
from my_patterns.finance import FinancePatterns

class CompanyPatterns(BasePattern[Company]):
    company_name = CompanyPatterns.company_name
    ein = CompanyPatterns.ein
    industry = CompanyPatterns.industry
    currency = FinancePatterns.currency_code

    pattern_config = PatternConfig(
        scope="companies",
        unique_fields=["ein"]
    )

Расширение существующих паттернов

Вы можете расширить существующие паттерны, добавляя новые поля:

class ExtendedUserRuPatterns(UserRuPatterns):
    """Расширенные паттерны для пользователей из РФ."""

    # Добавляем новые паттерны
    driver_license = r"^\d{2} \d{2} \d{6}$"
    medical_policy = r"^\d{16}$"
    snils_extended = r"^\d{3}-\d{3}-\d{3} \d{2}$"

Создание пользовательских генераторов

В редких случаях может потребоваться создание собственного генератора:

from fucktar.generator import ModelGenerator

class CustomModelGenerator(ModelGenerator[T]):
    """Пользовательский генератор с дополнительной логикой."""

    def __init__(
        self, model: type[T], patterns: dict[str, str], defaults: dict[str, Any]
    ) -> None:
        super().__init__(model, patterns, defaults)
        # Добавляем свою инициализацию

    def generate(self) -> T:
        # Добавляем свою логику перед генерацией
        obj = super().generate()
        # Добавляем свою логику после генерации
        return obj

Создание пользовательских сервисов

Вы можете создать собственные сервисы для дополнительной обработки данных:

class DataProcessingService:
    """Сервис для дополнительной обработки сгенерированных данных."""

    @staticmethod
    def enrich_user_data(user: User) -> User:
        """Обогащает данные пользователя дополнительной информацией."""
        # Добавляем возраст на основе даты рождения
        # Добавляем адрес на основе города
        # И т.д.
        return user

Использование:

users = UserPatterns().generate(count=100)
enriched_users = [DataProcessingService.enrich_user_data(user) for user in users]

Создание пользовательских исключений

Для специфических ошибок можно создать собственные исключения:

from fucktar.exceptions import GeneratorError

class CustomValidationError(GeneratorError):
    """Ошибка валидации пользовательских данных."""

    def __init__(self, message: str, field: str) -> None:
        super().__init__(message)
        self.field = field

Интеграция с внешними библиотеками

Вы можете интегрировать FUCKTAR с внешними библиотеками для расширения функциональности:

import faker
from fucktar.generator import BasePattern

class FakerIntegrationPattern(BasePattern[User]):
    """Паттерн, использующий Faker для генерации данных."""

    def __init__(self) -> None:
        super().__init__()
        self.faker = faker.Faker('ru_RU')

    def generate(self, count: int = 1) -> User | list[User]:
        if count == 1:
            return User(
                first_name=self.faker.first_name(),
                last_name=self.faker.last_name(),
                email=self.faker.email(),
                phone=self.faker.phone_number(),
                # Преобразуем IPv4Address в строку
                ipv4=str(self.faker.ipv4())
            )
        else:
            return [self.generate() for _ in range(count)]

Рекомендации по расширению

  1. Используйте существующие паттерны как основу для создания собственных
  2. Следуйте соглашениям об именовании, принятым в библиотеке
  3. Документируйте свои расширения
  4. Пишите тесты для своих расширений
  5. Используйте типизацию для обеспечения безопасности кода
  6. При интеграции с внешними библиотеками учитывайте их лицензии
  7. Создавайте переиспользуемые компоненты, которые могут быть полезны другим разработчикам