Розробка AI-генерації API за описом (Text-to-API)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка AI-генерації API за описом (Text-to-API)
Складний
~1-2 тижні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

AI-генерація API з текстових описів (Text-to-API)

Text-to-API — це генерація повнофункціонального REST/GraphQL API-шару з описання на природній мові або OpenAPI-специфікації. Завдання ширше, ніж просто написати endpoints: потрібні моделі даних, валідація, middleware, тести, документація. AI виступає як junior-розробник з хорошим знанням FastAPI/Express, який працює зі швидкістю тисяч рядків за хвилину.

Архітектура генератора API

from anthropic import Anthropic
from pathlib import Path
import json
from pydantic import BaseModel
from typing import Literal, Optional

client = Anthropic()

class APIEndpoint(BaseModel):
    method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"]
    path: str
    summary: str
    request_body: Optional[dict] = None
    response_schema: dict
    auth_required: bool = True
    query_params: list[dict] = []

class APISpec(BaseModel):
    title: str
    description: str
    version: str
    base_path: str
    endpoints: list[APIEndpoint]
    entities: list[dict]  # Бізнес-сутності

class TextToAPIGenerator:

    def parse_description(self, description: str) -> APISpec:
        """Парсить текстове описання в структуровану специфікацію"""

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            system="""Ти — API-архітектор. Парсиш описання системи в структуру REST API.

REST правила:
- Іменники в URL (не дієслова): /users, /orders
- Правильні HTTP методи: GET=читання, POST=створення, PUT=повна заміна, PATCH=часткове оновлення, DELETE=видалення
- Вкладеність максимум 2 рівні: /users/{id}/orders
- Plural для колекцій: /products, /categories
- Пагінація: ?page=1&limit=20
- Фільтрація: ?status=active&created_after=2024-01-01""",
            messages=[{
                "role": "user",
                "content": f"""Розбери описання та поверни JSON специфікацію API:

{{
  "title": "...",
  "description": "...",
  "version": "1.0.0",
  "base_path": "/api/v1",
  "entities": [
    {{"name": "...", "fields": [{{"name": "...", "type": "...", "required": true}}]}}
  ],
  "endpoints": [
    {{
      "method": "GET|POST|PUT|PATCH|DELETE",
      "path": "/resource/{{id}}",
      "summary": "...",
      "auth_required": true,
      "request_body": {{"field": "type"}},
      "response_schema": {{"id": "int", "name": "str"}},
      "query_params": [{{"name": "...", "type": "...", "required": false}}]
    }}
  ]
}}

Описання системи:
{description}"""
            }]
        )

        text = response.content[0].text
        start = text.find("{")
        end = text.rfind("}") + 1
        data = json.loads(text[start:end])
        return APISpec(**data)

    def generate_fastapi_code(self, spec: APISpec) -> dict[str, str]:
        """Генерує повний FastAPI проект"""

        files = {}

        # models.py
        files["models.py"] = self._generate_models(spec)

        # schemas.py
        files["schemas.py"] = self._generate_schemas(spec)

        # routers/{resource}.py для кожної сутності
        for entity in spec.entities:
            router_code = self._generate_router(entity, spec)
            files[f"routers/{entity['name'].lower()}.py"] = router_code

        # main.py
        files["main.py"] = self._generate_main(spec)

        # tests/
        for entity in spec.entities:
            test_code = self._generate_tests(entity, spec)
            files[f"tests/test_{entity['name'].lower()}.py"] = test_code

        return files

    def _generate_models(self, spec: APISpec) -> str:
        """Генерує SQLAlchemy моделі"""

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            messages=[{
                "role": "user",
                "content": f"""Створи SQLAlchemy 2.0 моделі для сутностей:

Сутності:
{json.dumps(spec.entities, ensure_ascii=False, indent=2)}

Вимоги:
- Використовуй DeclarativeBase
- Додай id (Integer PK autoincrement), created_at, updated_at для всіх моделей
- Використовуй правильні типи: String(256), Text, Integer, Float, Boolean, DateTime
- Додай __tablename__
- Додай relationship() для зв'язків між моделями
- Додай __repr__ для дебагу

Поверни тільки Python код."""
            }]
        )

        return response.content[0].text.strip()

    def _generate_schemas(self, spec: APISpec) -> str:
        """Генерує Pydantic v2 схеми"""

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            messages=[{
                "role": "user",
                "content": f"""Створи Pydantic v2 схеми для валідації:

Сутності: {json.dumps(spec.entities, ensure_ascii=False)}
Endpoints: {json.dumps([e.dict() for e in spec.endpoints], ensure_ascii=False)}

Для кожної сутності створи:
- <Entity>Create — для POST (всі обов'язкові поля)
- <Entity>Update — для PATCH (всі поля Optional)
- <Entity>Response — для ответів (включаючи id, created_at)
- <Entity>ListResponse — з пагінацією

Додай field validators де потрібно (формат email, позитивні числа, довжина строк).

Поверни тільки Python код."""
            }]
        )

        return response.content[0].text.strip()

    def _generate_router(self, entity: dict, spec: APISpec) -> str:
        """Генерує роутер з CRUD endpoints"""

        entity_endpoints = [
            e for e in spec.endpoints
            if entity["name"].lower() in e.path.lower()
        ]

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            messages=[{
                "role": "user",
                "content": f"""Створи FastAPI роутер для сутності {entity['name']}.

Endpoints для реалізації:
{json.dumps([e.dict() for e in entity_endpoints], ensure_ascii=False, indent=2)}

Вимоги:
- Використовуй APIRouter з prefix та tags
- Dependency injection для DB session (AsyncSession)
- Dependency injection для авторизації (get_current_user)
- Async/await для всіх операцій
- Правильні HTTP статуси: 201 для POST, 204 для DELETE, 404 якщо не знайдено
- Пагінація через query params page/limit
- Логування через structlog

Поверни тільки Python код."""
            }]
        )

        return response.content[0].text.strip()

    def _generate_main(self, spec: APISpec) -> str:
        return f"""from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager

{chr(10).join(f"from routers.{e['name'].lower()} import router as {e['name'].lower()}_router" for e in spec.entities)}

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    yield
    # Shutdown

app = FastAPI(
    title="{spec.title}",
    description="{spec.description}",
    version="{spec.version}",
    lifespan=lifespan,
)

app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])

{chr(10).join(f'app.include_router({e["name"].lower()}_router, prefix="{spec.base_path}")' for e in spec.entities)}
"""

    def _generate_tests(self, entity: dict, spec: APISpec) -> str:
        """Генерує pytest тести для CRUD endpoints"""

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=2048,
            messages=[{
                "role": "user",
                "content": f"""Створи pytest тести для CRUD endpoints сутності {entity['name']}.

Використовуй:
- pytest-asyncio для async тестів
- httpx.AsyncClient для HTTP запитів
- pytest fixtures для setup/teardown
- TestDatabase (SQLite in-memory) для ізоляції

Покрий: створення, читання списка, читання одного, оновлення, видалення, 404 випадки, валідацію вхідних даних.

Поверни тільки Python код."""
            }]
        )

        return response.content[0].text.strip()

CLI інтерфейс

import click
import yaml

@click.command()
@click.argument("description_file", type=click.Path(exists=True))
@click.option("--output-dir", "-o", default="./generated_api")
@click.option("--framework", default="fastapi", type=click.Choice(["fastapi", "express"]))
def generate_api(description_file: str, output_dir: str, framework: str):
    """Генерує API з текстового описання"""

    description = Path(description_file).read_text()
    generator = TextToAPIGenerator()

    click.echo("Parsing description...")
    spec = generator.parse_description(description)
    click.echo(f"Found {len(spec.endpoints)} endpoints, {len(spec.entities)} entities")

    click.echo("Generating code...")
    files = generator.generate_fastapi_code(spec)

    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    for filename, content in files.items():
        file_path = output_path / filename
        file_path.parent.mkdir(parents=True, exist_ok=True)
        file_path.write_text(content)
        click.echo(f"  Created: {filename}")

    # Генеруємо docker-compose та requirements.txt
    _generate_project_files(output_path, spec)

    click.echo(f"\nAPI generated in {output_dir}")
    click.echo("Run: cd generated_api && docker-compose up")

if __name__ == "__main__":
    generate_api()

Приклад описання для генерації

# Система управління задачами

Багатокористувацька система для команд.

Сутності:
- User: email (унікальний), name, role (admin/member), avatar_url
- Team: name, description, owner_id
- Project: name, description, team_id, status (active/archived)
- Task: title, description, project_id, assignee_id, status (todo/in_progress/done), priority (low/medium/high), due_date

Функціональність:
- Реєстрація та авторизація (JWT)
- CRUD для команд, проектів, задач
- Призначення задач учасникам команди
- Фільтрація задач по статусу, виконавцю, пріоритету
- Пагінація всіх списків
- Soft delete для задач

Практичний кейс: внутрішній B2B-продукт

Задача: стартап хотів за 2 тижні отримати MVP backend для marketplace послуг. 8 основних сутностей, 45+ endpoints.

Генерація:

  • Описання продукту на 2 сторінці → APISpec (30 секунд)
  • Генерація коду FastAPI (7 файлів + тести) → 8 хвилин
  • Ручна доробка бізнес-логіки авторизації → 3 дні
  • Інтеграція платіжного шлюзу → 2 дні

Результат: робочий MVP за 5 днів замість запланованих 14. Test coverage 67% (тести були згенеровані автоматично).

Що AI генерує добре: CRUD, пагінація, валідація, структура проекту, тести happy path.

Що потребує рук: складна бізнес-логіка авторизації, специфічні алгоритми ціноутворення, нетривіальні SQL запити з віконними функціями.

Терміни

  • Прототип генератора (описання → один файл): 2–3 дні
  • Повна генерація проекту з тестами: 1–2 тижні
  • Підтримка додаткових фреймворків (Express, Django REST): +1 тиждень кожний
  • Інтеграція в CI/CD для регенерації при зміні специфікації: 1 тиждень