Skip to main content

Python library for 4writers.net automation

Project description

py4writers

PyPI version Python 3.12+

Python библиотека для автоматизации работы с 4writers.net - асинхронный API для получения заказов, управления файлами и взаимодействия с платформой.

✨ Основные возможности

  • 🔐 Авторизация - автоматическая авторизация и управление сессией
  • 📋 Получение заказов - доступные заказы (free orders) и выполненные (completed orders)
  • 📄 Работа с файлами - получение списка файлов и скачивание
  • 🔄 Retry механизм - автоматические повторные попытки при ошибках сети
  • Rate limiting - контроль параллельных запросов (до 10 одновременно)
  • 🎯 Context manager - автоматическое управление ресурсами через async with
  • 🛡️ Type hints - полная типизация для IDE autocomplete
  • 📊 Детальное логирование - отслеживание всех операций

📦 Установка

pip install py4writers

Или через poetry:

poetry add py4writers

🚀 Быстрый старт

Базовый пример

import asyncio
from py4writers import API

async def main():
    # Используем context manager для автоматического закрытия ресурсов
    async with API(login="your_login", password="your_password") as api:
        # Авторизация
        await api.login()

        # Получаем доступные заказы
        orders = await api.get_orders(page=1, page_size=50)

        for order in orders:
            print(f"📦 {order.order_id}: {order.title}")
            print(f"💰 ${order.total:.2f} | ⏰ {order.deadline}")
            if order.description:
                print(f"📝 {order.description[:100]}...")

if __name__ == "__main__":
    asyncio.run(main())

Использование с .env файлом

import asyncio
from py4writers import API
from envparse import env

# Загружаем переменные окружения
env.read_envfile(".env")
LOGIN = env.str("LOGIN")
PASSWORD = env.str("PASSWORD")

async def main():
    async with API(login=LOGIN, password=PASSWORD) as api:
        await api.login()
        orders = await api.get_orders()
        print(f"Найдено заказов: {len(orders)}")

asyncio.run(main())

📚 Примеры использования

1. Получение доступных заказов

async with API(login=LOGIN, password=PASSWORD) as api:
    await api.login()

    # Получить заказы с пагинацией
    orders = await api.get_orders(
        page=1,
        page_size=50,
        category="essay"
    )

    for order in orders:
        print(f"Order #{order.order_id}")
        print(f"  Название: {order.title}")
        print(f"  Тема: {order.subject}")
        print(f"  Тип: {order.order_type}")
        print(f"  Уровень: {order.academic_level}")
        print(f"  Страниц: {order.pages}")
        print(f"  Источников: {order.sources}")
        print(f"  Стиль: {order.style}")
        print(f"  Язык: {order.language}")
        print(f"  Дедлайн: {order.deadline}")
        print(f"  Осталось времени: {order.remaining}")
        print(f"  Зарплата: ${order.salary:.2f}")
        print(f"  Бонус: ${order.bonus:.2f}")
        print(f"  Всего: ${order.total:.2f}")
        print(f"  Описание: {order.description}")
        print()

2. Получение выполненных заказов

async with API(login=LOGIN, password=PASSWORD) as api:
    await api.login()

    # Получаем выполненные заказы
    completed = await api.get_completed_orders(page=1)

    for order in completed:
        print(f"✅ Order #{order.order_id}")
        print(f"  Название: {order.title}")
        print(f"  Ваша выплата: ${order.your_payment:.2f}")
        print(f"  Работа редактора: ${order.editor_work:.2f}")
        print(f"  Страниц: {order.pages}")
        print(f"  Описание: {order.description}")
        print(f"  Файлов: {len(order.files) if order.files else 0}")
        print()

3. Работа с файлами

async with API(login=LOGIN, password=PASSWORD) as api:
    await api.login()

    # Получаем список файлов заказа
    files = await api.get_order_files(order_index=2569038)

    for file in files:
        print(f"📁 {file.name}")
        print(f"  ID: {file.id}")
        print(f"  Автор: {file.author}")
        print(f"  Дата: {file.date}")

        # Скачиваем файл
        file_bytes = await api.download_file(file.id)

        if file_bytes:
            # Сохраняем на диск
            with open(f"downloaded_{file.name}", "wb") as f:
                f.write(file_bytes)
            print(f"  ✅ Скачан: {len(file_bytes):,} байт")

4. Получение деталей заказа

async with API(login=LOGIN, password=PASSWORD) as api:
    await api.login()

    # Для обычного заказа
    description = await api.fetch_order_details(
        order_index=2569038,
        is_completed=False
    )

    # Для выполненного заказа
    description = await api.fetch_order_details(
        order_index=2569038,
        is_completed=True
    )

    print(f"Описание: {description}")

5. Взятие заказа в работу

async with API(login=LOGIN, password=PASSWORD) as api:
    await api.login()

    # Берем заказ по индексу
    success = await api.take_order(order_index=2569038)

    if success:
        print("✅ Заказ успешно взят!")
    else:
        print("❌ Не удалось взять заказ")

📊 Модели данных

Order

@dataclass
class Order:
    order_id: str           # ID заказа
    order_index: int        # Индекс заказа (для запросов)
    title: str              # Название
    subject: str            # Тема
    deadline: str           # Дедлайн
    remaining: str          # Оставшееся время
    order_type: str         # Тип работы (Essay, Research Paper, etc.)
    academic_level: str     # Академический уровень
    style: str              # Стиль оформления (APA, MLA, etc.)
    language: str           # Язык
    pages: Optional[int]    # Количество страниц
    sources: Optional[int]  # Количество источников
    salary: Optional[float] # Зарплата
    bonus: Optional[float]  # Бонус
    total: Optional[float]  # Итого
    description: Optional[str]      # Описание заказа
    files: Optional[List[File]]     # Файлы заказа
    editor_work: Optional[float]    # Работа редактора (completed)
    your_payment: Optional[float]   # Ваша выплата (completed)

File

@dataclass
class File:
    id: int         # ID файла
    name: str       # Название файла
    author: str     # Автор загрузки
    date: str       # Дата загрузки

⚙️ Конфигурация

Создание API клиента

from py4writers import API

# С credentials
api = API(login="user", password="pass")

# С кастомным HTTP клиентом
from py4writers.client.aiohttp import AiohttpClient

http_client = AiohttpClient(timeout=60)
api = API(
    login="user",
    password="pass",
    http_client=http_client
)

# Context manager (рекомендуется)
async with API(login="user", password="pass") as api:
    await api.login()
    # ваш код

Настройка логирования

import logging

# Базовая настройка
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Детальное логирование
logging.basicConfig(level=logging.DEBUG)

🛡️ Обработка ошибок

from py4writers import API
from py4writers.exceptions import (
    AuthenticationError,
    SessionExpiredError,
    NetworkError,
    ParsingError
)

async with API(login=LOGIN, password=PASSWORD) as api:
    try:
        await api.login()
        orders = await api.get_orders()

    except AuthenticationError as e:
        print(f"❌ Ошибка авторизации: {e}")

    except SessionExpiredError as e:
        print(f"⏰ Сессия истекла: {e}")
        # API автоматически попытается переавторизоваться

    except NetworkError as e:
        print(f"🌐 Сетевая ошибка: {e}")
        # Retry декоратор автоматически повторит запрос

    except ParsingError as e:
        print(f"📄 Ошибка парсинга: {e}")

🔧 Продвинутые возможности

Rate Limiting

API автоматически ограничивает количество параллельных запросов (по умолчанию 10):

from py4writers.utils.rate_limiter import RateLimiter

# Кастомный лимит
rate_limiter = RateLimiter(max_concurrent=5)
api = API(
    login=LOGIN,
    password=PASSWORD,
    rate_limiter=rate_limiter
)

Retry механизм

Используйте декоратор для автоматических повторных попыток:

from py4writers.utils.retry import async_retry
from py4writers.exceptions import NetworkError

@async_retry(
    max_attempts=3,
    delay=1.0,
    backoff=2.0,
    exceptions=(NetworkError,)
)
async def my_function():
    # ваш код
    pass

📝 Требования

  • Python 3.12+
  • aiohttp
  • beautifulsoup4
  • lxml
  • certifi

🔄 Changelog

[0.6.1] - 2026-01-17

🔧 Fixed

  • Исправлен парсинг описаний для completed orders
  • Добавлен отдельный endpoint для completed order details

[0.6.0] - 2026-01-17

✨ Added

  • Context Manager Support
  • Custom Exceptions
  • Retry Logic
  • Rate Limiting
  • OrderParser Class
  • Pagination Support
  • Better Logging

🔧 Fixed

  • Resource Leak в AiohttpClient
  • Session Expiration handling
  • BeautifulSoup warnings
  • Code duplication (200+ строк)

📄 Лицензия

MIT License

🤝 Контрибьюция

Pull requests приветствуются! Для больших изменений сначала откройте issue для обсуждения.

📧 Контакты

⭐ Поддержка

Если библиотека была полезна, поставьте звезду на GitHub!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py4writers-0.7.0.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py4writers-0.7.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file py4writers-0.7.0.tar.gz.

File metadata

  • Download URL: py4writers-0.7.0.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.12.3 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for py4writers-0.7.0.tar.gz
Algorithm Hash digest
SHA256 27fb3b9b235f16077976686b6aa543f2f68de40bf26d899a8d20b274ec2474e8
MD5 805c2e396a2c091e8be04a23dc681bd1
BLAKE2b-256 acff666306371fa842cd45490e28f406b891660ba6285782b714afbd91a2136a

See more details on using hashes here.

File details

Details for the file py4writers-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: py4writers-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.12.3 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for py4writers-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa26adf054ca3db7eb5c83e0a7c148fb71b4fb0a77490064b2dc43257602005b
MD5 cdd70a08f88c34381000892c5c92e294
BLAKE2b-256 c751c8181eee23ffcf363312c52a92c3a614640a2178957048c4b7eec62d7077

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page