commit
9f055ef095
5 changed files with 290 additions and 0 deletions
-
5.env.template
-
162.gitignore
-
9README.md
-
108main.py
-
6requirements.txt
@ -0,0 +1,5 @@ |
|||||
|
DB_URL=mssql+pyodbc://{user}:{password}@{host}/{database_name}?driver=ODBC+Driver+17+for+SQL+Server |
||||
|
HOST=0.0.0.0 |
||||
|
PORT=4444 |
||||
|
SERVER_ROOT= |
||||
|
PREFIX=/agree |
@ -0,0 +1,162 @@ |
|||||
|
# Byte-compiled / optimized / DLL files |
||||
|
__pycache__/ |
||||
|
*.py[cod] |
||||
|
*$py.class |
||||
|
|
||||
|
# C extensions |
||||
|
*.so |
||||
|
|
||||
|
# Distribution / packaging |
||||
|
.Python |
||||
|
build/ |
||||
|
develop-eggs/ |
||||
|
dist/ |
||||
|
downloads/ |
||||
|
eggs/ |
||||
|
.eggs/ |
||||
|
lib/ |
||||
|
lib64/ |
||||
|
parts/ |
||||
|
sdist/ |
||||
|
var/ |
||||
|
wheels/ |
||||
|
share/python-wheels/ |
||||
|
*.egg-info/ |
||||
|
.installed.cfg |
||||
|
*.egg |
||||
|
MANIFEST |
||||
|
|
||||
|
# PyInstaller |
||||
|
# Usually these files are written by a python script from a template |
||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||
|
*.manifest |
||||
|
*.spec |
||||
|
|
||||
|
# Installer logs |
||||
|
pip-log.txt |
||||
|
pip-delete-this-directory.txt |
||||
|
|
||||
|
# Unit test / coverage reports |
||||
|
htmlcov/ |
||||
|
.tox/ |
||||
|
.nox/ |
||||
|
.coverage |
||||
|
.coverage.* |
||||
|
.cache |
||||
|
nosetests.xml |
||||
|
coverage.xml |
||||
|
*.cover |
||||
|
*.py,cover |
||||
|
.hypothesis/ |
||||
|
.pytest_cache/ |
||||
|
cover/ |
||||
|
|
||||
|
# Translations |
||||
|
*.mo |
||||
|
*.pot |
||||
|
|
||||
|
# Django stuff: |
||||
|
*.log |
||||
|
local_settings.py |
||||
|
db.sqlite3 |
||||
|
db.sqlite3-journal |
||||
|
|
||||
|
# Flask stuff: |
||||
|
instance/ |
||||
|
.webassets-cache |
||||
|
|
||||
|
# Scrapy stuff: |
||||
|
.scrapy |
||||
|
|
||||
|
# Sphinx documentation |
||||
|
docs/_build/ |
||||
|
|
||||
|
# PyBuilder |
||||
|
.pybuilder/ |
||||
|
target/ |
||||
|
|
||||
|
# Jupyter Notebook |
||||
|
.ipynb_checkpoints |
||||
|
|
||||
|
# IPython |
||||
|
profile_default/ |
||||
|
ipython_config.py |
||||
|
|
||||
|
# pyenv |
||||
|
# For a library or package, you might want to ignore these files since the code is |
||||
|
# intended to run in multiple environments; otherwise, check them in: |
||||
|
# .python-version |
||||
|
|
||||
|
# pipenv |
||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||
|
# install all needed dependencies. |
||||
|
#Pipfile.lock |
||||
|
|
||||
|
# poetry |
||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more |
||||
|
# commonly ignored for libraries. |
||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
||||
|
#poetry.lock |
||||
|
|
||||
|
# pdm |
||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. |
||||
|
#pdm.lock |
||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it |
||||
|
# in version control. |
||||
|
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control |
||||
|
.pdm.toml |
||||
|
.pdm-python |
||||
|
.pdm-build/ |
||||
|
|
||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm |
||||
|
__pypackages__/ |
||||
|
|
||||
|
# Celery stuff |
||||
|
celerybeat-schedule |
||||
|
celerybeat.pid |
||||
|
|
||||
|
# SageMath parsed files |
||||
|
*.sage.py |
||||
|
|
||||
|
# Environments |
||||
|
.env |
||||
|
.venv |
||||
|
env/ |
||||
|
venv/ |
||||
|
ENV/ |
||||
|
env.bak/ |
||||
|
venv.bak/ |
||||
|
|
||||
|
# Spyder project settings |
||||
|
.spyderproject |
||||
|
.spyproject |
||||
|
|
||||
|
# Rope project settings |
||||
|
.ropeproject |
||||
|
|
||||
|
# mkdocs documentation |
||||
|
/site |
||||
|
|
||||
|
# mypy |
||||
|
.mypy_cache/ |
||||
|
.dmypy.json |
||||
|
dmypy.json |
||||
|
|
||||
|
# Pyre type checker |
||||
|
.pyre/ |
||||
|
|
||||
|
# pytype static type analyzer |
||||
|
.pytype/ |
||||
|
|
||||
|
# Cython debug symbols |
||||
|
cython_debug/ |
||||
|
|
||||
|
# PyCharm |
||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can |
||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore |
||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear |
||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder. |
||||
|
#.idea/ |
@ -0,0 +1,9 @@ |
|||||
|
создать виртуальное окружение |
||||
|
""python3 -m venv .venv""" |
||||
|
подключиться к виртуальному окружению |
||||
|
""".\.venv\Scripts\activate""" |
||||
|
Загрузить библиотеки с файла requirements.txt |
||||
|
"""pip install -r requirements.txt""" |
||||
|
в файле .env.template заменить на ваши данные и сохранить в .env |
||||
|
Запустить приложение |
||||
|
"""main.py""" |
@ -0,0 +1,108 @@ |
|||||
|
from fastapi import FastAPI, APIRouter, Request |
||||
|
from fastapi.middleware.cors import CORSMiddleware |
||||
|
from fastapi.responses import ORJSONResponse, HTMLResponse |
||||
|
from sqlmodel import create_engine, Field, SQLModel, UUID, DateTime, func, Column, text, bindparam |
||||
|
from sqlalchemy.dialects.mssql import UNIQUEIDENTIFIER, DATETIME |
||||
|
from sqlalchemy import insert |
||||
|
from dotenv import load_dotenv |
||||
|
from typing import Optional, Sequence |
||||
|
from datetime import datetime |
||||
|
from uuid import UUID |
||||
|
import os |
||||
|
load_dotenv() |
||||
|
DB_URL = os.getenv("DB_URL") |
||||
|
SERVER_ROOT = os.getenv("SERVER_ROOT") |
||||
|
PREFIX = os.getenv("PREFIX") |
||||
|
db_engine = create_engine(DB_URL) |
||||
|
|
||||
|
class Agreement(SQLModel,table=True): |
||||
|
id: Optional[int] = Field(default=None, primary_key=True) |
||||
|
id_account: UUID = Field(sa_column=Column(UNIQUEIDENTIFIER)) |
||||
|
id_personal_account: Optional[int] |
||||
|
date_registration:datetime = Field(sa_column=Column(DATETIME)) |
||||
|
FIO: Optional[str] |
||||
|
phone: Optional[str] |
||||
|
email: Optional[str] |
||||
|
agreement:Optional[bool] = True |
||||
|
agreement_date: Optional[datetime] = Field(sa_column=Column(DATETIME)) |
||||
|
|
||||
|
class AgreementCreate(SQLModel): |
||||
|
id_account: UUID |
||||
|
id_personal_account: Optional[int] |
||||
|
date_registration:datetime |
||||
|
FIO: Optional[str] |
||||
|
phone: Optional[str] |
||||
|
email: Optional[str] |
||||
|
agreement:Optional[bool] = True |
||||
|
agreement_date: Optional[datetime] |
||||
|
SQLModel.metadata.create_all(db_engine, checkfirst=True) |
||||
|
|
||||
|
app = FastAPI(openapi_url = SERVER_ROOT +"/openapi.json", docs_url=SERVER_ROOT+"/docs", default_response_class=ORJSONResponse) |
||||
|
app.add_middleware( |
||||
|
CORSMiddleware, |
||||
|
allow_origins=["*"], |
||||
|
allow_credentials=True, |
||||
|
allow_methods=["*"], |
||||
|
allow_headers=["*"], |
||||
|
) |
||||
|
|
||||
|
router = APIRouter( |
||||
|
prefix=PREFIX |
||||
|
) |
||||
|
|
||||
|
@app.get("/", response_class= HTMLResponse) |
||||
|
async def hello(request: Request): |
||||
|
return """ |
||||
|
<html> |
||||
|
<head> |
||||
|
<title>Привет</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<h1>Это API, а не сайт!</h1> |
||||
|
</body> |
||||
|
</html> |
||||
|
""" |
||||
|
|
||||
|
@router.get('/') |
||||
|
async def get_ageement(id_account: Optional[UUID] = None) -> Sequence[Agreement]: |
||||
|
with db_engine.begin() as con: |
||||
|
query = text("SELECT * FROM agreement WHERE id_account=:id_account").params({"id_account":id_account}) |
||||
|
return con.execute(query).fetchall() |
||||
|
|
||||
|
|
||||
|
@router.delete("/") |
||||
|
async def delete_pk(acc_list: Sequence[UUID]): |
||||
|
with db_engine.begin() as con: |
||||
|
stmt = text("DELETE agreement WHERE id_account IN :acc_list") |
||||
|
params = {"acc_list":acc_list} |
||||
|
stmt = stmt.bindparams(bindparam('acc_list', expanding=True)) |
||||
|
con.execute(stmt, params) |
||||
|
return {"msg":"has deleted"} |
||||
|
|
||||
|
|
||||
|
@router.post("/") |
||||
|
async def add_agreement(agrees: Sequence[AgreementCreate]): |
||||
|
with db_engine.begin() as con: |
||||
|
dict_list=[] |
||||
|
acc_list = [] |
||||
|
for agree in agrees: |
||||
|
agree_dict = agree.model_dump() |
||||
|
dict_list.append(agree_dict) |
||||
|
acc_id = agree_dict.get("id_account") |
||||
|
if acc_id not in acc_list: |
||||
|
acc_list.append(acc_id) |
||||
|
await delete_pk(acc_list) |
||||
|
stmt = insert(Agreement).values(dict_list) |
||||
|
con.execute(stmt) |
||||
|
con.commit() |
||||
|
return {"msg": "added succesfully"} |
||||
|
|
||||
|
app.include_router(router) |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
import uvicorn |
||||
|
uvicorn.run( |
||||
|
app, |
||||
|
host=os.getenv("HOST"), |
||||
|
port=int(os.getenv("PORT")) |
||||
|
) |
@ -0,0 +1,6 @@ |
|||||
|
fastapi |
||||
|
uvicorn |
||||
|
sqlmodel |
||||
|
pyodbc |
||||
|
python-dotenv |
||||
|
orjson |
Write
Preview
Loading…
Cancel
Save
Reference in new issue