Я программист и всегда ищу способ повысить свою продуктивность, чтобы найти больше времени для чего-то более значимого в жизни, например, спорить с незнакомцами в Твиттере. Для этого я использую множество инструментов, включая IDE, плагины и недавно GitHub Copilot. ИИ помогает мне завершать мой код больше, чем ваша жена может завершать ваши предложения, но он не идеален. Ему все еще нужен программист, чтобы подумать о том, как закодировать его на основе требований, и часто код, сгенерированный из GitHub Copilot, даже не может работать. В основном я использую его для автоматического завершения моего хорошо продуманного кода.

Наконец-то появился ChatGPT. Чат-бот, который может говорить и вести глубокую беседу и помнить, что вы сказали, что он сказал, может быть правильным. Я попробовал его на длинных выходных, в основном пытаясь сломать его, исследовать пределы ИИ и узнать, что он способен генерировать функциональный код.

В рабочее время мне пришла в голову идея использовать ChatGPT, чтобы полностью выполнять свою работу. По сути, превратите требование в реальный код. Мое требование очень простое: RESTAPI, который имеет возможность глобально приостанавливать и возобновлять вызовы других RESTAPI (также известный как автоматический выключатель). Я решил представить требование в виде диалога, а не эссе, как это делает настоящий владелец продукта.

Сначала я попросил ChatGPT сделать простой фиктивный API, который делает что-то похожее на обычный функциональный RESTAPI.

Я: Напишите Python FastAPI для возврата удаленного IP-адреса пользователя.

ChatGPT:

Вот пример приложения FastAPI, которое возвращает удаленный IP-адрес пользователя:

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])
app.add_middleware(HTTPSRedirectMiddleware)

@app.get("/")
async def get_ip_address(request):
    return {"remote_ip": request.client.host}

Это приложение использует TrustedHostMiddleware, чтобы убедиться, что запрос исходит от доверенного хоста (например, «example.com» в данном случае). Он также использует HTTPSRedirectMiddleware для автоматического перенаправления HTTP-запросов на HTTPS.

Чтобы получить доступ к IP-адресу пользователя, приложение использует атрибут request.client.host. Это возвращает IP-адрес клиента пользователя, который в данном случае является удаленным IP-адресом.

В этот момент я уже был впечатлен результатом. Он описывает, что код делает действительно хорошо, но я не буду его запускать, так как это не является реальным требованием. Я продолжаю просить о своем главном требовании.

Я: добавьте функцию приостановки и возобновления работы API

ChatGPT:

Вот пример того, как вы можете добавить функцию для приостановки и возобновления работы приложения FastAPI:

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
from starlette.requests import Request
from starlette.responses import Response

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])
app.add_middleware(HTTPSRedirectMiddleware)

PAUSED = False

@app.middleware("http")
async def pause_middleware(request: Request, call_next):
    global PAUSED
    if PAUSED:
        return Response("The API is currently paused", status_code=503)
    response = await call_next(request)
    return response

@app.get("/pause")
async def pause():
    global PAUSED
    PAUSED = True
    return {"message": "The API has been paused"}

@app.get("/resume")
async def resume():
    global PAUSED
    PAUSED = False
    return {"message": "The API has been resumed"}

@app.get("/")
async def get_ip_address(request):
    return {"remote_ip": request.client.host}

Это приложение добавляет глобальную переменную PAUSED, которая изначально имеет значение False. Он также добавляет функцию pause_middleware, которая проверяет значение переменной PAUSED и возвращает ответ с кодом состояния 503 (служба недоступна), если работа API приостановлена. Это промежуточное ПО добавляется в приложение с помощью декоратора app.middleware, что позволяет ему выполняться для каждого HTTP-запроса.

Приложение также добавляет две новые конечные точки: /pause и /resume, которые можно использовать для приостановки и возобновления работы API соответственно. Эти конечные точки просто переключают значение переменной PAUSED.

Когда работа API приостановлена, все запросы к нему будут получать ответ с кодом состояния 503 и сообщением о том, что работа API приостановлена. Когда он будет возобновлен, запросы будут обрабатываться в обычном режиме.

Это продолжает меня впечатлять. Он добавил промежуточное программное обеспечение для перехвата всех запросов и проверки состояния приостановки с помощью глобальной переменной PAUSED и возврата HTTP-ошибки 503, когда она приостановлена. На самом деле я копирую код и запускаю его в своей реальной работе, но мне не нравится результат ошибки, который представляет собой простой текст. Я мог бы легко изменить его сам, но я мог бы просто попросить ChatGPT изменить его.

ME: Измените ответ промежуточного программного обеспечения на JSON

ChatGPT:

Вот пример того, как вы можете изменить промежуточное ПО в предыдущем примере, чтобы возвращать ответ JSON вместо обычного текстового ответа: Скопировать код

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])
app.add_middleware(HTTPSRedirectMiddleware)

PAUSED = False

@app.middleware("http")
async def pause_middleware(request: Request, call_next):
    global PAUSED
    if PAUSED:
        return JSONResponse(
            {"message": "The API is currently paused"},
            status_code=503
        )
    response = await call_next(request)
    return response

@app.get("/pause")
async def pause():
    global PAUSED
    PAUSED = True
    return {"message": "The API has been paused"}

@app.get("/resume")
async def resume():
    global PAUSED
    PAUSED = False
    return {"message": "The API has been resumed"}

@app.get("/")
async def get_ip_address(request):
    return {"remote_ip": request.client.host}

Это приложение похоже на предыдущий пример, но вместо того, чтобы возвращать объект Response в промежуточном программном обеспечении, оно возвращает объект JSONResponse. Это позволяет указать тело ответа JSON и код состояния HTTP.

Он может запомнить сгенерированный код. Я могу исправить код, просто поговорив с ним, но в коде есть серьезный недостаток. Он не может возобновить работу API после первой паузы, вызванной при вызове /resume промежуточного программного обеспечения, всегда отвечает 503 и не сможет снова изменить флаг PAUSED. Я рассеянно спросил о проблеме.

Я: Но как он может возобновиться, если промежуточное ПО всегда отвечает ошибкой 503?

ЧатGPT:

Промежуточное ПО возвращает ответ с кодом состояния 503 только в том случае, если переменная PAUSED равна True. Если переменная PAUSED равна False, ПО промежуточного слоя просто передает запрос следующему компоненту ПО промежуточного слоя или обработчику конечной точки, а ответ обрабатывается как обычно.

Это означает, что когда вызывается конечная точка /resume и для переменной PAUSED установлено значение False, промежуточное программное обеспечение не будет возвращать ответ, а запрос будет обрабатываться обработчиком конечной точки. Это позволяет возобновить работу API и снова начать обслуживать запросы.

Вот пример того, как это может выглядеть:

Первоначально переменная PAUSED имеет значение False.

Выполняется запрос к конечной точке /

Вызывается функция pause_middleware и проверяет значение переменной PAUSED

Переменная PAUSED равна False, поэтому промежуточное ПО передает запрос обработчику конечной точки get_ip_address.

Обработчик конечной точки get_ip_address возвращает ответ с IP-адресом пользователя.

Ответ возвращается клиенту

Теперь предположим, что вызывается конечная точка /pause, которая устанавливает для переменной PAUSED значение True. Если сделать запрос к конечной точке /, произойдет следующее:

Переменная PAUSED установлена ​​на True

Выполняется запрос к конечной точке /

Вызывается функция pause_middleware и проверяет значение переменной PAUSED

Переменная PAUSED имеет значение True, поэтому промежуточное ПО возвращает ответ JSON с кодом состояния 503 и сообщением о том, что работа API приостановлена.

Ответ возвращается клиенту

Если вызывается конечная точка /resume, которая устанавливает для переменной PAUSED значение False, последующие запросы к конечной точке / будут обрабатываться как обычно, поскольку промежуточное ПО будет передавать их обработчику конечной точки вместо возврата ответа.

Ответ в основном описывает простую логическую логику, как будто мне было 10 лет, и я ничего не исправил. Я должен спросить еще раз, но более конкретно о логической ошибке.

Я: Но он не может использовать /resume для возобновления работы API, пока переменная PAUSED имеет значение True, потому что промежуточное ПО всегда будет возвращать ошибку 503.

ChatGPT:

Вы правы в том, что если переменная PAUSED равна True, промежуточное ПО всегда будет возвращать ответ с кодом состояния 503, а конечная точка /resume не сможет возобновить работу API.

Однако вы можете изменить промежуточное ПО, чтобы оно возвращало ответ только с кодом состояния 503, если путь запроса не /resume. Это позволит вызывать конечную точку /resume, даже если переменная PAUSED равна True.

Вот пример того, как вы могли бы это сделать:

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])
app.add_middleware(HTTPSRedirectMiddleware)

PAUSED = False

@app.middleware("http")
async def pause_middleware(request: Request, call_next):
    global PAUSED
    if PAUSED and request.url.path != "/resume":
        return JSONResponse(
            {"message": "The API is currently paused"},
            status_code=503
        )
    response = await call_next(request)
    return response

@app.get("/pause")
async def pause():
    global PAUSED
    PAUSED = True
    return {"message": "The API has been paused"}

@app.get("/resume")
async def resume():
    global PAUSED
    PAUSED = False
    return {"message": "The API has been resumed"}

@app.get("/")
async def get_ip_address(request):
    return {"remote_ip": request.client.host}

В этом приложении функция pause_middleware проверяет значение переменной PAUSED, но возвращает ответ с кодом состояния 503 только в том случае, если переменная PAUSED равна True, а путь запроса не равен /resume. Это позволяет вызывать конечную точку /resume, даже когда работа API приостановлена.

Когда вызывается конечная точка /resume, она устанавливает для переменной PAUSED значение False, что приводит к тому, что промежуточное ПО перестает возвращать ответ с кодом состояния 503 для последующих запросов. Это позволяет возобновить работу API и снова начать обслуживать запросы.

Это показывает, как он может уверенно ошибаться и бесстыдно признавать свою ошибку. Кроме того, может исправить себя, если дать руководство. При этом я пытаюсь сам исправить код с помощью GitHub Copilot. Он завершает условие промежуточного ПО с помощью request.url.path != “/pause”, что неверно. Я копирую код из ChatGPT и добавляю его в реальный проект.

Теперь я почти уверен, что ChatGPT может кодировать из требований и может быть адаптирован к изменениям. Но я чувствую, что кодирование ИИ — это временное решение. Разработка программного обеспечения в далеком будущем может не нуждаться в языке программирования. Мы можем просто говорить на естественном языке с ИИ, и он сгенерирует работающий исполняемый двоичный файл, который делает то, что мы сказали.