Skip to content

Architecture β€” kwork-api

πŸ“ ΠžΠ±Π·ΠΎΡ€

kwork-api β€” асинхронный Python ΠΊΠ»ΠΈΠ΅Π½Ρ‚ для Kwork.ru API с ΠΏΠΎΠ»Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ.


πŸ—οΈ АрхитСктура

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    User Application                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   KworkClient                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Authentication Layer                             β”‚  β”‚
β”‚  β”‚  - login() / token auth                           β”‚  β”‚
β”‚  β”‚  - Session management                             β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  API Groups                                       β”‚  β”‚
β”‚  β”‚  - catalog, projects, user, reference, ...       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  HTTP Layer (httpx)                               β”‚  β”‚
β”‚  β”‚  - HTTP/2 support                                 β”‚  β”‚
β”‚  β”‚  - Timeout handling                               β”‚  β”‚
β”‚  β”‚  - Error handling                                 β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Kwork.ru API (HTTPS)                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

kwork-api/
β”œβ”€β”€ src/kwork_api/
β”‚   β”œβ”€β”€ __init__.py          # Public API
β”‚   β”œβ”€β”€ client.py            # KworkClient + API groups
β”‚   β”œβ”€β”€ models.py            # Pydantic models
β”‚   └── errors.py            # Exception classes
β”‚
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ test_client.py       # Client tests
β”‚   β”œβ”€β”€ test_models.py       # Model tests
β”‚   └── test_all_endpoints.py # Endpoint tests
β”‚
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ index.md             # Quick start
β”‚   β”œβ”€β”€ api-reference.md     # API docs
β”‚   β”œβ”€β”€ RELEASE.md           # Release guide
β”‚   └── ARCHITECTURE.md      # This file
β”‚
β”œβ”€β”€ .github/workflows/
β”‚   └── ci.yml               # CI/CD pipeline
β”‚
β”œβ”€β”€ pyproject.toml           # Project config
β”œβ”€β”€ uv.lock                  # Dependencies lock
└── README.md                # Main documentation

πŸ”‘ ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹

1. KworkClient

ΠžΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: ОсновноС взаимодСйствиС с API

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ: - АутСнтификация (login / token) - Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ сСссиСй - Π”Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ API Π³Ρ€ΡƒΠΏΠΏΠ°ΠΌ

API Groups:

client.catalog      # CatalogAPI
client.projects     # ProjectsAPI
client.user         # UserAPI
client.reference    # ReferenceAPI
client.notifications # NotificationsAPI
client.other        # OtherAPI


2. Models (Pydantic)

ΠžΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: Валидация ΠΈ типизация ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² API

ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ: - User models: KworkUser, AuthResponse - Kwork models: Kwork, KworkDetails, KworkCategory - Project models: Project, ProjectsResponse - Review models: Review, ReviewsResponse - Notification models: Notification, Dialog - Reference models: City, Country, TimeZone, Feature, Badge - Error models: ErrorDetail, APIErrorResponse


3. Errors

ΠžΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок API

Π˜Π΅Ρ€Π°Ρ€Ρ…ΠΈΡ:

KworkError (base)
β”œβ”€β”€ KworkAuthError      # 401, 403
β”œβ”€β”€ KworkApiError       # 4xx, 5xx
β”‚   β”œβ”€β”€ KworkNotFoundError    # 404
β”‚   β”œβ”€β”€ KworkRateLimitError   # 429
β”‚   └── KworkValidationError  # 400
└── KworkNetworkError   # Network issues


4. HTTP Layer (httpx)

ΠžΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ: HTTP запросы

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ: - HTTP/2 ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° - Π’Π°ΠΉΠΌΠ°ΡƒΡ‚Ρ‹ - Cookies management - Token authentication - Error handling


πŸ”„ Flow: АутСнтификация

User β†’ KworkClient.login(username, password)
                β”‚
                β–Ό
        POST /signIn (cookies)
                β”‚
                β–Ό
        POST /getWebAuthToken (token)
                β”‚
                β–Ό
        Store token + cookies
                β”‚
                β–Ό
        Return authenticated client

πŸ”„ Flow: API Request

User β†’ client.catalog.get_list(page=1)
                β”‚
                β–Ό
        CatalogAPI.get_list()
                β”‚
                β–Ό
        KworkClient._request()
                β”‚
                β–Ό
        httpx.AsyncClient.post()
                β”‚
                β–Ό
        KworkClient._handle_response()
                β”‚
                β–Ό
        CatalogResponse.model_validate()
                β”‚
                β–Ό
        Return typed response

πŸš€ CI/CD Pipeline

Push/Tag β†’ GitHub Actions
    β”‚
    β”œβ”€β”€ Test Job
    β”‚   β”œβ”€β”€ Install UV + Python
    β”‚   β”œβ”€β”€ Run linters (ruff)
    β”‚   β”œβ”€β”€ Run tests (pytest)
    β”‚   └── Upload coverage
    β”‚
    β”œβ”€β”€ Build Job
    β”‚   β”œβ”€β”€ Build wheel + sdist
    β”‚   └── Upload artifacts
    β”‚
    β”œβ”€β”€ Publish Job (on tag)
    β”‚   β”œβ”€β”€ Download artifacts
    β”‚   └── Publish to Gitea Registry
    β”‚
    └── Docs Job
        β”œβ”€β”€ Build MkDocs
        └── Upload site

πŸ“Š Зависимости

Runtime

  • httpx[http2]>=0.26.0 β€” HTTP client
  • pydantic>=2.0.0 β€” Data validation
  • structlog>=24.0.0 β€” Logging

Development

  • pytest>=8.0.0 β€” Testing
  • pytest-cov>=4.0.0 β€” Coverage
  • pytest-asyncio>=0.23.0 β€” Async tests
  • respx>=0.20.0 β€” HTTP mocking
  • ruff>=0.3.0 β€” Linting
  • mkdocs + mkdocstrings β€” Documentation

πŸ”’ Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ

  • Π’ΠΎΠΊΠ΅Π½Ρ‹: НС ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Π»ΠΎΠ³Π°Ρ…
  • ΠŸΠ°Ρ€ΠΎΠ»ΠΈ: ΠŸΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ login()
  • БСссии: Token + cookies хранятся Π² ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅
  • HTTPS: ВсС запросы Ρ‡Π΅Ρ€Π΅Π· HTTPS

πŸ“ˆ ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

  • Async/Await: ΠΠ΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ запросы
  • HTTP/2: Multiplexing запросов
  • Connection pooling: ΠŸΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ соСдинСний
  • Timeouts: Π—Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ зависаний

πŸ§ͺ ВСстированиС

  • Unit тСсты: 92% coverage
  • Mock HTTP: respx для изоляции
  • Async tests: pytest-asyncio
  • CI: АвтоматичСский ΠΏΡ€ΠΎΠ³ΠΎΠ½ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠΎΠΌΠΌΠΈΡ‚Π΅

πŸ“ ЛицСнзия

MIT License β€” свободноС использованиС с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ авторства.