-
Notifications
You must be signed in to change notification settings - Fork 99
git + простые бэкэнды #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…dme.md (копирую со старого репозитория)
.github/workflows/ci.yml
Outdated
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| # 2. Устанавливаем Python 3.11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
на работе только не пиши так коммы с гпт
.github/workflows/ci.yml
Outdated
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: 3.11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
можно поновее версию
.github/workflows/ci.yml
Outdated
|
|
||
| # 6. Форматирование кода Ruff с исправлением | ||
| - name: Run Ruff Format | ||
| run: ruff format . --line-length 88 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
само форматирование в CI не делают, его делают локально, потому что надо создать коммит, который в CI пропадёт. тут стоило сделать ruff format --check
| response = requests.get(self.url, headers=self.headers) | ||
| response.raise_for_status() | ||
| return response.json() | ||
| except requests.exceptions.RequestException as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try except внутри методов использовать не стоит, просто прокидывай исключение наверх и лови в fastapi exception handler.
| response.raise_for_status() | ||
| return response.json() | ||
| except requests.exceptions.RequestException as e: | ||
| print("HTTP GET Error:", e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
логи только через logging либо loguru
| print("HTTP GET Error:", e) | ||
| raise | ||
|
|
||
| def post(self, payload: dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
У дикта не указал тип внутренностей. Также не указал возвращаемый тип.
|
|
||
| @abstractmethod | ||
| def save_data(self, data): | ||
| """Обязательный метод для наследников""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
комментарий дурацкий
|
|
||
| class CloudflareLLM(BaseHTTPClient): | ||
| def __init__(self): | ||
| token = os.getenv("CLOUDFLARE_AUTH_TOKEN") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
переменные из окружения тянем в отдельном файле config.py. и лучше это делать через starlette environment и класс pydantic basesettings
| super().__init__(token, url) | ||
|
|
||
| def load_data(self): | ||
| """Для LLM загрузка данных не требуется, поэтому просто возвращаем None""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
нарушение принципа I из SOLID
| """Для LLM загрузка данных не требуется, поэтому просто возвращаем None""" | ||
| return None | ||
|
|
||
| def save_data(self, data): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
типизацию не сделал
| raise HTTPException(status_code=500, detail=str(e)) | ||
|
|
||
|
|
||
| @app.post("/tasks") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
добавь аргумент response_model=
Также в эндпоинтах входящие запросы нужно перегонять в pydantic (фастапи это автоматически делает) и возвращать надо тоже pydantic
| tasks = storage.load_data() | ||
| new_id = max([t["id"] for t in tasks], default=0) + 1 | ||
| solution = llm.get_solution(title) | ||
| new_task = {"id": new_id, "title": title, "status": "in work", "solution": solution} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вот это точно должен был быть pydantic, никаких диктов
| tasks.append(new_task) | ||
| storage.save_data(tasks) | ||
| return new_task | ||
| except Exception as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это тоже убери, лови все в exception handler
| tasks.append(new_task) | ||
| storage.save_data(tasks) | ||
| return new_task | ||
| except Exception as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это тоже убери, лови все в exception handler
| tasks = storage.load_data() | ||
| for task in tasks: | ||
| if task["id"] == task_id: | ||
| tasks.remove(task) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
логичнее сюда было запихать аргумент task_id и уже внутри все найти и удалить
| if task["id"] == task_id: | ||
| tasks.remove(task) | ||
| storage.save_data(tasks) | ||
| return {"message": "Task deleted"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
просто 200 ок возвращай и все, так не делают
| постоянными. | ||
| - файл можно отредактировать даже без поднятия сервера. удобство работы с данными. масштабируемость? | ||
| 3) Избавились ли мы таким способом от хранения состояния или нет? | ||
| - нет, не избавились. мы всё также продолжаем читать/изменять/сохранять данные, которые меняют это |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
не избавились, но приложение стало stateless
| @@ -0,0 +1,2 @@ | |||
| fastapi | |||
| uvicorn[standard] No newline at end of file | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
точные версии указывай
| @@ -0,0 +1,12 @@ | |||
| [ | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
этот файл лучше не пушить и класть в .gitignore
LilChichaaa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
написал
| run: pip install ruff==0.13.3 | ||
|
|
||
| - name: Run Ruff Check | ||
| run: ruff check . --line-length 88 --select E,F,W --show-files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ruff format --check забыл
| url = f"https://api.github.com/gists/{settings.GIST_ID}" | ||
| super().__init__(token=settings.GITHUB_TOKEN, url=url) | ||
|
|
||
| def load_data(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тип возвращаемый то надо указывать
| content = gist_data["files"]["tasks.json"]["content"] | ||
| return json.loads(content) | ||
|
|
||
| def save_data(self, tasks): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут тоже не типизировал
| status: Optional[str] = None | ||
|
|
||
| class TaskUpdate(BaseModel): | ||
| title: Optional[str] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вместо Optional используй str | None
также не использовал возможности валидации, у строк можно задать минимальную длину и тд
LilChichaaa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ок
No description provided.